diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-12-03 03:55:44 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-12-03 03:55:44 -0500 |
commit | eb10149d17784ad28061ba6c29025a2ef0a5e71a (patch) | |
tree | d22b6b196d8c7550d0bb1e6c39bc0b5623fa53e6 | |
parent | dda415d41882449f841f88d829dd65b6ee1c374c (diff) | |
parent | 854ea639bb6b0b7ec433e0a59405f4f199ffae4f (diff) |
Merge tag 'asoc-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next
ASoC: Updates for v3.8
Very quiet release for ASoC really:
- Standardisation of the logging.
- DT and dmaengine support for Atmel.
- Support for Wolfson ADSP cores.
- New drivers for Freescale/iVeia P1022 and Maxim MAX98090.
301 files changed, 7775 insertions, 2751 deletions
@@ -1823,6 +1823,11 @@ S: Kattreinstr 38 | |||
1823 | S: D-64295 | 1823 | S: D-64295 |
1824 | S: Germany | 1824 | S: Germany |
1825 | 1825 | ||
1826 | N: Avi Kivity | ||
1827 | E: avi.kivity@gmail.com | ||
1828 | D: Kernel-based Virtual Machine (KVM) | ||
1829 | S: Ra'annana, Israel | ||
1830 | |||
1826 | N: Andi Kleen | 1831 | N: Andi Kleen |
1827 | E: andi@firstfloor.org | 1832 | E: andi@firstfloor.org |
1828 | U: http://www.halobates.de | 1833 | U: http://www.halobates.de |
diff --git a/Documentation/devicetree/bindings/misc/atmel-ssc.txt b/Documentation/devicetree/bindings/misc/atmel-ssc.txt new file mode 100644 index 000000000000..38e51ad2e07e --- /dev/null +++ b/Documentation/devicetree/bindings/misc/atmel-ssc.txt | |||
@@ -0,0 +1,15 @@ | |||
1 | * Atmel SSC driver. | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: "atmel,at91rm9200-ssc" or "atmel,at91sam9g45-ssc" | ||
5 | - atmel,at91rm9200-ssc: support pdc transfer | ||
6 | - atmel,at91sam9g45-ssc: support dma transfer | ||
7 | - reg: Should contain SSC registers location and length | ||
8 | - interrupts: Should contain SSC interrupt | ||
9 | |||
10 | Example: | ||
11 | ssc0: ssc@fffbc000 { | ||
12 | compatible = "atmel,at91rm9200-ssc"; | ||
13 | reg = <0xfffbc000 0x4000>; | ||
14 | interrupts = <14 4 5>; | ||
15 | }; | ||
diff --git a/Documentation/devicetree/bindings/net/mdio-gpio.txt b/Documentation/devicetree/bindings/net/mdio-gpio.txt index bc9549529014..c79bab025369 100644 --- a/Documentation/devicetree/bindings/net/mdio-gpio.txt +++ b/Documentation/devicetree/bindings/net/mdio-gpio.txt | |||
@@ -8,9 +8,16 @@ gpios property as described in section VIII.1 in the following order: | |||
8 | 8 | ||
9 | MDC, MDIO. | 9 | MDC, MDIO. |
10 | 10 | ||
11 | Note: Each gpio-mdio bus should have an alias correctly numbered in "aliases" | ||
12 | node. | ||
13 | |||
11 | Example: | 14 | Example: |
12 | 15 | ||
13 | mdio { | 16 | aliases { |
17 | mdio-gpio0 = <&mdio0>; | ||
18 | }; | ||
19 | |||
20 | mdio0: mdio { | ||
14 | compatible = "virtual,mdio-gpio"; | 21 | compatible = "virtual,mdio-gpio"; |
15 | #address-cells = <1>; | 22 | #address-cells = <1>; |
16 | #size-cells = <0>; | 23 | #size-cells = <0>; |
diff --git a/Documentation/devicetree/bindings/sound/ak4104.txt b/Documentation/devicetree/bindings/sound/ak4104.txt new file mode 100644 index 000000000000..b902ee39cf89 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/ak4104.txt | |||
@@ -0,0 +1,22 @@ | |||
1 | AK4104 S/PDIF transmitter | ||
2 | |||
3 | This device supports SPI mode only. | ||
4 | |||
5 | Required properties: | ||
6 | |||
7 | - compatible : "asahi-kasei,ak4104" | ||
8 | |||
9 | - reg : The chip select number on the SPI bus | ||
10 | |||
11 | Optional properties: | ||
12 | |||
13 | - reset-gpio : a GPIO spec for the reset pin. If specified, it will be | ||
14 | deasserted before communication to the device starts. | ||
15 | |||
16 | Example: | ||
17 | |||
18 | spdif: ak4104@0 { | ||
19 | compatible = "asahi-kasei,ak4104"; | ||
20 | reg = <0>; | ||
21 | spi-max-frequency = <5000000>; | ||
22 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/atmel-at91sam9g20ek-wm8731-audio.txt b/Documentation/devicetree/bindings/sound/atmel-at91sam9g20ek-wm8731-audio.txt new file mode 100644 index 000000000000..9c5a9947b64d --- /dev/null +++ b/Documentation/devicetree/bindings/sound/atmel-at91sam9g20ek-wm8731-audio.txt | |||
@@ -0,0 +1,26 @@ | |||
1 | * Atmel at91sam9g20ek wm8731 audio complex | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: "atmel,at91sam9g20ek-wm8731-audio" | ||
5 | - atmel,model: The user-visible name of this sound complex. | ||
6 | - atmel,audio-routing: A list of the connections between audio components. | ||
7 | - atmel,ssc-controller: The phandle of the SSC controller | ||
8 | - atmel,audio-codec: The phandle of the WM8731 audio codec | ||
9 | Optional properties: | ||
10 | - pinctrl-names, pinctrl-0: Please refer to pinctrl-bindings.txt | ||
11 | |||
12 | Example: | ||
13 | sound { | ||
14 | compatible = "atmel,at91sam9g20ek-wm8731-audio"; | ||
15 | pinctrl-names = "default"; | ||
16 | pinctrl-0 = <&pinctrl_pck0_as_mck>; | ||
17 | |||
18 | atmel,model = "wm8731 @ AT91SAMG20EK"; | ||
19 | |||
20 | atmel,audio-routing = | ||
21 | "Ext Spk", "LHPOUT", | ||
22 | "Int MIC", "MICIN"; | ||
23 | |||
24 | atmel,ssc-controller = <&ssc0>; | ||
25 | atmel,audio-codec = <&wm8731>; | ||
26 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/cs4271.txt b/Documentation/devicetree/bindings/sound/cs4271.txt index c81b5fd5a5bc..a850fb9c88ea 100644 --- a/Documentation/devicetree/bindings/sound/cs4271.txt +++ b/Documentation/devicetree/bindings/sound/cs4271.txt | |||
@@ -18,6 +18,8 @@ Optional properties: | |||
18 | 18 | ||
19 | - reset-gpio: a GPIO spec to define which pin is connected to the chip's | 19 | - reset-gpio: a GPIO spec to define which pin is connected to the chip's |
20 | !RESET pin | 20 | !RESET pin |
21 | - cirrus,amuteb-eq-bmutec: When given, the Codec's AMUTEB=BMUTEC flag | ||
22 | is enabled. | ||
21 | 23 | ||
22 | Examples: | 24 | Examples: |
23 | 25 | ||
diff --git a/Documentation/devicetree/bindings/sound/omap-abe-twl6040.txt b/Documentation/devicetree/bindings/sound/omap-abe-twl6040.txt index 65dec876cb2d..fd40c852d7c7 100644 --- a/Documentation/devicetree/bindings/sound/omap-abe-twl6040.txt +++ b/Documentation/devicetree/bindings/sound/omap-abe-twl6040.txt | |||
@@ -12,7 +12,7 @@ Required properties: | |||
12 | 12 | ||
13 | Optional properties: | 13 | Optional properties: |
14 | - ti,dmic: phandle for the OMAP dmic node if the machine have it connected | 14 | - ti,dmic: phandle for the OMAP dmic node if the machine have it connected |
15 | - ti,jack_detection: Need to be set to <1> if the board capable to detect jack | 15 | - ti,jack_detection: Need to be present if the board capable to detect jack |
16 | insertion, removal. | 16 | insertion, removal. |
17 | 17 | ||
18 | Available audio endpoints for the audio-routing table: | 18 | Available audio endpoints for the audio-routing table: |
@@ -59,7 +59,7 @@ sound { | |||
59 | compatible = "ti,abe-twl6040"; | 59 | compatible = "ti,abe-twl6040"; |
60 | ti,model = "SDP4430"; | 60 | ti,model = "SDP4430"; |
61 | 61 | ||
62 | ti,jack-detection = <1>; | 62 | ti,jack-detection; |
63 | ti,mclk-freq = <38400000>; | 63 | ti,mclk-freq = <38400000>; |
64 | 64 | ||
65 | ti,mcpdm = <&mcpdm>; | 65 | ti,mcpdm = <&mcpdm>; |
diff --git a/Documentation/networking/vxlan.txt b/Documentation/networking/vxlan.txt index 5b34b762d7d5..6d993510f091 100644 --- a/Documentation/networking/vxlan.txt +++ b/Documentation/networking/vxlan.txt | |||
@@ -32,7 +32,7 @@ no entry is in the forwarding table. | |||
32 | # ip link delete vxlan0 | 32 | # ip link delete vxlan0 |
33 | 33 | ||
34 | 3. Show vxlan info | 34 | 3. Show vxlan info |
35 | # ip -d show vxlan0 | 35 | # ip -d link show vxlan0 |
36 | 36 | ||
37 | It is possible to create, destroy and display the vxlan | 37 | It is possible to create, destroy and display the vxlan |
38 | forwarding table using the new bridge command. | 38 | forwarding table using the new bridge command. |
@@ -41,7 +41,7 @@ forwarding table using the new bridge command. | |||
41 | # bridge fdb add to 00:17:42:8a:b4:05 dst 192.19.0.2 dev vxlan0 | 41 | # bridge fdb add to 00:17:42:8a:b4:05 dst 192.19.0.2 dev vxlan0 |
42 | 42 | ||
43 | 2. Delete forwarding table entry | 43 | 2. Delete forwarding table entry |
44 | # bridge fdb delete 00:17:42:8a:b4:05 | 44 | # bridge fdb delete 00:17:42:8a:b4:05 dev vxlan0 |
45 | 45 | ||
46 | 3. Show forwarding table | 46 | 3. Show forwarding table |
47 | # bridge fdb show dev vxlan0 | 47 | # bridge fdb show dev vxlan0 |
diff --git a/MAINTAINERS b/MAINTAINERS index bb0b27db673f..9386a63ea8f6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -526,17 +526,17 @@ F: drivers/video/geode/ | |||
526 | F: arch/x86/include/asm/geode.h | 526 | F: arch/x86/include/asm/geode.h |
527 | 527 | ||
528 | AMD IOMMU (AMD-VI) | 528 | AMD IOMMU (AMD-VI) |
529 | M: Joerg Roedel <joerg.roedel@amd.com> | 529 | M: Joerg Roedel <joro@8bytes.org> |
530 | L: iommu@lists.linux-foundation.org | 530 | L: iommu@lists.linux-foundation.org |
531 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git | 531 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git |
532 | S: Supported | 532 | S: Maintained |
533 | F: drivers/iommu/amd_iommu*.[ch] | 533 | F: drivers/iommu/amd_iommu*.[ch] |
534 | F: include/linux/amd-iommu.h | 534 | F: include/linux/amd-iommu.h |
535 | 535 | ||
536 | AMD MICROCODE UPDATE SUPPORT | 536 | AMD MICROCODE UPDATE SUPPORT |
537 | M: Andreas Herrmann <andreas.herrmann3@amd.com> | 537 | M: Andreas Herrmann <herrmann.der.user@googlemail.com> |
538 | L: amd64-microcode@amd64.org | 538 | L: amd64-microcode@amd64.org |
539 | S: Supported | 539 | S: Maintained |
540 | F: arch/x86/kernel/microcode_amd.c | 540 | F: arch/x86/kernel/microcode_amd.c |
541 | 541 | ||
542 | AMS (Apple Motion Sensor) DRIVER | 542 | AMS (Apple Motion Sensor) DRIVER |
@@ -841,6 +841,14 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/kristoffer/linux-hpc.git | |||
841 | F: arch/arm/mach-sa1100/jornada720.c | 841 | F: arch/arm/mach-sa1100/jornada720.c |
842 | F: arch/arm/mach-sa1100/include/mach/jornada720.h | 842 | F: arch/arm/mach-sa1100/include/mach/jornada720.h |
843 | 843 | ||
844 | ARM/IGEP MACHINE SUPPORT | ||
845 | M: Enric Balletbo i Serra <eballetbo@gmail.com> | ||
846 | M: Javier Martinez Canillas <javier@dowhile0.org> | ||
847 | L: linux-omap@vger.kernel.org | ||
848 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||
849 | S: Maintained | ||
850 | F: arch/arm/mach-omap2/board-igep0020.c | ||
851 | |||
844 | ARM/INCOME PXA270 SUPPORT | 852 | ARM/INCOME PXA270 SUPPORT |
845 | M: Marek Vasut <marek.vasut@gmail.com> | 853 | M: Marek Vasut <marek.vasut@gmail.com> |
846 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 854 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
@@ -2708,10 +2716,10 @@ F: include/linux/edac.h | |||
2708 | 2716 | ||
2709 | EDAC-AMD64 | 2717 | EDAC-AMD64 |
2710 | M: Doug Thompson <dougthompson@xmission.com> | 2718 | M: Doug Thompson <dougthompson@xmission.com> |
2711 | M: Borislav Petkov <borislav.petkov@amd.com> | 2719 | M: Borislav Petkov <bp@alien8.de> |
2712 | L: linux-edac@vger.kernel.org | 2720 | L: linux-edac@vger.kernel.org |
2713 | W: bluesmoke.sourceforge.net | 2721 | W: bluesmoke.sourceforge.net |
2714 | S: Supported | 2722 | S: Maintained |
2715 | F: drivers/edac/amd64_edac* | 2723 | F: drivers/edac/amd64_edac* |
2716 | 2724 | ||
2717 | EDAC-E752X | 2725 | EDAC-E752X |
@@ -3753,7 +3761,7 @@ S: Maintained | |||
3753 | F: drivers/platform/x86/ideapad-laptop.c | 3761 | F: drivers/platform/x86/ideapad-laptop.c |
3754 | 3762 | ||
3755 | IDE/ATAPI DRIVERS | 3763 | IDE/ATAPI DRIVERS |
3756 | M: Borislav Petkov <petkovbb@gmail.com> | 3764 | M: Borislav Petkov <bp@alien8.de> |
3757 | L: linux-ide@vger.kernel.org | 3765 | L: linux-ide@vger.kernel.org |
3758 | S: Maintained | 3766 | S: Maintained |
3759 | F: Documentation/cdrom/ide-cd | 3767 | F: Documentation/cdrom/ide-cd |
@@ -4280,8 +4288,8 @@ F: include/linux/lockd/ | |||
4280 | F: include/linux/sunrpc/ | 4288 | F: include/linux/sunrpc/ |
4281 | 4289 | ||
4282 | KERNEL VIRTUAL MACHINE (KVM) | 4290 | KERNEL VIRTUAL MACHINE (KVM) |
4283 | M: Avi Kivity <avi@redhat.com> | ||
4284 | M: Marcelo Tosatti <mtosatti@redhat.com> | 4291 | M: Marcelo Tosatti <mtosatti@redhat.com> |
4292 | M: Gleb Natapov <gleb@redhat.com> | ||
4285 | L: kvm@vger.kernel.org | 4293 | L: kvm@vger.kernel.org |
4286 | W: http://kvm.qumranet.com | 4294 | W: http://kvm.qumranet.com |
4287 | S: Supported | 4295 | S: Supported |
@@ -5413,7 +5421,7 @@ S: Maintained | |||
5413 | F: sound/drivers/opl4/ | 5421 | F: sound/drivers/opl4/ |
5414 | 5422 | ||
5415 | OPROFILE | 5423 | OPROFILE |
5416 | M: Robert Richter <robert.richter@amd.com> | 5424 | M: Robert Richter <rric@kernel.org> |
5417 | L: oprofile-list@lists.sf.net | 5425 | L: oprofile-list@lists.sf.net |
5418 | S: Maintained | 5426 | S: Maintained |
5419 | F: arch/*/include/asm/oprofile*.h | 5427 | F: arch/*/include/asm/oprofile*.h |
@@ -8198,7 +8206,7 @@ F: drivers/platform/x86 | |||
8198 | 8206 | ||
8199 | X86 MCE INFRASTRUCTURE | 8207 | X86 MCE INFRASTRUCTURE |
8200 | M: Tony Luck <tony.luck@intel.com> | 8208 | M: Tony Luck <tony.luck@intel.com> |
8201 | M: Borislav Petkov <bp@amd64.org> | 8209 | M: Borislav Petkov <bp@alien8.de> |
8202 | L: linux-edac@vger.kernel.org | 8210 | L: linux-edac@vger.kernel.org |
8203 | S: Maintained | 8211 | S: Maintained |
8204 | F: arch/x86/kernel/cpu/mcheck/* | 8212 | F: arch/x86/kernel/cpu/mcheck/* |
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 3 | 1 | VERSION = 3 |
2 | PATCHLEVEL = 7 | 2 | PATCHLEVEL = 7 |
3 | SUBLEVEL = 0 | 3 | SUBLEVEL = 0 |
4 | EXTRAVERSION = -rc6 | 4 | EXTRAVERSION = -rc7 |
5 | NAME = Terrified Chipmunk | 5 | NAME = Terrified Chipmunk |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 1e6956a90608..14db93e4c8a8 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c | |||
@@ -445,7 +445,7 @@ struct procfs_args { | |||
445 | * unhappy with OSF UFS. [CHECKME] | 445 | * unhappy with OSF UFS. [CHECKME] |
446 | */ | 446 | */ |
447 | static int | 447 | static int |
448 | osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags) | 448 | osf_ufs_mount(const char *dirname, struct ufs_args __user *args, int flags) |
449 | { | 449 | { |
450 | int retval; | 450 | int retval; |
451 | struct cdfs_args tmp; | 451 | struct cdfs_args tmp; |
@@ -465,7 +465,7 @@ osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags) | |||
465 | } | 465 | } |
466 | 466 | ||
467 | static int | 467 | static int |
468 | osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags) | 468 | osf_cdfs_mount(const char *dirname, struct cdfs_args __user *args, int flags) |
469 | { | 469 | { |
470 | int retval; | 470 | int retval; |
471 | struct cdfs_args tmp; | 471 | struct cdfs_args tmp; |
@@ -485,7 +485,7 @@ osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags) | |||
485 | } | 485 | } |
486 | 486 | ||
487 | static int | 487 | static int |
488 | osf_procfs_mount(char *dirname, struct procfs_args __user *args, int flags) | 488 | osf_procfs_mount(const char *dirname, struct procfs_args __user *args, int flags) |
489 | { | 489 | { |
490 | struct procfs_args tmp; | 490 | struct procfs_args tmp; |
491 | 491 | ||
diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi index d410581a5a85..aaa42d8d4f88 100644 --- a/arch/arm/boot/dts/at91sam9260.dtsi +++ b/arch/arm/boot/dts/at91sam9260.dtsi | |||
@@ -29,6 +29,7 @@ | |||
29 | tcb0 = &tcb0; | 29 | tcb0 = &tcb0; |
30 | tcb1 = &tcb1; | 30 | tcb1 = &tcb1; |
31 | i2c0 = &i2c0; | 31 | i2c0 = &i2c0; |
32 | ssc0 = &ssc0; | ||
32 | }; | 33 | }; |
33 | cpus { | 34 | cpus { |
34 | cpu@0 { | 35 | cpu@0 { |
@@ -212,6 +213,13 @@ | |||
212 | status = "disabled"; | 213 | status = "disabled"; |
213 | }; | 214 | }; |
214 | 215 | ||
216 | ssc0: ssc@fffbc000 { | ||
217 | compatible = "atmel,at91rm9200-ssc"; | ||
218 | reg = <0xfffbc000 0x4000>; | ||
219 | interrupts = <14 4 5>; | ||
220 | status = "disable"; | ||
221 | }; | ||
222 | |||
215 | adc0: adc@fffe0000 { | 223 | adc0: adc@fffe0000 { |
216 | compatible = "atmel,at91sam9260-adc"; | 224 | compatible = "atmel,at91sam9260-adc"; |
217 | reg = <0xfffe0000 0x100>; | 225 | reg = <0xfffe0000 0x100>; |
diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi index 3e6e5c1abbf3..3b721ee59b10 100644 --- a/arch/arm/boot/dts/at91sam9263.dtsi +++ b/arch/arm/boot/dts/at91sam9263.dtsi | |||
@@ -25,6 +25,8 @@ | |||
25 | gpio4 = &pioE; | 25 | gpio4 = &pioE; |
26 | tcb0 = &tcb0; | 26 | tcb0 = &tcb0; |
27 | i2c0 = &i2c0; | 27 | i2c0 = &i2c0; |
28 | ssc0 = &ssc0; | ||
29 | ssc1 = &ssc1; | ||
28 | }; | 30 | }; |
29 | cpus { | 31 | cpus { |
30 | cpu@0 { | 32 | cpu@0 { |
@@ -173,6 +175,20 @@ | |||
173 | status = "disabled"; | 175 | status = "disabled"; |
174 | }; | 176 | }; |
175 | 177 | ||
178 | ssc0: ssc@fff98000 { | ||
179 | compatible = "atmel,at91rm9200-ssc"; | ||
180 | reg = <0xfff98000 0x4000>; | ||
181 | interrupts = <16 4 5>; | ||
182 | status = "disable"; | ||
183 | }; | ||
184 | |||
185 | ssc1: ssc@fff9c000 { | ||
186 | compatible = "atmel,at91rm9200-ssc"; | ||
187 | reg = <0xfff9c000 0x4000>; | ||
188 | interrupts = <17 4 5>; | ||
189 | status = "disable"; | ||
190 | }; | ||
191 | |||
176 | macb0: ethernet@fffbc000 { | 192 | macb0: ethernet@fffbc000 { |
177 | compatible = "cdns,at32ap7000-macb", "cdns,macb"; | 193 | compatible = "cdns,at32ap7000-macb", "cdns,macb"; |
178 | reg = <0xfffbc000 0x100>; | 194 | reg = <0xfffbc000 0x100>; |
diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi index e6391a4e6649..2dcec8de759f 100644 --- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi +++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi | |||
@@ -30,6 +30,16 @@ | |||
30 | 30 | ||
31 | ahb { | 31 | ahb { |
32 | apb { | 32 | apb { |
33 | pinctrl@fffff400 { | ||
34 | board { | ||
35 | pinctrl_pck0_as_mck: pck0_as_mck { | ||
36 | atmel,pins = | ||
37 | <2 1 0x2 0x0>; /* PC1 periph B */ | ||
38 | }; | ||
39 | |||
40 | }; | ||
41 | }; | ||
42 | |||
33 | dbgu: serial@fffff200 { | 43 | dbgu: serial@fffff200 { |
34 | status = "okay"; | 44 | status = "okay"; |
35 | }; | 45 | }; |
@@ -51,6 +61,11 @@ | |||
51 | atmel,vbus-gpio = <&pioC 5 0>; | 61 | atmel,vbus-gpio = <&pioC 5 0>; |
52 | status = "okay"; | 62 | status = "okay"; |
53 | }; | 63 | }; |
64 | |||
65 | ssc0: ssc@fffbc000 { | ||
66 | status = "okay"; | ||
67 | pinctrl-0 = <&pinctrl_ssc0_tx>; | ||
68 | }; | ||
54 | }; | 69 | }; |
55 | 70 | ||
56 | nand0: nand@40000000 { | 71 | nand0: nand@40000000 { |
@@ -114,7 +129,7 @@ | |||
114 | reg = <0x50>; | 129 | reg = <0x50>; |
115 | }; | 130 | }; |
116 | 131 | ||
117 | wm8731@1b { | 132 | wm8731: wm8731@1b { |
118 | compatible = "wm8731"; | 133 | compatible = "wm8731"; |
119 | reg = <0x1b>; | 134 | reg = <0x1b>; |
120 | }; | 135 | }; |
@@ -139,4 +154,19 @@ | |||
139 | gpio-key,wakeup; | 154 | gpio-key,wakeup; |
140 | }; | 155 | }; |
141 | }; | 156 | }; |
157 | |||
158 | sound { | ||
159 | compatible = "atmel,at91sam9g20ek-wm8731-audio"; | ||
160 | pinctrl-names = "default"; | ||
161 | pinctrl-0 = <&pinctrl_pck0_as_mck>; | ||
162 | |||
163 | atmel,model = "wm8731 @ AT91SAMG20EK"; | ||
164 | |||
165 | atmel,audio-routing = | ||
166 | "Ext Spk", "LHPOUT", | ||
167 | "Int Mic", "MICIN"; | ||
168 | |||
169 | atmel,ssc-controller = <&ssc0>; | ||
170 | atmel,audio-codec = <&wm8731>; | ||
171 | }; | ||
142 | }; | 172 | }; |
diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index 3add030d61f8..acfa207162ff 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi | |||
@@ -31,6 +31,8 @@ | |||
31 | tcb1 = &tcb1; | 31 | tcb1 = &tcb1; |
32 | i2c0 = &i2c0; | 32 | i2c0 = &i2c0; |
33 | i2c1 = &i2c1; | 33 | i2c1 = &i2c1; |
34 | ssc0 = &ssc0; | ||
35 | ssc1 = &ssc1; | ||
34 | }; | 36 | }; |
35 | cpus { | 37 | cpus { |
36 | cpu@0 { | 38 | cpu@0 { |
@@ -226,6 +228,20 @@ | |||
226 | status = "disabled"; | 228 | status = "disabled"; |
227 | }; | 229 | }; |
228 | 230 | ||
231 | ssc0: ssc@fff9c000 { | ||
232 | compatible = "atmel,at91sam9g45-ssc"; | ||
233 | reg = <0xfff9c000 0x4000>; | ||
234 | interrupts = <16 4 5>; | ||
235 | status = "disable"; | ||
236 | }; | ||
237 | |||
238 | ssc1: ssc@fffa0000 { | ||
239 | compatible = "atmel,at91sam9g45-ssc"; | ||
240 | reg = <0xfffa0000 0x4000>; | ||
241 | interrupts = <17 4 5>; | ||
242 | status = "disable"; | ||
243 | }; | ||
244 | |||
229 | adc0: adc@fffb0000 { | 245 | adc0: adc@fffb0000 { |
230 | compatible = "atmel,at91sam9260-adc"; | 246 | compatible = "atmel,at91sam9260-adc"; |
231 | reg = <0xfffb0000 0x100>; | 247 | reg = <0xfffb0000 0x100>; |
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index 03fc136421c5..69667d0ac347 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi | |||
@@ -30,6 +30,7 @@ | |||
30 | i2c0 = &i2c0; | 30 | i2c0 = &i2c0; |
31 | i2c1 = &i2c1; | 31 | i2c1 = &i2c1; |
32 | i2c2 = &i2c2; | 32 | i2c2 = &i2c2; |
33 | ssc0 = &ssc0; | ||
33 | }; | 34 | }; |
34 | cpus { | 35 | cpus { |
35 | cpu@0 { | 36 | cpu@0 { |
@@ -87,6 +88,13 @@ | |||
87 | interrupts = <1 4 7>; | 88 | interrupts = <1 4 7>; |
88 | }; | 89 | }; |
89 | 90 | ||
91 | ssc0: ssc@f0010000 { | ||
92 | compatible = "atmel,at91sam9g45-ssc"; | ||
93 | reg = <0xf0010000 0x4000>; | ||
94 | interrupts = <28 4 5>; | ||
95 | status = "disable"; | ||
96 | }; | ||
97 | |||
90 | tcb0: timer@f8008000 { | 98 | tcb0: timer@f8008000 { |
91 | compatible = "atmel,at91sam9x5-tcb"; | 99 | compatible = "atmel,at91sam9x5-tcb"; |
92 | reg = <0xf8008000 0x100>; | 100 | reg = <0xf8008000 0x100>; |
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c index 5269825194a8..af47c75db513 100644 --- a/arch/arm/mach-at91/at91rm9200.c +++ b/arch/arm/mach-at91/at91rm9200.c | |||
@@ -184,9 +184,12 @@ static struct clk_lookup periph_clocks_lookups[] = { | |||
184 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tc3_clk), | 184 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tc3_clk), |
185 | CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk), | 185 | CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk), |
186 | CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk), | 186 | CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk), |
187 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), | 187 | CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.0", &ssc0_clk), |
188 | CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), | 188 | CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.1", &ssc1_clk), |
189 | CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk), | 189 | CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.2", &ssc2_clk), |
190 | CLKDEV_CON_DEV_ID("pclk", "fffd0000.ssc", &ssc0_clk), | ||
191 | CLKDEV_CON_DEV_ID("pclk", "fffd4000.ssc", &ssc1_clk), | ||
192 | CLKDEV_CON_DEV_ID("pclk", "fffd8000.ssc", &ssc2_clk), | ||
190 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91rm9200.0", &twi_clk), | 193 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91rm9200.0", &twi_clk), |
191 | /* fake hclk clock */ | 194 | /* fake hclk clock */ |
192 | CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), | 195 | CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), |
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index 3cee0e6ea7c3..9e76427aaec2 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c | |||
@@ -752,7 +752,7 @@ static struct resource ssc0_resources[] = { | |||
752 | }; | 752 | }; |
753 | 753 | ||
754 | static struct platform_device at91rm9200_ssc0_device = { | 754 | static struct platform_device at91rm9200_ssc0_device = { |
755 | .name = "ssc", | 755 | .name = "at91rm9200_ssc", |
756 | .id = 0, | 756 | .id = 0, |
757 | .dev = { | 757 | .dev = { |
758 | .dma_mask = &ssc0_dmamask, | 758 | .dma_mask = &ssc0_dmamask, |
@@ -794,7 +794,7 @@ static struct resource ssc1_resources[] = { | |||
794 | }; | 794 | }; |
795 | 795 | ||
796 | static struct platform_device at91rm9200_ssc1_device = { | 796 | static struct platform_device at91rm9200_ssc1_device = { |
797 | .name = "ssc", | 797 | .name = "at91rm9200_ssc", |
798 | .id = 1, | 798 | .id = 1, |
799 | .dev = { | 799 | .dev = { |
800 | .dma_mask = &ssc1_dmamask, | 800 | .dma_mask = &ssc1_dmamask, |
@@ -836,7 +836,7 @@ static struct resource ssc2_resources[] = { | |||
836 | }; | 836 | }; |
837 | 837 | ||
838 | static struct platform_device at91rm9200_ssc2_device = { | 838 | static struct platform_device at91rm9200_ssc2_device = { |
839 | .name = "ssc", | 839 | .name = "at91rm9200_ssc", |
840 | .id = 2, | 840 | .id = 2, |
841 | .dev = { | 841 | .dev = { |
842 | .dma_mask = &ssc2_dmamask, | 842 | .dma_mask = &ssc2_dmamask, |
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index f8202615f4a8..a41eb3d23f68 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c | |||
@@ -210,7 +210,8 @@ static struct clk_lookup periph_clocks_lookups[] = { | |||
210 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tc3_clk), | 210 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tc3_clk), |
211 | CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk), | 211 | CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk), |
212 | CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk), | 212 | CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk), |
213 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc_clk), | 213 | CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.0", &ssc_clk), |
214 | CLKDEV_CON_DEV_ID("pclk", "fffbc000.ssc", &ssc_clk), | ||
214 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260.0", &twi_clk), | 215 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260.0", &twi_clk), |
215 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.0", &twi_clk), | 216 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.0", &twi_clk), |
216 | /* more usart lookup table for DT entries */ | 217 | /* more usart lookup table for DT entries */ |
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 414bd855fb0c..e67cfa2acbe0 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c | |||
@@ -742,7 +742,7 @@ static struct resource ssc_resources[] = { | |||
742 | }; | 742 | }; |
743 | 743 | ||
744 | static struct platform_device at91sam9260_ssc_device = { | 744 | static struct platform_device at91sam9260_ssc_device = { |
745 | .name = "ssc", | 745 | .name = "at91rm9200_ssc", |
746 | .id = 0, | 746 | .id = 0, |
747 | .dev = { | 747 | .dev = { |
748 | .dma_mask = &ssc_dmamask, | 748 | .dma_mask = &ssc_dmamask, |
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index 04295c04b3e0..7fcbe0583342 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c | |||
@@ -174,9 +174,12 @@ static struct clk_lookup periph_clocks_lookups[] = { | |||
174 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), | 174 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), |
175 | CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk), | 175 | CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk), |
176 | CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), | 176 | CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), |
177 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), | 177 | CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.0", &ssc0_clk), |
178 | CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), | 178 | CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.1", &ssc1_clk), |
179 | CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk), | 179 | CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.2", &ssc2_clk), |
180 | CLKDEV_CON_DEV_ID("pclk", "fffbc000.ssc", &ssc0_clk), | ||
181 | CLKDEV_CON_DEV_ID("pclk", "fffc0000.ssc", &ssc1_clk), | ||
182 | CLKDEV_CON_DEV_ID("pclk", "fffc4000.ssc", &ssc2_clk), | ||
180 | CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &hck0), | 183 | CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &hck0), |
181 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9261.0", &twi_clk), | 184 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9261.0", &twi_clk), |
182 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10.0", &twi_clk), | 185 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10.0", &twi_clk), |
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index cd604aad8e96..a27d9dd0faa4 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c | |||
@@ -706,7 +706,7 @@ static struct resource ssc0_resources[] = { | |||
706 | }; | 706 | }; |
707 | 707 | ||
708 | static struct platform_device at91sam9261_ssc0_device = { | 708 | static struct platform_device at91sam9261_ssc0_device = { |
709 | .name = "ssc", | 709 | .name = "at91rm9200_ssc", |
710 | .id = 0, | 710 | .id = 0, |
711 | .dev = { | 711 | .dev = { |
712 | .dma_mask = &ssc0_dmamask, | 712 | .dma_mask = &ssc0_dmamask, |
@@ -748,7 +748,7 @@ static struct resource ssc1_resources[] = { | |||
748 | }; | 748 | }; |
749 | 749 | ||
750 | static struct platform_device at91sam9261_ssc1_device = { | 750 | static struct platform_device at91sam9261_ssc1_device = { |
751 | .name = "ssc", | 751 | .name = "at91rm9200_ssc", |
752 | .id = 1, | 752 | .id = 1, |
753 | .dev = { | 753 | .dev = { |
754 | .dma_mask = &ssc1_dmamask, | 754 | .dma_mask = &ssc1_dmamask, |
@@ -790,7 +790,7 @@ static struct resource ssc2_resources[] = { | |||
790 | }; | 790 | }; |
791 | 791 | ||
792 | static struct platform_device at91sam9261_ssc2_device = { | 792 | static struct platform_device at91sam9261_ssc2_device = { |
793 | .name = "ssc", | 793 | .name = "at91rm9200_ssc", |
794 | .id = 2, | 794 | .id = 2, |
795 | .dev = { | 795 | .dev = { |
796 | .dma_mask = &ssc2_dmamask, | 796 | .dma_mask = &ssc2_dmamask, |
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index d6f9c23927c4..c0f4c8c1f4ed 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c | |||
@@ -186,8 +186,10 @@ static struct clk *periph_clocks[] __initdata = { | |||
186 | static struct clk_lookup periph_clocks_lookups[] = { | 186 | static struct clk_lookup periph_clocks_lookups[] = { |
187 | /* One additional fake clock for macb_hclk */ | 187 | /* One additional fake clock for macb_hclk */ |
188 | CLKDEV_CON_ID("hclk", &macb_clk), | 188 | CLKDEV_CON_ID("hclk", &macb_clk), |
189 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), | 189 | CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.0", &ssc0_clk), |
190 | CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), | 190 | CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.1", &ssc1_clk), |
191 | CLKDEV_CON_DEV_ID("pclk", "fff98000.ssc", &ssc0_clk), | ||
192 | CLKDEV_CON_DEV_ID("pclk", "fff9c000.ssc", &ssc1_clk), | ||
191 | CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.0", &mmc0_clk), | 193 | CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.0", &mmc0_clk), |
192 | CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.1", &mmc1_clk), | 194 | CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.1", &mmc1_clk), |
193 | CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), | 195 | CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), |
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index 9c61e59a2104..8215839f2d54 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c | |||
@@ -1199,7 +1199,7 @@ static struct resource ssc0_resources[] = { | |||
1199 | }; | 1199 | }; |
1200 | 1200 | ||
1201 | static struct platform_device at91sam9263_ssc0_device = { | 1201 | static struct platform_device at91sam9263_ssc0_device = { |
1202 | .name = "ssc", | 1202 | .name = "at91rm9200_ssc", |
1203 | .id = 0, | 1203 | .id = 0, |
1204 | .dev = { | 1204 | .dev = { |
1205 | .dma_mask = &ssc0_dmamask, | 1205 | .dma_mask = &ssc0_dmamask, |
@@ -1241,7 +1241,7 @@ static struct resource ssc1_resources[] = { | |||
1241 | }; | 1241 | }; |
1242 | 1242 | ||
1243 | static struct platform_device at91sam9263_ssc1_device = { | 1243 | static struct platform_device at91sam9263_ssc1_device = { |
1244 | .name = "ssc", | 1244 | .name = "at91rm9200_ssc", |
1245 | .id = 1, | 1245 | .id = 1, |
1246 | .dev = { | 1246 | .dev = { |
1247 | .dma_mask = &ssc1_dmamask, | 1247 | .dma_mask = &ssc1_dmamask, |
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index 84af1b506d92..a4282d3742bf 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c | |||
@@ -239,8 +239,10 @@ static struct clk_lookup periph_clocks_lookups[] = { | |||
239 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tcb0_clk), | 239 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tcb0_clk), |
240 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10.0", &twi0_clk), | 240 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10.0", &twi0_clk), |
241 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10.1", &twi1_clk), | 241 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10.1", &twi1_clk), |
242 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), | 242 | CLKDEV_CON_DEV_ID("pclk", "at91sam9g45_ssc.0", &ssc0_clk), |
243 | CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), | 243 | CLKDEV_CON_DEV_ID("pclk", "at91sam9g45_ssc.1", &ssc1_clk), |
244 | CLKDEV_CON_DEV_ID("pclk", "fff9c000.ssc", &ssc0_clk), | ||
245 | CLKDEV_CON_DEV_ID("pclk", "fffa0000.ssc", &ssc1_clk), | ||
244 | CLKDEV_CON_DEV_ID(NULL, "atmel-trng", &trng_clk), | 246 | CLKDEV_CON_DEV_ID(NULL, "atmel-trng", &trng_clk), |
245 | CLKDEV_CON_DEV_ID(NULL, "atmel_sha", &aestdessha_clk), | 247 | CLKDEV_CON_DEV_ID(NULL, "atmel_sha", &aestdessha_clk), |
246 | CLKDEV_CON_DEV_ID(NULL, "atmel_tdes", &aestdessha_clk), | 248 | CLKDEV_CON_DEV_ID(NULL, "atmel_tdes", &aestdessha_clk), |
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index fcd233cb33d2..d26474a97fec 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c | |||
@@ -1459,7 +1459,7 @@ static struct resource ssc0_resources[] = { | |||
1459 | }; | 1459 | }; |
1460 | 1460 | ||
1461 | static struct platform_device at91sam9g45_ssc0_device = { | 1461 | static struct platform_device at91sam9g45_ssc0_device = { |
1462 | .name = "ssc", | 1462 | .name = "at91sam9g45_ssc", |
1463 | .id = 0, | 1463 | .id = 0, |
1464 | .dev = { | 1464 | .dev = { |
1465 | .dma_mask = &ssc0_dmamask, | 1465 | .dma_mask = &ssc0_dmamask, |
@@ -1501,7 +1501,7 @@ static struct resource ssc1_resources[] = { | |||
1501 | }; | 1501 | }; |
1502 | 1502 | ||
1503 | static struct platform_device at91sam9g45_ssc1_device = { | 1503 | static struct platform_device at91sam9g45_ssc1_device = { |
1504 | .name = "ssc", | 1504 | .name = "at91sam9g45_ssc", |
1505 | .id = 1, | 1505 | .id = 1, |
1506 | .dev = { | 1506 | .dev = { |
1507 | .dma_mask = &ssc1_dmamask, | 1507 | .dma_mask = &ssc1_dmamask, |
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index 72e908412222..b683fdc699f1 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c | |||
@@ -184,8 +184,10 @@ static struct clk_lookup periph_clocks_lookups[] = { | |||
184 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), | 184 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), |
185 | CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk), | 185 | CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk), |
186 | CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), | 186 | CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), |
187 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), | 187 | CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.0", &ssc0_clk), |
188 | CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), | 188 | CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.1", &ssc1_clk), |
189 | CLKDEV_CON_DEV_ID("pclk", "fffc0000.ssc", &ssc0_clk), | ||
190 | CLKDEV_CON_DEV_ID("pclk", "fffc4000.ssc", &ssc1_clk), | ||
189 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.0", &twi0_clk), | 191 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.0", &twi0_clk), |
190 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.1", &twi1_clk), | 192 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.1", &twi1_clk), |
191 | CLKDEV_CON_ID("pioA", &pioA_clk), | 193 | CLKDEV_CON_ID("pioA", &pioA_clk), |
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index 5047bdc92adf..b656110e8afe 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c | |||
@@ -832,7 +832,7 @@ static struct resource ssc0_resources[] = { | |||
832 | }; | 832 | }; |
833 | 833 | ||
834 | static struct platform_device at91sam9rl_ssc0_device = { | 834 | static struct platform_device at91sam9rl_ssc0_device = { |
835 | .name = "ssc", | 835 | .name = "at91rm9200_ssc", |
836 | .id = 0, | 836 | .id = 0, |
837 | .dev = { | 837 | .dev = { |
838 | .dma_mask = &ssc0_dmamask, | 838 | .dma_mask = &ssc0_dmamask, |
@@ -874,7 +874,7 @@ static struct resource ssc1_resources[] = { | |||
874 | }; | 874 | }; |
875 | 875 | ||
876 | static struct platform_device at91sam9rl_ssc1_device = { | 876 | static struct platform_device at91sam9rl_ssc1_device = { |
877 | .name = "ssc", | 877 | .name = "at91rm9200_ssc", |
878 | .id = 1, | 878 | .id = 1, |
879 | .dev = { | 879 | .dev = { |
880 | .dma_mask = &ssc1_dmamask, | 880 | .dma_mask = &ssc1_dmamask, |
diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c index e5035380dcbc..18fbbb27f97f 100644 --- a/arch/arm/mach-at91/at91sam9x5.c +++ b/arch/arm/mach-at91/at91sam9x5.c | |||
@@ -231,6 +231,7 @@ static struct clk_lookup periph_clocks_lookups[] = { | |||
231 | CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb0_clk), | 231 | CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb0_clk), |
232 | CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma0_clk), | 232 | CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma0_clk), |
233 | CLKDEV_CON_DEV_ID("dma_clk", "ffffee00.dma-controller", &dma1_clk), | 233 | CLKDEV_CON_DEV_ID("dma_clk", "ffffee00.dma-controller", &dma1_clk), |
234 | CLKDEV_CON_DEV_ID("pclk", "f0010000.ssc", &ssc_clk), | ||
234 | CLKDEV_CON_DEV_ID(NULL, "f8010000.i2c", &twi0_clk), | 235 | CLKDEV_CON_DEV_ID(NULL, "f8010000.i2c", &twi0_clk), |
235 | CLKDEV_CON_DEV_ID(NULL, "f8014000.i2c", &twi1_clk), | 236 | CLKDEV_CON_DEV_ID(NULL, "f8014000.i2c", &twi1_clk), |
236 | CLKDEV_CON_DEV_ID(NULL, "f8018000.i2c", &twi2_clk), | 237 | CLKDEV_CON_DEV_ID(NULL, "f8018000.i2c", &twi2_clk), |
diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c index 3ab2b86a3762..ebdbf42c02c1 100644 --- a/arch/arm/mach-at91/board-sam9g20ek.c +++ b/arch/arm/mach-at91/board-sam9g20ek.c | |||
@@ -353,6 +353,16 @@ static struct i2c_board_info __initdata ek_i2c_devices[] = { | |||
353 | }, | 353 | }, |
354 | }; | 354 | }; |
355 | 355 | ||
356 | static struct platform_device sam9g20ek_audio_device = { | ||
357 | .name = "at91sam9g20ek-audio", | ||
358 | .id = -1, | ||
359 | }; | ||
360 | |||
361 | static void __init ek_add_device_audio(void) | ||
362 | { | ||
363 | platform_device_register(&sam9g20ek_audio_device); | ||
364 | } | ||
365 | |||
356 | 366 | ||
357 | static void __init ek_board_init(void) | 367 | static void __init ek_board_init(void) |
358 | { | 368 | { |
@@ -394,6 +404,7 @@ static void __init ek_board_init(void) | |||
394 | at91_set_B_periph(AT91_PIN_PC1, 0); | 404 | at91_set_B_periph(AT91_PIN_PC1, 0); |
395 | /* SSC (for WM8731) */ | 405 | /* SSC (for WM8731) */ |
396 | at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX); | 406 | at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX); |
407 | ek_add_device_audio(); | ||
397 | } | 408 | } |
398 | 409 | ||
399 | MACHINE_START(AT91SAM9G20EK, "Atmel AT91SAM9G20-EK") | 410 | MACHINE_START(AT91SAM9G20EK, "Atmel AT91SAM9G20-EK") |
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index 32ee3f895967..d9bc3fa7bb22 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c | |||
@@ -762,16 +762,19 @@ static u8 da850_iis_serializer_direction[] = { | |||
762 | }; | 762 | }; |
763 | 763 | ||
764 | static struct snd_platform_data da850_evm_snd_data = { | 764 | static struct snd_platform_data da850_evm_snd_data = { |
765 | .tx_dma_offset = 0x2000, | 765 | .tx_dma_offset = 0x2000, |
766 | .rx_dma_offset = 0x2000, | 766 | .rx_dma_offset = 0x2000, |
767 | .op_mode = DAVINCI_MCASP_IIS_MODE, | 767 | .op_mode = DAVINCI_MCASP_IIS_MODE, |
768 | .num_serializer = ARRAY_SIZE(da850_iis_serializer_direction), | 768 | .num_serializer = ARRAY_SIZE(da850_iis_serializer_direction), |
769 | .tdm_slots = 2, | 769 | .tdm_slots = 2, |
770 | .serial_dir = da850_iis_serializer_direction, | 770 | .serial_dir = da850_iis_serializer_direction, |
771 | .asp_chan_q = EVENTQ_0, | 771 | .asp_chan_q = EVENTQ_0, |
772 | .version = MCASP_VERSION_2, | 772 | .ram_chan_q = EVENTQ_1, |
773 | .txnumevt = 1, | 773 | .version = MCASP_VERSION_2, |
774 | .rxnumevt = 1, | 774 | .txnumevt = 1, |
775 | .rxnumevt = 1, | ||
776 | .sram_size_playback = SZ_8K, | ||
777 | .sram_size_capture = SZ_8K, | ||
775 | }; | 778 | }; |
776 | 779 | ||
777 | static const short da850_evm_mcasp_pins[] __initconst = { | 780 | static const short da850_evm_mcasp_pins[] __initconst = { |
@@ -1509,6 +1512,7 @@ static __init void da850_evm_init(void) | |||
1509 | pr_warning("da850_evm_init: mcasp mux setup failed: %d\n", | 1512 | pr_warning("da850_evm_init: mcasp mux setup failed: %d\n", |
1510 | ret); | 1513 | ret); |
1511 | 1514 | ||
1515 | da850_evm_snd_data.sram_pool = sram_get_gen_pool(); | ||
1512 | da8xx_register_mcasp(0, &da850_evm_snd_data); | 1516 | da8xx_register_mcasp(0, &da850_evm_snd_data); |
1513 | 1517 | ||
1514 | ret = davinci_cfg_reg_list(da850_lcdcntl_pins); | 1518 | ret = davinci_cfg_reg_list(da850_lcdcntl_pins); |
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index cd0c8b1e1ecf..14e9947bad6e 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c | |||
@@ -713,8 +713,7 @@ static int dm644x_venc_setup_clock(enum vpbe_enc_timings_type type, | |||
713 | break; | 713 | break; |
714 | case VPBE_ENC_CUSTOM_TIMINGS: | 714 | case VPBE_ENC_CUSTOM_TIMINGS: |
715 | if (pclock <= 27000000) { | 715 | if (pclock <= 27000000) { |
716 | v |= DM644X_VPSS_MUXSEL_PLL2_MODE | | 716 | v |= DM644X_VPSS_DACCLKEN; |
717 | DM644X_VPSS_DACCLKEN; | ||
718 | writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL)); | 717 | writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL)); |
719 | } else { | 718 | } else { |
720 | /* | 719 | /* |
diff --git a/arch/arm/mach-exynos/dma.c b/arch/arm/mach-exynos/dma.c index 21d568b3b149..87e07d6fc615 100644 --- a/arch/arm/mach-exynos/dma.c +++ b/arch/arm/mach-exynos/dma.c | |||
@@ -275,6 +275,9 @@ static int __init exynos_dma_init(void) | |||
275 | exynos_pdma1_pdata.nr_valid_peri = | 275 | exynos_pdma1_pdata.nr_valid_peri = |
276 | ARRAY_SIZE(exynos4210_pdma1_peri); | 276 | ARRAY_SIZE(exynos4210_pdma1_peri); |
277 | exynos_pdma1_pdata.peri_id = exynos4210_pdma1_peri; | 277 | exynos_pdma1_pdata.peri_id = exynos4210_pdma1_peri; |
278 | |||
279 | if (samsung_rev() == EXYNOS4210_REV_0) | ||
280 | exynos_mdma1_device.res.start = EXYNOS4_PA_S_MDMA1; | ||
278 | } else if (soc_is_exynos4212() || soc_is_exynos4412()) { | 281 | } else if (soc_is_exynos4212() || soc_is_exynos4412()) { |
279 | exynos_pdma0_pdata.nr_valid_peri = | 282 | exynos_pdma0_pdata.nr_valid_peri = |
280 | ARRAY_SIZE(exynos4212_pdma0_peri); | 283 | ARRAY_SIZE(exynos4212_pdma0_peri); |
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h index 8480849affb9..ed4da4544cd2 100644 --- a/arch/arm/mach-exynos/include/mach/map.h +++ b/arch/arm/mach-exynos/include/mach/map.h | |||
@@ -90,6 +90,7 @@ | |||
90 | 90 | ||
91 | #define EXYNOS4_PA_MDMA0 0x10810000 | 91 | #define EXYNOS4_PA_MDMA0 0x10810000 |
92 | #define EXYNOS4_PA_MDMA1 0x12850000 | 92 | #define EXYNOS4_PA_MDMA1 0x12850000 |
93 | #define EXYNOS4_PA_S_MDMA1 0x12840000 | ||
93 | #define EXYNOS4_PA_PDMA0 0x12680000 | 94 | #define EXYNOS4_PA_PDMA0 0x12680000 |
94 | #define EXYNOS4_PA_PDMA1 0x12690000 | 95 | #define EXYNOS4_PA_PDMA1 0x12690000 |
95 | #define EXYNOS5_PA_MDMA0 0x10800000 | 96 | #define EXYNOS5_PA_MDMA0 0x10800000 |
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index 48d5e41dfbfa..378590694447 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c | |||
@@ -580,6 +580,11 @@ static void __init igep_wlan_bt_init(void) | |||
580 | } else | 580 | } else |
581 | return; | 581 | return; |
582 | 582 | ||
583 | /* Make sure that the GPIO pins are muxed correctly */ | ||
584 | omap_mux_init_gpio(igep_wlan_bt_gpios[0].gpio, OMAP_PIN_OUTPUT); | ||
585 | omap_mux_init_gpio(igep_wlan_bt_gpios[1].gpio, OMAP_PIN_OUTPUT); | ||
586 | omap_mux_init_gpio(igep_wlan_bt_gpios[2].gpio, OMAP_PIN_OUTPUT); | ||
587 | |||
583 | err = gpio_request_array(igep_wlan_bt_gpios, | 588 | err = gpio_request_array(igep_wlan_bt_gpios, |
584 | ARRAY_SIZE(igep_wlan_bt_gpios)); | 589 | ARRAY_SIZE(igep_wlan_bt_gpios)); |
585 | if (err) { | 590 | if (err) { |
diff --git a/arch/arm/mach-omap2/common-board-devices.c b/arch/arm/mach-omap2/common-board-devices.c index 48daac2581b4..84551f205e46 100644 --- a/arch/arm/mach-omap2/common-board-devices.c +++ b/arch/arm/mach-omap2/common-board-devices.c | |||
@@ -64,30 +64,36 @@ void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce, | |||
64 | struct spi_board_info *spi_bi = &ads7846_spi_board_info; | 64 | struct spi_board_info *spi_bi = &ads7846_spi_board_info; |
65 | int err; | 65 | int err; |
66 | 66 | ||
67 | err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown"); | 67 | /* |
68 | if (err) { | 68 | * If a board defines get_pendown_state() function, request the pendown |
69 | pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err); | 69 | * GPIO and set the GPIO debounce time. |
70 | return; | 70 | * If a board does not define the get_pendown_state() function, then |
71 | } | 71 | * the ads7846 driver will setup the pendown GPIO itself. |
72 | */ | ||
73 | if (board_pdata && board_pdata->get_pendown_state) { | ||
74 | err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown"); | ||
75 | if (err) { | ||
76 | pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err); | ||
77 | return; | ||
78 | } | ||
72 | 79 | ||
73 | if (gpio_debounce) | 80 | if (gpio_debounce) |
74 | gpio_set_debounce(gpio_pendown, gpio_debounce); | 81 | gpio_set_debounce(gpio_pendown, gpio_debounce); |
82 | |||
83 | gpio_export(gpio_pendown, 0); | ||
84 | } | ||
75 | 85 | ||
76 | spi_bi->bus_num = bus_num; | 86 | spi_bi->bus_num = bus_num; |
77 | spi_bi->irq = gpio_to_irq(gpio_pendown); | 87 | spi_bi->irq = gpio_to_irq(gpio_pendown); |
78 | 88 | ||
89 | ads7846_config.gpio_pendown = gpio_pendown; | ||
90 | |||
79 | if (board_pdata) { | 91 | if (board_pdata) { |
80 | board_pdata->gpio_pendown = gpio_pendown; | 92 | board_pdata->gpio_pendown = gpio_pendown; |
93 | board_pdata->gpio_pendown_debounce = gpio_debounce; | ||
81 | spi_bi->platform_data = board_pdata; | 94 | spi_bi->platform_data = board_pdata; |
82 | if (board_pdata->get_pendown_state) | ||
83 | gpio_export(gpio_pendown, 0); | ||
84 | } else { | ||
85 | ads7846_config.gpio_pendown = gpio_pendown; | ||
86 | } | 95 | } |
87 | 96 | ||
88 | if (!board_pdata || (board_pdata && !board_pdata->get_pendown_state)) | ||
89 | gpio_free(gpio_pendown); | ||
90 | |||
91 | spi_register_board_info(&ads7846_spi_board_info, 1); | 97 | spi_register_board_info(&ads7846_spi_board_info, 1); |
92 | } | 98 | } |
93 | #else | 99 | #else |
diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c index 44c42057b61c..a256135d8e48 100644 --- a/arch/arm/mach-omap2/twl-common.c +++ b/arch/arm/mach-omap2/twl-common.c | |||
@@ -73,6 +73,7 @@ void __init omap4_pmic_init(const char *pmic_type, | |||
73 | { | 73 | { |
74 | /* PMIC part*/ | 74 | /* PMIC part*/ |
75 | omap_mux_init_signal("sys_nirq1", OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE); | 75 | omap_mux_init_signal("sys_nirq1", OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE); |
76 | omap_mux_init_signal("fref_clk0_out.sys_drm_msecure", OMAP_PIN_OUTPUT); | ||
76 | omap_pmic_init(1, 400, pmic_type, 7 + OMAP44XX_IRQ_GIC_START, pmic_data); | 77 | omap_pmic_init(1, 400, pmic_type, 7 + OMAP44XX_IRQ_GIC_START, pmic_data); |
77 | 78 | ||
78 | /* Register additional devices on i2c1 bus if needed */ | 79 | /* Register additional devices on i2c1 bus if needed */ |
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c index a5683a84c6ee..6013831a043e 100644 --- a/arch/arm/plat-omap/i2c.c +++ b/arch/arm/plat-omap/i2c.c | |||
@@ -26,12 +26,14 @@ | |||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
28 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
29 | #include <linux/i2c-omap.h> | ||
29 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
30 | #include <linux/err.h> | 31 | #include <linux/err.h> |
31 | #include <linux/clk.h> | 32 | #include <linux/clk.h> |
32 | 33 | ||
33 | #include <mach/irqs.h> | 34 | #include <mach/irqs.h> |
34 | #include <plat/i2c.h> | 35 | #include <plat/i2c.h> |
36 | #include <plat/omap-pm.h> | ||
35 | #include <plat/omap_device.h> | 37 | #include <plat/omap_device.h> |
36 | 38 | ||
37 | #define OMAP_I2C_SIZE 0x3f | 39 | #define OMAP_I2C_SIZE 0x3f |
@@ -127,6 +129,16 @@ static inline int omap1_i2c_add_bus(int bus_id) | |||
127 | 129 | ||
128 | 130 | ||
129 | #ifdef CONFIG_ARCH_OMAP2PLUS | 131 | #ifdef CONFIG_ARCH_OMAP2PLUS |
132 | /* | ||
133 | * XXX This function is a temporary compatibility wrapper - only | ||
134 | * needed until the I2C driver can be converted to call | ||
135 | * omap_pm_set_max_dev_wakeup_lat() and handle a return code. | ||
136 | */ | ||
137 | static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t) | ||
138 | { | ||
139 | omap_pm_set_max_mpu_wakeup_lat(dev, t); | ||
140 | } | ||
141 | |||
130 | static inline int omap2_i2c_add_bus(int bus_id) | 142 | static inline int omap2_i2c_add_bus(int bus_id) |
131 | { | 143 | { |
132 | int l; | 144 | int l; |
@@ -158,6 +170,15 @@ static inline int omap2_i2c_add_bus(int bus_id) | |||
158 | dev_attr = (struct omap_i2c_dev_attr *)oh->dev_attr; | 170 | dev_attr = (struct omap_i2c_dev_attr *)oh->dev_attr; |
159 | pdata->flags = dev_attr->flags; | 171 | pdata->flags = dev_attr->flags; |
160 | 172 | ||
173 | /* | ||
174 | * When waiting for completion of a i2c transfer, we need to | ||
175 | * set a wake up latency constraint for the MPU. This is to | ||
176 | * ensure quick enough wakeup from idle, when transfer | ||
177 | * completes. | ||
178 | * Only omap3 has support for constraints | ||
179 | */ | ||
180 | if (cpu_is_omap34xx()) | ||
181 | pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat; | ||
161 | pdev = omap_device_build(name, bus_id, oh, pdata, | 182 | pdev = omap_device_build(name, bus_id, oh, pdata, |
162 | sizeof(struct omap_i2c_bus_platform_data), | 183 | sizeof(struct omap_i2c_bus_platform_data), |
163 | NULL, 0, 0); | 184 | NULL, 0, 0); |
diff --git a/arch/m68k/include/asm/signal.h b/arch/m68k/include/asm/signal.h index 67e489d8d1bd..2df26b57c26a 100644 --- a/arch/m68k/include/asm/signal.h +++ b/arch/m68k/include/asm/signal.h | |||
@@ -41,7 +41,7 @@ struct k_sigaction { | |||
41 | static inline void sigaddset(sigset_t *set, int _sig) | 41 | static inline void sigaddset(sigset_t *set, int _sig) |
42 | { | 42 | { |
43 | asm ("bfset %0{%1,#1}" | 43 | asm ("bfset %0{%1,#1}" |
44 | : "+od" (*set) | 44 | : "+o" (*set) |
45 | : "id" ((_sig - 1) ^ 31) | 45 | : "id" ((_sig - 1) ^ 31) |
46 | : "cc"); | 46 | : "cc"); |
47 | } | 47 | } |
@@ -49,7 +49,7 @@ static inline void sigaddset(sigset_t *set, int _sig) | |||
49 | static inline void sigdelset(sigset_t *set, int _sig) | 49 | static inline void sigdelset(sigset_t *set, int _sig) |
50 | { | 50 | { |
51 | asm ("bfclr %0{%1,#1}" | 51 | asm ("bfclr %0{%1,#1}" |
52 | : "+od" (*set) | 52 | : "+o" (*set) |
53 | : "id" ((_sig - 1) ^ 31) | 53 | : "id" ((_sig - 1) ^ 31) |
54 | : "cc"); | 54 | : "cc"); |
55 | } | 55 | } |
@@ -65,7 +65,7 @@ static inline int __gen_sigismember(sigset_t *set, int _sig) | |||
65 | int ret; | 65 | int ret; |
66 | asm ("bfextu %1{%2,#1},%0" | 66 | asm ("bfextu %1{%2,#1},%0" |
67 | : "=d" (ret) | 67 | : "=d" (ret) |
68 | : "od" (*set), "id" ((_sig-1) ^ 31) | 68 | : "o" (*set), "id" ((_sig-1) ^ 31) |
69 | : "cc"); | 69 | : "cc"); |
70 | return ret; | 70 | return ret; |
71 | } | 71 | } |
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index a53f8ec37aac..290dc6a1d7a3 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c | |||
@@ -79,7 +79,7 @@ static struct resource data_resource = { .name = "Kernel data", }; | |||
79 | void __init add_memory_region(phys_t start, phys_t size, long type) | 79 | void __init add_memory_region(phys_t start, phys_t size, long type) |
80 | { | 80 | { |
81 | int x = boot_mem_map.nr_map; | 81 | int x = boot_mem_map.nr_map; |
82 | struct boot_mem_map_entry *prev = boot_mem_map.map + x - 1; | 82 | int i; |
83 | 83 | ||
84 | /* Sanity check */ | 84 | /* Sanity check */ |
85 | if (start + size < start) { | 85 | if (start + size < start) { |
@@ -88,15 +88,29 @@ void __init add_memory_region(phys_t start, phys_t size, long type) | |||
88 | } | 88 | } |
89 | 89 | ||
90 | /* | 90 | /* |
91 | * Try to merge with previous entry if any. This is far less than | 91 | * Try to merge with existing entry, if any. |
92 | * perfect but is sufficient for most real world cases. | ||
93 | */ | 92 | */ |
94 | if (x && prev->addr + prev->size == start && prev->type == type) { | 93 | for (i = 0; i < boot_mem_map.nr_map; i++) { |
95 | prev->size += size; | 94 | struct boot_mem_map_entry *entry = boot_mem_map.map + i; |
95 | unsigned long top; | ||
96 | |||
97 | if (entry->type != type) | ||
98 | continue; | ||
99 | |||
100 | if (start + size < entry->addr) | ||
101 | continue; /* no overlap */ | ||
102 | |||
103 | if (entry->addr + entry->size < start) | ||
104 | continue; /* no overlap */ | ||
105 | |||
106 | top = max(entry->addr + entry->size, start + size); | ||
107 | entry->addr = min(entry->addr, start); | ||
108 | entry->size = top - entry->addr; | ||
109 | |||
96 | return; | 110 | return; |
97 | } | 111 | } |
98 | 112 | ||
99 | if (x == BOOT_MEM_MAP_MAX) { | 113 | if (boot_mem_map.nr_map == BOOT_MEM_MAP_MAX) { |
100 | pr_err("Ooops! Too many entries in the memory map!\n"); | 114 | pr_err("Ooops! Too many entries in the memory map!\n"); |
101 | return; | 115 | return; |
102 | } | 116 | } |
diff --git a/arch/mips/lib/mips-atomic.c b/arch/mips/lib/mips-atomic.c index e091430dbeb1..cd160be3ce4d 100644 --- a/arch/mips/lib/mips-atomic.c +++ b/arch/mips/lib/mips-atomic.c | |||
@@ -56,7 +56,7 @@ __asm__( | |||
56 | " .set pop \n" | 56 | " .set pop \n" |
57 | " .endm \n"); | 57 | " .endm \n"); |
58 | 58 | ||
59 | void arch_local_irq_disable(void) | 59 | notrace void arch_local_irq_disable(void) |
60 | { | 60 | { |
61 | preempt_disable(); | 61 | preempt_disable(); |
62 | __asm__ __volatile__( | 62 | __asm__ __volatile__( |
@@ -93,7 +93,7 @@ __asm__( | |||
93 | " .set pop \n" | 93 | " .set pop \n" |
94 | " .endm \n"); | 94 | " .endm \n"); |
95 | 95 | ||
96 | unsigned long arch_local_irq_save(void) | 96 | notrace unsigned long arch_local_irq_save(void) |
97 | { | 97 | { |
98 | unsigned long flags; | 98 | unsigned long flags; |
99 | preempt_disable(); | 99 | preempt_disable(); |
@@ -135,7 +135,7 @@ __asm__( | |||
135 | " .set pop \n" | 135 | " .set pop \n" |
136 | " .endm \n"); | 136 | " .endm \n"); |
137 | 137 | ||
138 | void arch_local_irq_restore(unsigned long flags) | 138 | notrace void arch_local_irq_restore(unsigned long flags) |
139 | { | 139 | { |
140 | unsigned long __tmp1; | 140 | unsigned long __tmp1; |
141 | 141 | ||
@@ -159,7 +159,7 @@ void arch_local_irq_restore(unsigned long flags) | |||
159 | EXPORT_SYMBOL(arch_local_irq_restore); | 159 | EXPORT_SYMBOL(arch_local_irq_restore); |
160 | 160 | ||
161 | 161 | ||
162 | void __arch_local_irq_restore(unsigned long flags) | 162 | notrace void __arch_local_irq_restore(unsigned long flags) |
163 | { | 163 | { |
164 | unsigned long __tmp1; | 164 | unsigned long __tmp1; |
165 | 165 | ||
diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c index fd49aeda9eb8..5dede04f2f3e 100644 --- a/arch/parisc/kernel/signal32.c +++ b/arch/parisc/kernel/signal32.c | |||
@@ -65,7 +65,8 @@ put_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz) | |||
65 | { | 65 | { |
66 | compat_sigset_t s; | 66 | compat_sigset_t s; |
67 | 67 | ||
68 | if (sz != sizeof *set) panic("put_sigset32()"); | 68 | if (sz != sizeof *set) |
69 | return -EINVAL; | ||
69 | sigset_64to32(&s, set); | 70 | sigset_64to32(&s, set); |
70 | 71 | ||
71 | return copy_to_user(up, &s, sizeof s); | 72 | return copy_to_user(up, &s, sizeof s); |
@@ -77,7 +78,8 @@ get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz) | |||
77 | compat_sigset_t s; | 78 | compat_sigset_t s; |
78 | int r; | 79 | int r; |
79 | 80 | ||
80 | if (sz != sizeof *set) panic("put_sigset32()"); | 81 | if (sz != sizeof *set) |
82 | return -EINVAL; | ||
81 | 83 | ||
82 | if ((r = copy_from_user(&s, up, sz)) == 0) { | 84 | if ((r = copy_from_user(&s, up, sz)) == 0) { |
83 | sigset_32to64(set, &s); | 85 | sigset_32to64(set, &s); |
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 7426e40699bd..f76c10863c62 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c | |||
@@ -73,6 +73,8 @@ static unsigned long get_shared_area(struct address_space *mapping, | |||
73 | struct vm_area_struct *vma; | 73 | struct vm_area_struct *vma; |
74 | int offset = mapping ? get_offset(mapping) : 0; | 74 | int offset = mapping ? get_offset(mapping) : 0; |
75 | 75 | ||
76 | offset = (offset + (pgoff << PAGE_SHIFT)) & 0x3FF000; | ||
77 | |||
76 | addr = DCACHE_ALIGN(addr - offset) + offset; | 78 | addr = DCACHE_ALIGN(addr - offset) + offset; |
77 | 79 | ||
78 | for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) { | 80 | for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) { |
diff --git a/arch/powerpc/boot/dts/mpc5200b.dtsi b/arch/powerpc/boot/dts/mpc5200b.dtsi index 7ab286ab5300..39ed65a44c5f 100644 --- a/arch/powerpc/boot/dts/mpc5200b.dtsi +++ b/arch/powerpc/boot/dts/mpc5200b.dtsi | |||
@@ -231,6 +231,12 @@ | |||
231 | interrupts = <2 7 0>; | 231 | interrupts = <2 7 0>; |
232 | }; | 232 | }; |
233 | 233 | ||
234 | sclpc@3c00 { | ||
235 | compatible = "fsl,mpc5200-lpbfifo"; | ||
236 | reg = <0x3c00 0x60>; | ||
237 | interrupts = <2 23 0>; | ||
238 | }; | ||
239 | |||
234 | i2c@3d00 { | 240 | i2c@3d00 { |
235 | #address-cells = <1>; | 241 | #address-cells = <1>; |
236 | #size-cells = <0>; | 242 | #size-cells = <0>; |
diff --git a/arch/powerpc/boot/dts/o2d.dtsi b/arch/powerpc/boot/dts/o2d.dtsi index 3444eb8f0ade..24f668039295 100644 --- a/arch/powerpc/boot/dts/o2d.dtsi +++ b/arch/powerpc/boot/dts/o2d.dtsi | |||
@@ -86,12 +86,6 @@ | |||
86 | reg = <0>; | 86 | reg = <0>; |
87 | }; | 87 | }; |
88 | }; | 88 | }; |
89 | |||
90 | sclpc@3c00 { | ||
91 | compatible = "fsl,mpc5200-lpbfifo"; | ||
92 | reg = <0x3c00 0x60>; | ||
93 | interrupts = <3 23 0>; | ||
94 | }; | ||
95 | }; | 89 | }; |
96 | 90 | ||
97 | localbus { | 91 | localbus { |
diff --git a/arch/powerpc/boot/dts/pcm030.dts b/arch/powerpc/boot/dts/pcm030.dts index 9e354997eb7e..96512c058033 100644 --- a/arch/powerpc/boot/dts/pcm030.dts +++ b/arch/powerpc/boot/dts/pcm030.dts | |||
@@ -59,7 +59,7 @@ | |||
59 | #gpio-cells = <2>; | 59 | #gpio-cells = <2>; |
60 | }; | 60 | }; |
61 | 61 | ||
62 | psc@2000 { /* PSC1 in ac97 mode */ | 62 | audioplatform: psc@2000 { /* PSC1 in ac97 mode */ |
63 | compatible = "mpc5200b-psc-ac97","fsl,mpc5200b-psc-ac97"; | 63 | compatible = "mpc5200b-psc-ac97","fsl,mpc5200b-psc-ac97"; |
64 | cell-index = <0>; | 64 | cell-index = <0>; |
65 | }; | 65 | }; |
@@ -134,4 +134,9 @@ | |||
134 | localbus { | 134 | localbus { |
135 | status = "disabled"; | 135 | status = "disabled"; |
136 | }; | 136 | }; |
137 | |||
138 | sound { | ||
139 | compatible = "phytec,pcm030-audio-fabric"; | ||
140 | asoc-platform = <&audioplatform>; | ||
141 | }; | ||
137 | }; | 142 | }; |
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c index 8520b58a5e9a..b89ef65392dc 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c | |||
@@ -372,10 +372,11 @@ static int mpc52xx_irqhost_map(struct irq_domain *h, unsigned int virq, | |||
372 | case MPC52xx_IRQ_L1_MAIN: irqchip = &mpc52xx_main_irqchip; break; | 372 | case MPC52xx_IRQ_L1_MAIN: irqchip = &mpc52xx_main_irqchip; break; |
373 | case MPC52xx_IRQ_L1_PERP: irqchip = &mpc52xx_periph_irqchip; break; | 373 | case MPC52xx_IRQ_L1_PERP: irqchip = &mpc52xx_periph_irqchip; break; |
374 | case MPC52xx_IRQ_L1_SDMA: irqchip = &mpc52xx_sdma_irqchip; break; | 374 | case MPC52xx_IRQ_L1_SDMA: irqchip = &mpc52xx_sdma_irqchip; break; |
375 | default: | 375 | case MPC52xx_IRQ_L1_CRIT: |
376 | pr_err("%s: invalid irq: virq=%i, l1=%i, l2=%i\n", | 376 | pr_warn("%s: Critical IRQ #%d is unsupported! Nopping it.\n", |
377 | __func__, virq, l1irq, l2irq); | 377 | __func__, l2irq); |
378 | return -EINVAL; | 378 | irq_set_chip(virq, &no_irq_chip); |
379 | return 0; | ||
379 | } | 380 | } |
380 | 381 | ||
381 | irq_set_chip_and_handler(virq, irqchip, handle_level_irq); | 382 | irq_set_chip_and_handler(virq, irqchip, handle_level_irq); |
diff --git a/arch/powerpc/platforms/pseries/eeh_pe.c b/arch/powerpc/platforms/pseries/eeh_pe.c index 797cd181dc3f..d16c8ded1084 100644 --- a/arch/powerpc/platforms/pseries/eeh_pe.c +++ b/arch/powerpc/platforms/pseries/eeh_pe.c | |||
@@ -449,7 +449,7 @@ int eeh_rmv_from_parent_pe(struct eeh_dev *edev, int purge_pe) | |||
449 | if (list_empty(&pe->edevs)) { | 449 | if (list_empty(&pe->edevs)) { |
450 | cnt = 0; | 450 | cnt = 0; |
451 | list_for_each_entry(child, &pe->child_list, child) { | 451 | list_for_each_entry(child, &pe->child_list, child) { |
452 | if (!(pe->type & EEH_PE_INVALID)) { | 452 | if (!(child->type & EEH_PE_INVALID)) { |
453 | cnt++; | 453 | cnt++; |
454 | break; | 454 | break; |
455 | } | 455 | } |
diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index d19f4977c834..e5b084723131 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c | |||
@@ -220,7 +220,8 @@ static struct device_node *find_pe_dn(struct pci_dev *dev, int *total) | |||
220 | 220 | ||
221 | /* Get the top level device in the PE */ | 221 | /* Get the top level device in the PE */ |
222 | edev = of_node_to_eeh_dev(dn); | 222 | edev = of_node_to_eeh_dev(dn); |
223 | edev = list_first_entry(&edev->pe->edevs, struct eeh_dev, list); | 223 | if (edev->pe) |
224 | edev = list_first_entry(&edev->pe->edevs, struct eeh_dev, list); | ||
224 | dn = eeh_dev_to_of_node(edev); | 225 | dn = eeh_dev_to_of_node(edev); |
225 | if (!dn) | 226 | if (!dn) |
226 | return NULL; | 227 | return NULL; |
diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h index f93003123bce..67c62578d170 100644 --- a/arch/sparc/include/asm/prom.h +++ b/arch/sparc/include/asm/prom.h | |||
@@ -63,10 +63,13 @@ extern char *of_console_options; | |||
63 | extern void irq_trans_init(struct device_node *dp); | 63 | extern void irq_trans_init(struct device_node *dp); |
64 | extern char *build_path_component(struct device_node *dp); | 64 | extern char *build_path_component(struct device_node *dp); |
65 | 65 | ||
66 | /* SPARC has a local implementation */ | 66 | /* SPARC has local implementations */ |
67 | extern int of_address_to_resource(struct device_node *dev, int index, | 67 | extern int of_address_to_resource(struct device_node *dev, int index, |
68 | struct resource *r); | 68 | struct resource *r); |
69 | #define of_address_to_resource of_address_to_resource | 69 | #define of_address_to_resource of_address_to_resource |
70 | 70 | ||
71 | void __iomem *of_iomap(struct device_node *node, int index); | ||
72 | #define of_iomap of_iomap | ||
73 | |||
71 | #endif /* __KERNEL__ */ | 74 | #endif /* __KERNEL__ */ |
72 | #endif /* _SPARC_PROM_H */ | 75 | #endif /* _SPARC_PROM_H */ |
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index 867de2f8189c..689e1ba62809 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c | |||
@@ -295,9 +295,7 @@ void do_rt_sigreturn(struct pt_regs *regs) | |||
295 | err |= restore_fpu_state(regs, fpu_save); | 295 | err |= restore_fpu_state(regs, fpu_save); |
296 | 296 | ||
297 | err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); | 297 | err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); |
298 | err |= do_sigaltstack(&sf->stack, NULL, (unsigned long)sf); | 298 | if (err || do_sigaltstack(&sf->stack, NULL, (unsigned long)sf) == -EFAULT) |
299 | |||
300 | if (err) | ||
301 | goto segv; | 299 | goto segv; |
302 | 300 | ||
303 | err |= __get_user(rwin_save, &sf->rwin_save); | 301 | err |= __get_user(rwin_save, &sf->rwin_save); |
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index c760e073963e..e87b0cac14b5 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c | |||
@@ -12,6 +12,8 @@ | |||
12 | #include <asm/setup.h> | 12 | #include <asm/setup.h> |
13 | #include <asm/desc.h> | 13 | #include <asm/desc.h> |
14 | 14 | ||
15 | #undef memcpy /* Use memcpy from misc.c */ | ||
16 | |||
15 | #include "eboot.h" | 17 | #include "eboot.h" |
16 | 18 | ||
17 | static efi_system_table_t *sys_table; | 19 | static efi_system_table_t *sys_table; |
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S index 2a017441b8b2..8c132a625b94 100644 --- a/arch/x86/boot/header.S +++ b/arch/x86/boot/header.S | |||
@@ -476,6 +476,3 @@ die: | |||
476 | setup_corrupt: | 476 | setup_corrupt: |
477 | .byte 7 | 477 | .byte 7 |
478 | .string "No setup signature found...\n" | 478 | .string "No setup signature found...\n" |
479 | |||
480 | .data | ||
481 | dummy: .long 0 | ||
diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index dcfde52979c3..19f16ebaf4fa 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h | |||
@@ -205,21 +205,14 @@ static inline bool user_64bit_mode(struct pt_regs *regs) | |||
205 | } | 205 | } |
206 | #endif | 206 | #endif |
207 | 207 | ||
208 | /* | ||
209 | * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode | ||
210 | * when it traps. The previous stack will be directly underneath the saved | ||
211 | * registers, and 'sp/ss' won't even have been saved. Thus the '®s->sp'. | ||
212 | * | ||
213 | * This is valid only for kernel mode traps. | ||
214 | */ | ||
215 | static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) | ||
216 | { | ||
217 | #ifdef CONFIG_X86_32 | 208 | #ifdef CONFIG_X86_32 |
218 | return (unsigned long)(®s->sp); | 209 | extern unsigned long kernel_stack_pointer(struct pt_regs *regs); |
219 | #else | 210 | #else |
211 | static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) | ||
212 | { | ||
220 | return regs->sp; | 213 | return regs->sp; |
221 | #endif | ||
222 | } | 214 | } |
215 | #endif | ||
223 | 216 | ||
224 | #define GET_IP(regs) ((regs)->ip) | 217 | #define GET_IP(regs) ((regs)->ip) |
225 | #define GET_FP(regs) ((regs)->bp) | 218 | #define GET_FP(regs) ((regs)->bp) |
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index f7e98a2c0d12..1b7d1656a042 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c | |||
@@ -631,6 +631,20 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) | |||
631 | } | 631 | } |
632 | } | 632 | } |
633 | 633 | ||
634 | /* | ||
635 | * The way access filter has a performance penalty on some workloads. | ||
636 | * Disable it on the affected CPUs. | ||
637 | */ | ||
638 | if ((c->x86 == 0x15) && | ||
639 | (c->x86_model >= 0x02) && (c->x86_model < 0x20)) { | ||
640 | u64 val; | ||
641 | |||
642 | if (!rdmsrl_safe(0xc0011021, &val) && !(val & 0x1E)) { | ||
643 | val |= 0x1E; | ||
644 | wrmsrl_safe(0xc0011021, val); | ||
645 | } | ||
646 | } | ||
647 | |||
634 | cpu_detect_cache_sizes(c); | 648 | cpu_detect_cache_sizes(c); |
635 | 649 | ||
636 | /* Multi core CPU? */ | 650 | /* Multi core CPU? */ |
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index 698b6ec12e0f..1ac581f38dfa 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * | 6 | * |
7 | * Written by Jacob Shin - AMD, Inc. | 7 | * Written by Jacob Shin - AMD, Inc. |
8 | * | 8 | * |
9 | * Support: borislav.petkov@amd.com | 9 | * Maintained by: Borislav Petkov <bp@alien8.de> |
10 | * | 10 | * |
11 | * April 2006 | 11 | * April 2006 |
12 | * - added support for AMD Family 0x10 processors | 12 | * - added support for AMD Family 0x10 processors |
diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel.c b/arch/x86/kernel/cpu/mcheck/mce_intel.c index 5f88abf07e9c..4f9a3cbfc4a3 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_intel.c +++ b/arch/x86/kernel/cpu/mcheck/mce_intel.c | |||
@@ -285,34 +285,39 @@ void cmci_clear(void) | |||
285 | raw_spin_unlock_irqrestore(&cmci_discover_lock, flags); | 285 | raw_spin_unlock_irqrestore(&cmci_discover_lock, flags); |
286 | } | 286 | } |
287 | 287 | ||
288 | static long cmci_rediscover_work_func(void *arg) | ||
289 | { | ||
290 | int banks; | ||
291 | |||
292 | /* Recheck banks in case CPUs don't all have the same */ | ||
293 | if (cmci_supported(&banks)) | ||
294 | cmci_discover(banks); | ||
295 | |||
296 | return 0; | ||
297 | } | ||
298 | |||
288 | /* | 299 | /* |
289 | * After a CPU went down cycle through all the others and rediscover | 300 | * After a CPU went down cycle through all the others and rediscover |
290 | * Must run in process context. | 301 | * Must run in process context. |
291 | */ | 302 | */ |
292 | void cmci_rediscover(int dying) | 303 | void cmci_rediscover(int dying) |
293 | { | 304 | { |
294 | int banks; | 305 | int cpu, banks; |
295 | int cpu; | ||
296 | cpumask_var_t old; | ||
297 | 306 | ||
298 | if (!cmci_supported(&banks)) | 307 | if (!cmci_supported(&banks)) |
299 | return; | 308 | return; |
300 | if (!alloc_cpumask_var(&old, GFP_KERNEL)) | ||
301 | return; | ||
302 | cpumask_copy(old, ¤t->cpus_allowed); | ||
303 | 309 | ||
304 | for_each_online_cpu(cpu) { | 310 | for_each_online_cpu(cpu) { |
305 | if (cpu == dying) | 311 | if (cpu == dying) |
306 | continue; | 312 | continue; |
307 | if (set_cpus_allowed_ptr(current, cpumask_of(cpu))) | 313 | |
314 | if (cpu == smp_processor_id()) { | ||
315 | cmci_rediscover_work_func(NULL); | ||
308 | continue; | 316 | continue; |
309 | /* Recheck banks in case CPUs don't all have the same */ | 317 | } |
310 | if (cmci_supported(&banks)) | ||
311 | cmci_discover(banks); | ||
312 | } | ||
313 | 318 | ||
314 | set_cpus_allowed_ptr(current, old); | 319 | work_on_cpu(cpu, cmci_rediscover_work_func, NULL); |
315 | free_cpumask_var(old); | 320 | } |
316 | } | 321 | } |
317 | 322 | ||
318 | /* | 323 | /* |
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index b51b2c7ee51f..1328fe49a3f1 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
@@ -995,8 +995,8 @@ END(interrupt) | |||
995 | */ | 995 | */ |
996 | .p2align CONFIG_X86_L1_CACHE_SHIFT | 996 | .p2align CONFIG_X86_L1_CACHE_SHIFT |
997 | common_interrupt: | 997 | common_interrupt: |
998 | ASM_CLAC | ||
999 | XCPT_FRAME | 998 | XCPT_FRAME |
999 | ASM_CLAC | ||
1000 | addq $-0x80,(%rsp) /* Adjust vector to [-256,-1] range */ | 1000 | addq $-0x80,(%rsp) /* Adjust vector to [-256,-1] range */ |
1001 | interrupt do_IRQ | 1001 | interrupt do_IRQ |
1002 | /* 0(%rsp): old_rsp-ARGOFFSET */ | 1002 | /* 0(%rsp): old_rsp-ARGOFFSET */ |
@@ -1135,8 +1135,8 @@ END(common_interrupt) | |||
1135 | */ | 1135 | */ |
1136 | .macro apicinterrupt num sym do_sym | 1136 | .macro apicinterrupt num sym do_sym |
1137 | ENTRY(\sym) | 1137 | ENTRY(\sym) |
1138 | ASM_CLAC | ||
1139 | INTR_FRAME | 1138 | INTR_FRAME |
1139 | ASM_CLAC | ||
1140 | pushq_cfi $~(\num) | 1140 | pushq_cfi $~(\num) |
1141 | .Lcommon_\sym: | 1141 | .Lcommon_\sym: |
1142 | interrupt \do_sym | 1142 | interrupt \do_sym |
@@ -1190,8 +1190,8 @@ apicinterrupt IRQ_WORK_VECTOR \ | |||
1190 | */ | 1190 | */ |
1191 | .macro zeroentry sym do_sym | 1191 | .macro zeroentry sym do_sym |
1192 | ENTRY(\sym) | 1192 | ENTRY(\sym) |
1193 | ASM_CLAC | ||
1194 | INTR_FRAME | 1193 | INTR_FRAME |
1194 | ASM_CLAC | ||
1195 | PARAVIRT_ADJUST_EXCEPTION_FRAME | 1195 | PARAVIRT_ADJUST_EXCEPTION_FRAME |
1196 | pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */ | 1196 | pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */ |
1197 | subq $ORIG_RAX-R15, %rsp | 1197 | subq $ORIG_RAX-R15, %rsp |
@@ -1208,8 +1208,8 @@ END(\sym) | |||
1208 | 1208 | ||
1209 | .macro paranoidzeroentry sym do_sym | 1209 | .macro paranoidzeroentry sym do_sym |
1210 | ENTRY(\sym) | 1210 | ENTRY(\sym) |
1211 | ASM_CLAC | ||
1212 | INTR_FRAME | 1211 | INTR_FRAME |
1212 | ASM_CLAC | ||
1213 | PARAVIRT_ADJUST_EXCEPTION_FRAME | 1213 | PARAVIRT_ADJUST_EXCEPTION_FRAME |
1214 | pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */ | 1214 | pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */ |
1215 | subq $ORIG_RAX-R15, %rsp | 1215 | subq $ORIG_RAX-R15, %rsp |
@@ -1227,8 +1227,8 @@ END(\sym) | |||
1227 | #define INIT_TSS_IST(x) PER_CPU_VAR(init_tss) + (TSS_ist + ((x) - 1) * 8) | 1227 | #define INIT_TSS_IST(x) PER_CPU_VAR(init_tss) + (TSS_ist + ((x) - 1) * 8) |
1228 | .macro paranoidzeroentry_ist sym do_sym ist | 1228 | .macro paranoidzeroentry_ist sym do_sym ist |
1229 | ENTRY(\sym) | 1229 | ENTRY(\sym) |
1230 | ASM_CLAC | ||
1231 | INTR_FRAME | 1230 | INTR_FRAME |
1231 | ASM_CLAC | ||
1232 | PARAVIRT_ADJUST_EXCEPTION_FRAME | 1232 | PARAVIRT_ADJUST_EXCEPTION_FRAME |
1233 | pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */ | 1233 | pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */ |
1234 | subq $ORIG_RAX-R15, %rsp | 1234 | subq $ORIG_RAX-R15, %rsp |
@@ -1247,8 +1247,8 @@ END(\sym) | |||
1247 | 1247 | ||
1248 | .macro errorentry sym do_sym | 1248 | .macro errorentry sym do_sym |
1249 | ENTRY(\sym) | 1249 | ENTRY(\sym) |
1250 | ASM_CLAC | ||
1251 | XCPT_FRAME | 1250 | XCPT_FRAME |
1251 | ASM_CLAC | ||
1252 | PARAVIRT_ADJUST_EXCEPTION_FRAME | 1252 | PARAVIRT_ADJUST_EXCEPTION_FRAME |
1253 | subq $ORIG_RAX-R15, %rsp | 1253 | subq $ORIG_RAX-R15, %rsp |
1254 | CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15 | 1254 | CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15 |
@@ -1266,8 +1266,8 @@ END(\sym) | |||
1266 | /* error code is on the stack already */ | 1266 | /* error code is on the stack already */ |
1267 | .macro paranoiderrorentry sym do_sym | 1267 | .macro paranoiderrorentry sym do_sym |
1268 | ENTRY(\sym) | 1268 | ENTRY(\sym) |
1269 | ASM_CLAC | ||
1270 | XCPT_FRAME | 1269 | XCPT_FRAME |
1270 | ASM_CLAC | ||
1271 | PARAVIRT_ADJUST_EXCEPTION_FRAME | 1271 | PARAVIRT_ADJUST_EXCEPTION_FRAME |
1272 | subq $ORIG_RAX-R15, %rsp | 1272 | subq $ORIG_RAX-R15, %rsp |
1273 | CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15 | 1273 | CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15 |
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c index 7720ff5a9ee2..efdec7cd8e01 100644 --- a/arch/x86/kernel/microcode_amd.c +++ b/arch/x86/kernel/microcode_amd.c | |||
@@ -8,8 +8,8 @@ | |||
8 | * Tigran Aivazian <tigran@aivazian.fsnet.co.uk> | 8 | * Tigran Aivazian <tigran@aivazian.fsnet.co.uk> |
9 | * | 9 | * |
10 | * Maintainers: | 10 | * Maintainers: |
11 | * Andreas Herrmann <andreas.herrmann3@amd.com> | 11 | * Andreas Herrmann <herrmann.der.user@googlemail.com> |
12 | * Borislav Petkov <borislav.petkov@amd.com> | 12 | * Borislav Petkov <bp@alien8.de> |
13 | * | 13 | * |
14 | * This driver allows to upgrade microcode on F10h AMD | 14 | * This driver allows to upgrade microcode on F10h AMD |
15 | * CPUs and later. | 15 | * CPUs and later. |
@@ -190,6 +190,7 @@ static unsigned int verify_patch_size(int cpu, u32 patch_size, | |||
190 | #define F1XH_MPB_MAX_SIZE 2048 | 190 | #define F1XH_MPB_MAX_SIZE 2048 |
191 | #define F14H_MPB_MAX_SIZE 1824 | 191 | #define F14H_MPB_MAX_SIZE 1824 |
192 | #define F15H_MPB_MAX_SIZE 4096 | 192 | #define F15H_MPB_MAX_SIZE 4096 |
193 | #define F16H_MPB_MAX_SIZE 3458 | ||
193 | 194 | ||
194 | switch (c->x86) { | 195 | switch (c->x86) { |
195 | case 0x14: | 196 | case 0x14: |
@@ -198,6 +199,9 @@ static unsigned int verify_patch_size(int cpu, u32 patch_size, | |||
198 | case 0x15: | 199 | case 0x15: |
199 | max_size = F15H_MPB_MAX_SIZE; | 200 | max_size = F15H_MPB_MAX_SIZE; |
200 | break; | 201 | break; |
202 | case 0x16: | ||
203 | max_size = F16H_MPB_MAX_SIZE; | ||
204 | break; | ||
201 | default: | 205 | default: |
202 | max_size = F1XH_MPB_MAX_SIZE; | 206 | max_size = F1XH_MPB_MAX_SIZE; |
203 | break; | 207 | break; |
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index b00b33a18390..5e0596b0632e 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/perf_event.h> | 22 | #include <linux/perf_event.h> |
23 | #include <linux/hw_breakpoint.h> | 23 | #include <linux/hw_breakpoint.h> |
24 | #include <linux/rcupdate.h> | 24 | #include <linux/rcupdate.h> |
25 | #include <linux/module.h> | ||
25 | 26 | ||
26 | #include <asm/uaccess.h> | 27 | #include <asm/uaccess.h> |
27 | #include <asm/pgtable.h> | 28 | #include <asm/pgtable.h> |
@@ -166,6 +167,35 @@ static inline bool invalid_selector(u16 value) | |||
166 | 167 | ||
167 | #define FLAG_MASK FLAG_MASK_32 | 168 | #define FLAG_MASK FLAG_MASK_32 |
168 | 169 | ||
170 | /* | ||
171 | * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode | ||
172 | * when it traps. The previous stack will be directly underneath the saved | ||
173 | * registers, and 'sp/ss' won't even have been saved. Thus the '®s->sp'. | ||
174 | * | ||
175 | * Now, if the stack is empty, '®s->sp' is out of range. In this | ||
176 | * case we try to take the previous stack. To always return a non-null | ||
177 | * stack pointer we fall back to regs as stack if no previous stack | ||
178 | * exists. | ||
179 | * | ||
180 | * This is valid only for kernel mode traps. | ||
181 | */ | ||
182 | unsigned long kernel_stack_pointer(struct pt_regs *regs) | ||
183 | { | ||
184 | unsigned long context = (unsigned long)regs & ~(THREAD_SIZE - 1); | ||
185 | unsigned long sp = (unsigned long)®s->sp; | ||
186 | struct thread_info *tinfo; | ||
187 | |||
188 | if (context == (sp & ~(THREAD_SIZE - 1))) | ||
189 | return sp; | ||
190 | |||
191 | tinfo = (struct thread_info *)context; | ||
192 | if (tinfo->previous_esp) | ||
193 | return tinfo->previous_esp; | ||
194 | |||
195 | return (unsigned long)regs; | ||
196 | } | ||
197 | EXPORT_SYMBOL_GPL(kernel_stack_pointer); | ||
198 | |||
169 | static unsigned long *pt_regs_access(struct pt_regs *regs, unsigned long regno) | 199 | static unsigned long *pt_regs_access(struct pt_regs *regs, unsigned long regno) |
170 | { | 200 | { |
171 | BUILD_BUG_ON(offsetof(struct pt_regs, bx) != 0); | 201 | BUILD_BUG_ON(offsetof(struct pt_regs, bx) != 0); |
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 0777f042e400..60f926cd8b0e 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c | |||
@@ -197,7 +197,7 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start, | |||
197 | } | 197 | } |
198 | 198 | ||
199 | if (end == TLB_FLUSH_ALL || tlb_flushall_shift == -1 | 199 | if (end == TLB_FLUSH_ALL || tlb_flushall_shift == -1 |
200 | || vmflag == VM_HUGETLB) { | 200 | || vmflag & VM_HUGETLB) { |
201 | local_flush_tlb(); | 201 | local_flush_tlb(); |
202 | goto flush_all; | 202 | goto flush_all; |
203 | } | 203 | } |
diff --git a/arch/x86/pci/ce4100.c b/arch/x86/pci/ce4100.c index 41bd2a2d2c50..b914e20b5a00 100644 --- a/arch/x86/pci/ce4100.c +++ b/arch/x86/pci/ce4100.c | |||
@@ -115,6 +115,16 @@ static void sata_revid_read(struct sim_dev_reg *reg, u32 *value) | |||
115 | reg_read(reg, value); | 115 | reg_read(reg, value); |
116 | } | 116 | } |
117 | 117 | ||
118 | static void reg_noirq_read(struct sim_dev_reg *reg, u32 *value) | ||
119 | { | ||
120 | unsigned long flags; | ||
121 | |||
122 | raw_spin_lock_irqsave(&pci_config_lock, flags); | ||
123 | /* force interrupt pin value to 0 */ | ||
124 | *value = reg->sim_reg.value & 0xfff00ff; | ||
125 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); | ||
126 | } | ||
127 | |||
118 | static struct sim_dev_reg bus1_fixups[] = { | 128 | static struct sim_dev_reg bus1_fixups[] = { |
119 | DEFINE_REG(2, 0, 0x10, (16*MB), reg_init, reg_read, reg_write) | 129 | DEFINE_REG(2, 0, 0x10, (16*MB), reg_init, reg_read, reg_write) |
120 | DEFINE_REG(2, 0, 0x14, (256), reg_init, reg_read, reg_write) | 130 | DEFINE_REG(2, 0, 0x14, (256), reg_init, reg_read, reg_write) |
@@ -144,6 +154,7 @@ static struct sim_dev_reg bus1_fixups[] = { | |||
144 | DEFINE_REG(11, 5, 0x10, (64*KB), reg_init, reg_read, reg_write) | 154 | DEFINE_REG(11, 5, 0x10, (64*KB), reg_init, reg_read, reg_write) |
145 | DEFINE_REG(11, 6, 0x10, (256), reg_init, reg_read, reg_write) | 155 | DEFINE_REG(11, 6, 0x10, (256), reg_init, reg_read, reg_write) |
146 | DEFINE_REG(11, 7, 0x10, (64*KB), reg_init, reg_read, reg_write) | 156 | DEFINE_REG(11, 7, 0x10, (64*KB), reg_init, reg_read, reg_write) |
157 | DEFINE_REG(11, 7, 0x3c, 256, reg_init, reg_noirq_read, reg_write) | ||
147 | DEFINE_REG(12, 0, 0x10, (128*KB), reg_init, reg_read, reg_write) | 158 | DEFINE_REG(12, 0, 0x10, (128*KB), reg_init, reg_read, reg_write) |
148 | DEFINE_REG(12, 0, 0x14, (256), reg_init, reg_read, reg_write) | 159 | DEFINE_REG(12, 0, 0x14, (256), reg_init, reg_read, reg_write) |
149 | DEFINE_REG(12, 1, 0x10, (1024), reg_init, reg_read, reg_write) | 160 | DEFINE_REG(12, 1, 0x10, (1024), reg_init, reg_read, reg_write) |
@@ -161,8 +172,10 @@ static struct sim_dev_reg bus1_fixups[] = { | |||
161 | DEFINE_REG(16, 0, 0x10, (64*KB), reg_init, reg_read, reg_write) | 172 | DEFINE_REG(16, 0, 0x10, (64*KB), reg_init, reg_read, reg_write) |
162 | DEFINE_REG(16, 0, 0x14, (64*MB), reg_init, reg_read, reg_write) | 173 | DEFINE_REG(16, 0, 0x14, (64*MB), reg_init, reg_read, reg_write) |
163 | DEFINE_REG(16, 0, 0x18, (64*MB), reg_init, reg_read, reg_write) | 174 | DEFINE_REG(16, 0, 0x18, (64*MB), reg_init, reg_read, reg_write) |
175 | DEFINE_REG(16, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write) | ||
164 | DEFINE_REG(17, 0, 0x10, (128*KB), reg_init, reg_read, reg_write) | 176 | DEFINE_REG(17, 0, 0x10, (128*KB), reg_init, reg_read, reg_write) |
165 | DEFINE_REG(18, 0, 0x10, (1*KB), reg_init, reg_read, reg_write) | 177 | DEFINE_REG(18, 0, 0x10, (1*KB), reg_init, reg_read, reg_write) |
178 | DEFINE_REG(18, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write) | ||
166 | }; | 179 | }; |
167 | 180 | ||
168 | static void __init init_sim_regs(void) | 181 | static void __init init_sim_regs(void) |
diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c index 4c61b52191eb..92525cb8e54c 100644 --- a/arch/x86/platform/ce4100/ce4100.c +++ b/arch/x86/platform/ce4100/ce4100.c | |||
@@ -21,12 +21,25 @@ | |||
21 | #include <asm/i8259.h> | 21 | #include <asm/i8259.h> |
22 | #include <asm/io.h> | 22 | #include <asm/io.h> |
23 | #include <asm/io_apic.h> | 23 | #include <asm/io_apic.h> |
24 | #include <asm/emergency-restart.h> | ||
24 | 25 | ||
25 | static int ce4100_i8042_detect(void) | 26 | static int ce4100_i8042_detect(void) |
26 | { | 27 | { |
27 | return 0; | 28 | return 0; |
28 | } | 29 | } |
29 | 30 | ||
31 | /* | ||
32 | * The CE4100 platform has an internal 8051 Microcontroller which is | ||
33 | * responsible for signaling to the external Power Management Unit the | ||
34 | * intention to reset, reboot or power off the system. This 8051 device has | ||
35 | * its command register mapped at I/O port 0xcf9 and the value 0x4 is used | ||
36 | * to power off the system. | ||
37 | */ | ||
38 | static void ce4100_power_off(void) | ||
39 | { | ||
40 | outb(0x4, 0xcf9); | ||
41 | } | ||
42 | |||
30 | #ifdef CONFIG_SERIAL_8250 | 43 | #ifdef CONFIG_SERIAL_8250 |
31 | 44 | ||
32 | static unsigned int mem_serial_in(struct uart_port *p, int offset) | 45 | static unsigned int mem_serial_in(struct uart_port *p, int offset) |
@@ -139,8 +152,19 @@ void __init x86_ce4100_early_setup(void) | |||
139 | x86_init.mpparse.find_smp_config = x86_init_noop; | 152 | x86_init.mpparse.find_smp_config = x86_init_noop; |
140 | x86_init.pci.init = ce4100_pci_init; | 153 | x86_init.pci.init = ce4100_pci_init; |
141 | 154 | ||
155 | /* | ||
156 | * By default, the reboot method is ACPI which is supported by the | ||
157 | * CE4100 bootloader CEFDK using FADT.ResetReg Address and ResetValue | ||
158 | * the bootloader will however issue a system power off instead of | ||
159 | * reboot. By using BOOT_KBD we ensure proper system reboot as | ||
160 | * expected. | ||
161 | */ | ||
162 | reboot_type = BOOT_KBD; | ||
163 | |||
142 | #ifdef CONFIG_X86_IO_APIC | 164 | #ifdef CONFIG_X86_IO_APIC |
143 | x86_init.pci.init_irq = sdv_pci_init; | 165 | x86_init.pci.init_irq = sdv_pci_init; |
144 | x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc_nocheck; | 166 | x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc_nocheck; |
145 | #endif | 167 | #endif |
168 | |||
169 | pm_power_off = ce4100_power_off; | ||
146 | } | 170 | } |
diff --git a/block/blk-exec.c b/block/blk-exec.c index 8b6dc5bd4dd0..f71eac35c1b9 100644 --- a/block/blk-exec.c +++ b/block/blk-exec.c | |||
@@ -52,11 +52,17 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk, | |||
52 | rq_end_io_fn *done) | 52 | rq_end_io_fn *done) |
53 | { | 53 | { |
54 | int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK; | 54 | int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK; |
55 | bool is_pm_resume; | ||
55 | 56 | ||
56 | WARN_ON(irqs_disabled()); | 57 | WARN_ON(irqs_disabled()); |
57 | 58 | ||
58 | rq->rq_disk = bd_disk; | 59 | rq->rq_disk = bd_disk; |
59 | rq->end_io = done; | 60 | rq->end_io = done; |
61 | /* | ||
62 | * need to check this before __blk_run_queue(), because rq can | ||
63 | * be freed before that returns. | ||
64 | */ | ||
65 | is_pm_resume = rq->cmd_type == REQ_TYPE_PM_RESUME; | ||
60 | 66 | ||
61 | spin_lock_irq(q->queue_lock); | 67 | spin_lock_irq(q->queue_lock); |
62 | 68 | ||
@@ -71,7 +77,7 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk, | |||
71 | __elv_add_request(q, rq, where); | 77 | __elv_add_request(q, rq, where); |
72 | __blk_run_queue(q); | 78 | __blk_run_queue(q); |
73 | /* the queue is stopped so it won't be run */ | 79 | /* the queue is stopped so it won't be run */ |
74 | if (rq->cmd_type == REQ_TYPE_PM_RESUME) | 80 | if (is_pm_resume) |
75 | q->request_fn(q); | 81 | q->request_fn(q); |
76 | spin_unlock_irq(q->queue_lock); | 82 | spin_unlock_irq(q->queue_lock); |
77 | } | 83 | } |
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index b1ae48054dc5..b7078afddb74 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c | |||
@@ -238,7 +238,7 @@ static int __devexit ahci_remove(struct platform_device *pdev) | |||
238 | return 0; | 238 | return 0; |
239 | } | 239 | } |
240 | 240 | ||
241 | #ifdef CONFIG_PM | 241 | #ifdef CONFIG_PM_SLEEP |
242 | static int ahci_suspend(struct device *dev) | 242 | static int ahci_suspend(struct device *dev) |
243 | { | 243 | { |
244 | struct ahci_platform_data *pdata = dev_get_platdata(dev); | 244 | struct ahci_platform_data *pdata = dev_get_platdata(dev); |
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index fd9ecf74e631..5b0ba3f20edc 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c | |||
@@ -1105,10 +1105,15 @@ static int ata_acpi_bind_device(struct ata_port *ap, struct scsi_device *sdev, | |||
1105 | struct acpi_device *acpi_dev; | 1105 | struct acpi_device *acpi_dev; |
1106 | struct acpi_device_power_state *states; | 1106 | struct acpi_device_power_state *states; |
1107 | 1107 | ||
1108 | if (ap->flags & ATA_FLAG_ACPI_SATA) | 1108 | if (ap->flags & ATA_FLAG_ACPI_SATA) { |
1109 | ata_dev = &ap->link.device[sdev->channel]; | 1109 | if (!sata_pmp_attached(ap)) |
1110 | else | 1110 | ata_dev = &ap->link.device[sdev->id]; |
1111 | else | ||
1112 | ata_dev = &ap->pmp_link[sdev->channel].device[sdev->id]; | ||
1113 | } | ||
1114 | else { | ||
1111 | ata_dev = &ap->link.device[sdev->id]; | 1115 | ata_dev = &ap->link.device[sdev->id]; |
1116 | } | ||
1112 | 1117 | ||
1113 | *handle = ata_dev_acpi_handle(ata_dev); | 1118 | *handle = ata_dev_acpi_handle(ata_dev); |
1114 | 1119 | ||
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 3cc7096cfda7..f46fbd3bd3fb 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -2942,6 +2942,10 @@ const struct ata_timing *ata_timing_find_mode(u8 xfer_mode) | |||
2942 | 2942 | ||
2943 | if (xfer_mode == t->mode) | 2943 | if (xfer_mode == t->mode) |
2944 | return t; | 2944 | return t; |
2945 | |||
2946 | WARN_ONCE(true, "%s: unable to find timing for xfer_mode 0x%x\n", | ||
2947 | __func__, xfer_mode); | ||
2948 | |||
2945 | return NULL; | 2949 | return NULL; |
2946 | } | 2950 | } |
2947 | 2951 | ||
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index e3bda074fa12..a6df6a351d6e 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -1052,6 +1052,8 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev) | |||
1052 | { | 1052 | { |
1053 | sdev->use_10_for_rw = 1; | 1053 | sdev->use_10_for_rw = 1; |
1054 | sdev->use_10_for_ms = 1; | 1054 | sdev->use_10_for_ms = 1; |
1055 | sdev->no_report_opcodes = 1; | ||
1056 | sdev->no_write_same = 1; | ||
1055 | 1057 | ||
1056 | /* Schedule policy is determined by ->qc_defer() callback and | 1058 | /* Schedule policy is determined by ->qc_defer() callback and |
1057 | * it needs to see every deferred qc. Set dev_blocked to 1 to | 1059 | * it needs to see every deferred qc. Set dev_blocked to 1 to |
diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index 26201ebef3ca..371fd2c698b7 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c | |||
@@ -317,6 +317,12 @@ static int cf_init(struct arasan_cf_dev *acdev) | |||
317 | return ret; | 317 | return ret; |
318 | } | 318 | } |
319 | 319 | ||
320 | ret = clk_set_rate(acdev->clk, 166000000); | ||
321 | if (ret) { | ||
322 | dev_warn(acdev->host->dev, "clock set rate failed"); | ||
323 | return ret; | ||
324 | } | ||
325 | |||
320 | spin_lock_irqsave(&acdev->host->lock, flags); | 326 | spin_lock_irqsave(&acdev->host->lock, flags); |
321 | /* configure CF interface clock */ | 327 | /* configure CF interface clock */ |
322 | writel((pdata->cf_if_clk <= CF_IF_CLK_200M) ? pdata->cf_if_clk : | 328 | writel((pdata->cf_if_clk <= CF_IF_CLK_200M) ? pdata->cf_if_clk : |
@@ -908,7 +914,7 @@ static int __devexit arasan_cf_remove(struct platform_device *pdev) | |||
908 | return 0; | 914 | return 0; |
909 | } | 915 | } |
910 | 916 | ||
911 | #ifdef CONFIG_PM | 917 | #ifdef CONFIG_PM_SLEEP |
912 | static int arasan_cf_suspend(struct device *dev) | 918 | static int arasan_cf_suspend(struct device *dev) |
913 | { | 919 | { |
914 | struct ata_host *host = dev_get_drvdata(dev); | 920 | struct ata_host *host = dev_get_drvdata(dev); |
diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c index 0d7c4c2cd26f..400bf1c3e982 100644 --- a/drivers/ata/sata_highbank.c +++ b/drivers/ata/sata_highbank.c | |||
@@ -260,7 +260,7 @@ static const struct of_device_id ahci_of_match[] = { | |||
260 | }; | 260 | }; |
261 | MODULE_DEVICE_TABLE(of, ahci_of_match); | 261 | MODULE_DEVICE_TABLE(of, ahci_of_match); |
262 | 262 | ||
263 | static int __init ahci_highbank_probe(struct platform_device *pdev) | 263 | static int __devinit ahci_highbank_probe(struct platform_device *pdev) |
264 | { | 264 | { |
265 | struct device *dev = &pdev->dev; | 265 | struct device *dev = &pdev->dev; |
266 | struct ahci_host_priv *hpriv; | 266 | struct ahci_host_priv *hpriv; |
@@ -378,7 +378,7 @@ static int __devexit ahci_highbank_remove(struct platform_device *pdev) | |||
378 | return 0; | 378 | return 0; |
379 | } | 379 | } |
380 | 380 | ||
381 | #ifdef CONFIG_PM | 381 | #ifdef CONFIG_PM_SLEEP |
382 | static int ahci_highbank_suspend(struct device *dev) | 382 | static int ahci_highbank_suspend(struct device *dev) |
383 | { | 383 | { |
384 | struct ata_host *host = dev_get_drvdata(dev); | 384 | struct ata_host *host = dev_get_drvdata(dev); |
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index 44a4256533e1..08608de87e4e 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c | |||
@@ -142,6 +142,39 @@ static int k2_sata_scr_write(struct ata_link *link, | |||
142 | return 0; | 142 | return 0; |
143 | } | 143 | } |
144 | 144 | ||
145 | static int k2_sata_softreset(struct ata_link *link, | ||
146 | unsigned int *class, unsigned long deadline) | ||
147 | { | ||
148 | u8 dmactl; | ||
149 | void __iomem *mmio = link->ap->ioaddr.bmdma_addr; | ||
150 | |||
151 | dmactl = readb(mmio + ATA_DMA_CMD); | ||
152 | |||
153 | /* Clear the start bit */ | ||
154 | if (dmactl & ATA_DMA_START) { | ||
155 | dmactl &= ~ATA_DMA_START; | ||
156 | writeb(dmactl, mmio + ATA_DMA_CMD); | ||
157 | } | ||
158 | |||
159 | return ata_sff_softreset(link, class, deadline); | ||
160 | } | ||
161 | |||
162 | static int k2_sata_hardreset(struct ata_link *link, | ||
163 | unsigned int *class, unsigned long deadline) | ||
164 | { | ||
165 | u8 dmactl; | ||
166 | void __iomem *mmio = link->ap->ioaddr.bmdma_addr; | ||
167 | |||
168 | dmactl = readb(mmio + ATA_DMA_CMD); | ||
169 | |||
170 | /* Clear the start bit */ | ||
171 | if (dmactl & ATA_DMA_START) { | ||
172 | dmactl &= ~ATA_DMA_START; | ||
173 | writeb(dmactl, mmio + ATA_DMA_CMD); | ||
174 | } | ||
175 | |||
176 | return sata_sff_hardreset(link, class, deadline); | ||
177 | } | ||
145 | 178 | ||
146 | static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) | 179 | static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) |
147 | { | 180 | { |
@@ -346,6 +379,8 @@ static struct scsi_host_template k2_sata_sht = { | |||
346 | 379 | ||
347 | static struct ata_port_operations k2_sata_ops = { | 380 | static struct ata_port_operations k2_sata_ops = { |
348 | .inherits = &ata_bmdma_port_ops, | 381 | .inherits = &ata_bmdma_port_ops, |
382 | .softreset = k2_sata_softreset, | ||
383 | .hardreset = k2_sata_hardreset, | ||
349 | .sff_tf_load = k2_sata_tf_load, | 384 | .sff_tf_load = k2_sata_tf_load, |
350 | .sff_tf_read = k2_sata_tf_read, | 385 | .sff_tf_read = k2_sata_tf_read, |
351 | .sff_check_status = k2_stat_check_status, | 386 | .sff_check_status = k2_stat_check_status, |
diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index 74a67e0019a2..fbbd4ed2edf2 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c | |||
@@ -451,7 +451,7 @@ int dev_pm_qos_add_ancestor_request(struct device *dev, | |||
451 | if (ancestor) | 451 | if (ancestor) |
452 | error = dev_pm_qos_add_request(ancestor, req, value); | 452 | error = dev_pm_qos_add_request(ancestor, req, value); |
453 | 453 | ||
454 | if (error) | 454 | if (error < 0) |
455 | req->dev = NULL; | 455 | req->dev = NULL; |
456 | 456 | ||
457 | return error; | 457 | return error; |
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index 80f9ab9c3aa4..ac869d28d5ba 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h | |||
@@ -120,6 +120,8 @@ int _regmap_write(struct regmap *map, unsigned int reg, | |||
120 | 120 | ||
121 | struct regmap_range_node { | 121 | struct regmap_range_node { |
122 | struct rb_node node; | 122 | struct rb_node node; |
123 | const char *name; | ||
124 | struct regmap *map; | ||
123 | 125 | ||
124 | unsigned int range_min; | 126 | unsigned int range_min; |
125 | unsigned int range_max; | 127 | unsigned int range_max; |
diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c index bb1ff175b962..f4b9dd01c981 100644 --- a/drivers/base/regmap/regmap-debugfs.c +++ b/drivers/base/regmap/regmap-debugfs.c | |||
@@ -56,15 +56,15 @@ static const struct file_operations regmap_name_fops = { | |||
56 | .llseek = default_llseek, | 56 | .llseek = default_llseek, |
57 | }; | 57 | }; |
58 | 58 | ||
59 | static ssize_t regmap_map_read_file(struct file *file, char __user *user_buf, | 59 | static ssize_t regmap_read_debugfs(struct regmap *map, unsigned int from, |
60 | size_t count, loff_t *ppos) | 60 | unsigned int to, char __user *user_buf, |
61 | size_t count, loff_t *ppos) | ||
61 | { | 62 | { |
62 | int reg_len, val_len, tot_len; | 63 | int reg_len, val_len, tot_len; |
63 | size_t buf_pos = 0; | 64 | size_t buf_pos = 0; |
64 | loff_t p = 0; | 65 | loff_t p = 0; |
65 | ssize_t ret; | 66 | ssize_t ret; |
66 | int i; | 67 | int i; |
67 | struct regmap *map = file->private_data; | ||
68 | char *buf; | 68 | char *buf; |
69 | unsigned int val; | 69 | unsigned int val; |
70 | 70 | ||
@@ -80,7 +80,7 @@ static ssize_t regmap_map_read_file(struct file *file, char __user *user_buf, | |||
80 | val_len = 2 * map->format.val_bytes; | 80 | val_len = 2 * map->format.val_bytes; |
81 | tot_len = reg_len + val_len + 3; /* : \n */ | 81 | tot_len = reg_len + val_len + 3; /* : \n */ |
82 | 82 | ||
83 | for (i = 0; i <= map->max_register; i += map->reg_stride) { | 83 | for (i = from; i <= to; i += map->reg_stride) { |
84 | if (!regmap_readable(map, i)) | 84 | if (!regmap_readable(map, i)) |
85 | continue; | 85 | continue; |
86 | 86 | ||
@@ -95,7 +95,7 @@ static ssize_t regmap_map_read_file(struct file *file, char __user *user_buf, | |||
95 | 95 | ||
96 | /* Format the register */ | 96 | /* Format the register */ |
97 | snprintf(buf + buf_pos, count - buf_pos, "%.*x: ", | 97 | snprintf(buf + buf_pos, count - buf_pos, "%.*x: ", |
98 | reg_len, i); | 98 | reg_len, i - from); |
99 | buf_pos += reg_len + 2; | 99 | buf_pos += reg_len + 2; |
100 | 100 | ||
101 | /* Format the value, write all X if we can't read */ | 101 | /* Format the value, write all X if we can't read */ |
@@ -126,6 +126,15 @@ out: | |||
126 | return ret; | 126 | return ret; |
127 | } | 127 | } |
128 | 128 | ||
129 | static ssize_t regmap_map_read_file(struct file *file, char __user *user_buf, | ||
130 | size_t count, loff_t *ppos) | ||
131 | { | ||
132 | struct regmap *map = file->private_data; | ||
133 | |||
134 | return regmap_read_debugfs(map, 0, map->max_register, user_buf, | ||
135 | count, ppos); | ||
136 | } | ||
137 | |||
129 | #undef REGMAP_ALLOW_WRITE_DEBUGFS | 138 | #undef REGMAP_ALLOW_WRITE_DEBUGFS |
130 | #ifdef REGMAP_ALLOW_WRITE_DEBUGFS | 139 | #ifdef REGMAP_ALLOW_WRITE_DEBUGFS |
131 | /* | 140 | /* |
@@ -174,6 +183,22 @@ static const struct file_operations regmap_map_fops = { | |||
174 | .llseek = default_llseek, | 183 | .llseek = default_llseek, |
175 | }; | 184 | }; |
176 | 185 | ||
186 | static ssize_t regmap_range_read_file(struct file *file, char __user *user_buf, | ||
187 | size_t count, loff_t *ppos) | ||
188 | { | ||
189 | struct regmap_range_node *range = file->private_data; | ||
190 | struct regmap *map = range->map; | ||
191 | |||
192 | return regmap_read_debugfs(map, range->range_min, range->range_max, | ||
193 | user_buf, count, ppos); | ||
194 | } | ||
195 | |||
196 | static const struct file_operations regmap_range_fops = { | ||
197 | .open = simple_open, | ||
198 | .read = regmap_range_read_file, | ||
199 | .llseek = default_llseek, | ||
200 | }; | ||
201 | |||
177 | static ssize_t regmap_access_read_file(struct file *file, | 202 | static ssize_t regmap_access_read_file(struct file *file, |
178 | char __user *user_buf, size_t count, | 203 | char __user *user_buf, size_t count, |
179 | loff_t *ppos) | 204 | loff_t *ppos) |
@@ -244,6 +269,9 @@ static const struct file_operations regmap_access_fops = { | |||
244 | 269 | ||
245 | void regmap_debugfs_init(struct regmap *map, const char *name) | 270 | void regmap_debugfs_init(struct regmap *map, const char *name) |
246 | { | 271 | { |
272 | struct rb_node *next; | ||
273 | struct regmap_range_node *range_node; | ||
274 | |||
247 | if (name) { | 275 | if (name) { |
248 | map->debugfs_name = kasprintf(GFP_KERNEL, "%s-%s", | 276 | map->debugfs_name = kasprintf(GFP_KERNEL, "%s-%s", |
249 | dev_name(map->dev), name); | 277 | dev_name(map->dev), name); |
@@ -276,6 +304,18 @@ void regmap_debugfs_init(struct regmap *map, const char *name) | |||
276 | debugfs_create_bool("cache_bypass", 0400, map->debugfs, | 304 | debugfs_create_bool("cache_bypass", 0400, map->debugfs, |
277 | &map->cache_bypass); | 305 | &map->cache_bypass); |
278 | } | 306 | } |
307 | |||
308 | next = rb_first(&map->range_tree); | ||
309 | while (next) { | ||
310 | range_node = rb_entry(next, struct regmap_range_node, node); | ||
311 | |||
312 | if (range_node->name) | ||
313 | debugfs_create_file(range_node->name, 0400, | ||
314 | map->debugfs, range_node, | ||
315 | ®map_range_fops); | ||
316 | |||
317 | next = rb_next(&range_node->node); | ||
318 | } | ||
279 | } | 319 | } |
280 | 320 | ||
281 | void regmap_debugfs_exit(struct regmap *map) | 321 | void regmap_debugfs_exit(struct regmap *map) |
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 52069d29ff12..96253cd949e9 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c | |||
@@ -519,20 +519,38 @@ struct regmap *regmap_init(struct device *dev, | |||
519 | } | 519 | } |
520 | 520 | ||
521 | map->range_tree = RB_ROOT; | 521 | map->range_tree = RB_ROOT; |
522 | for (i = 0; i < config->n_ranges; i++) { | 522 | for (i = 0; i < config->num_ranges; i++) { |
523 | const struct regmap_range_cfg *range_cfg = &config->ranges[i]; | 523 | const struct regmap_range_cfg *range_cfg = &config->ranges[i]; |
524 | struct regmap_range_node *new; | 524 | struct regmap_range_node *new; |
525 | 525 | ||
526 | /* Sanity check */ | 526 | /* Sanity check */ |
527 | if (range_cfg->range_max < range_cfg->range_min || | 527 | if (range_cfg->range_max < range_cfg->range_min) { |
528 | range_cfg->range_max > map->max_register || | 528 | dev_err(map->dev, "Invalid range %d: %d < %d\n", i, |
529 | range_cfg->selector_reg > map->max_register || | 529 | range_cfg->range_max, range_cfg->range_min); |
530 | range_cfg->window_len == 0) | ||
531 | goto err_range; | 530 | goto err_range; |
531 | } | ||
532 | |||
533 | if (range_cfg->range_max > map->max_register) { | ||
534 | dev_err(map->dev, "Invalid range %d: %d > %d\n", i, | ||
535 | range_cfg->range_max, map->max_register); | ||
536 | goto err_range; | ||
537 | } | ||
538 | |||
539 | if (range_cfg->selector_reg > map->max_register) { | ||
540 | dev_err(map->dev, | ||
541 | "Invalid range %d: selector out of map\n", i); | ||
542 | goto err_range; | ||
543 | } | ||
544 | |||
545 | if (range_cfg->window_len == 0) { | ||
546 | dev_err(map->dev, "Invalid range %d: window_len 0\n", | ||
547 | i); | ||
548 | goto err_range; | ||
549 | } | ||
532 | 550 | ||
533 | /* Make sure, that this register range has no selector | 551 | /* Make sure, that this register range has no selector |
534 | or data window within its boundary */ | 552 | or data window within its boundary */ |
535 | for (j = 0; j < config->n_ranges; j++) { | 553 | for (j = 0; j < config->num_ranges; j++) { |
536 | unsigned sel_reg = config->ranges[j].selector_reg; | 554 | unsigned sel_reg = config->ranges[j].selector_reg; |
537 | unsigned win_min = config->ranges[j].window_start; | 555 | unsigned win_min = config->ranges[j].window_start; |
538 | unsigned win_max = win_min + | 556 | unsigned win_max = win_min + |
@@ -540,11 +558,17 @@ struct regmap *regmap_init(struct device *dev, | |||
540 | 558 | ||
541 | if (range_cfg->range_min <= sel_reg && | 559 | if (range_cfg->range_min <= sel_reg && |
542 | sel_reg <= range_cfg->range_max) { | 560 | sel_reg <= range_cfg->range_max) { |
561 | dev_err(map->dev, | ||
562 | "Range %d: selector for %d in window\n", | ||
563 | i, j); | ||
543 | goto err_range; | 564 | goto err_range; |
544 | } | 565 | } |
545 | 566 | ||
546 | if (!(win_max < range_cfg->range_min || | 567 | if (!(win_max < range_cfg->range_min || |
547 | win_min > range_cfg->range_max)) { | 568 | win_min > range_cfg->range_max)) { |
569 | dev_err(map->dev, | ||
570 | "Range %d: window for %d in window\n", | ||
571 | i, j); | ||
548 | goto err_range; | 572 | goto err_range; |
549 | } | 573 | } |
550 | } | 574 | } |
@@ -555,6 +579,8 @@ struct regmap *regmap_init(struct device *dev, | |||
555 | goto err_range; | 579 | goto err_range; |
556 | } | 580 | } |
557 | 581 | ||
582 | new->map = map; | ||
583 | new->name = range_cfg->name; | ||
558 | new->range_min = range_cfg->range_min; | 584 | new->range_min = range_cfg->range_min; |
559 | new->range_max = range_cfg->range_max; | 585 | new->range_max = range_cfg->range_max; |
560 | new->selector_reg = range_cfg->selector_reg; | 586 | new->selector_reg = range_cfg->selector_reg; |
@@ -564,6 +590,7 @@ struct regmap *regmap_init(struct device *dev, | |||
564 | new->window_len = range_cfg->window_len; | 590 | new->window_len = range_cfg->window_len; |
565 | 591 | ||
566 | if (_regmap_range_add(map, new) == false) { | 592 | if (_regmap_range_add(map, new) == false) { |
593 | dev_err(map->dev, "Failed to add range %d\n", i); | ||
567 | kfree(new); | 594 | kfree(new); |
568 | goto err_range; | 595 | goto err_range; |
569 | } | 596 | } |
@@ -579,7 +606,7 @@ struct regmap *regmap_init(struct device *dev, | |||
579 | } | 606 | } |
580 | 607 | ||
581 | ret = regcache_init(map, config); | 608 | ret = regcache_init(map, config); |
582 | if (ret < 0) | 609 | if (ret != 0) |
583 | goto err_range; | 610 | goto err_range; |
584 | 611 | ||
585 | regmap_debugfs_init(map, config->name); | 612 | regmap_debugfs_init(map, config->name); |
@@ -738,59 +765,57 @@ struct regmap *dev_get_regmap(struct device *dev, const char *name) | |||
738 | EXPORT_SYMBOL_GPL(dev_get_regmap); | 765 | EXPORT_SYMBOL_GPL(dev_get_regmap); |
739 | 766 | ||
740 | static int _regmap_select_page(struct regmap *map, unsigned int *reg, | 767 | static int _regmap_select_page(struct regmap *map, unsigned int *reg, |
768 | struct regmap_range_node *range, | ||
741 | unsigned int val_num) | 769 | unsigned int val_num) |
742 | { | 770 | { |
743 | struct regmap_range_node *range; | ||
744 | void *orig_work_buf; | 771 | void *orig_work_buf; |
745 | unsigned int win_offset; | 772 | unsigned int win_offset; |
746 | unsigned int win_page; | 773 | unsigned int win_page; |
747 | bool page_chg; | 774 | bool page_chg; |
748 | int ret; | 775 | int ret; |
749 | 776 | ||
750 | range = _regmap_range_lookup(map, *reg); | 777 | win_offset = (*reg - range->range_min) % range->window_len; |
751 | if (range) { | 778 | win_page = (*reg - range->range_min) / range->window_len; |
752 | win_offset = (*reg - range->range_min) % range->window_len; | ||
753 | win_page = (*reg - range->range_min) / range->window_len; | ||
754 | |||
755 | if (val_num > 1) { | ||
756 | /* Bulk write shouldn't cross range boundary */ | ||
757 | if (*reg + val_num - 1 > range->range_max) | ||
758 | return -EINVAL; | ||
759 | 779 | ||
760 | /* ... or single page boundary */ | 780 | if (val_num > 1) { |
761 | if (val_num > range->window_len - win_offset) | 781 | /* Bulk write shouldn't cross range boundary */ |
762 | return -EINVAL; | 782 | if (*reg + val_num - 1 > range->range_max) |
763 | } | 783 | return -EINVAL; |
764 | 784 | ||
765 | /* It is possible to have selector register inside data window. | 785 | /* ... or single page boundary */ |
766 | In that case, selector register is located on every page and | 786 | if (val_num > range->window_len - win_offset) |
767 | it needs no page switching, when accessed alone. */ | 787 | return -EINVAL; |
768 | if (val_num > 1 || | 788 | } |
769 | range->window_start + win_offset != range->selector_reg) { | ||
770 | /* Use separate work_buf during page switching */ | ||
771 | orig_work_buf = map->work_buf; | ||
772 | map->work_buf = map->selector_work_buf; | ||
773 | 789 | ||
774 | ret = _regmap_update_bits(map, range->selector_reg, | 790 | /* It is possible to have selector register inside data window. |
775 | range->selector_mask, | 791 | In that case, selector register is located on every page and |
776 | win_page << range->selector_shift, | 792 | it needs no page switching, when accessed alone. */ |
777 | &page_chg); | 793 | if (val_num > 1 || |
794 | range->window_start + win_offset != range->selector_reg) { | ||
795 | /* Use separate work_buf during page switching */ | ||
796 | orig_work_buf = map->work_buf; | ||
797 | map->work_buf = map->selector_work_buf; | ||
778 | 798 | ||
779 | map->work_buf = orig_work_buf; | 799 | ret = _regmap_update_bits(map, range->selector_reg, |
800 | range->selector_mask, | ||
801 | win_page << range->selector_shift, | ||
802 | &page_chg); | ||
780 | 803 | ||
781 | if (ret < 0) | 804 | map->work_buf = orig_work_buf; |
782 | return ret; | ||
783 | } | ||
784 | 805 | ||
785 | *reg = range->window_start + win_offset; | 806 | if (ret != 0) |
807 | return ret; | ||
786 | } | 808 | } |
787 | 809 | ||
810 | *reg = range->window_start + win_offset; | ||
811 | |||
788 | return 0; | 812 | return 0; |
789 | } | 813 | } |
790 | 814 | ||
791 | static int _regmap_raw_write(struct regmap *map, unsigned int reg, | 815 | static int _regmap_raw_write(struct regmap *map, unsigned int reg, |
792 | const void *val, size_t val_len) | 816 | const void *val, size_t val_len) |
793 | { | 817 | { |
818 | struct regmap_range_node *range; | ||
794 | u8 *u8 = map->work_buf; | 819 | u8 *u8 = map->work_buf; |
795 | void *buf; | 820 | void *buf; |
796 | int ret = -ENOTSUPP; | 821 | int ret = -ENOTSUPP; |
@@ -825,9 +850,35 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, | |||
825 | } | 850 | } |
826 | } | 851 | } |
827 | 852 | ||
828 | ret = _regmap_select_page(map, ®, val_len / map->format.val_bytes); | 853 | range = _regmap_range_lookup(map, reg); |
829 | if (ret < 0) | 854 | if (range) { |
830 | return ret; | 855 | int val_num = val_len / map->format.val_bytes; |
856 | int win_offset = (reg - range->range_min) % range->window_len; | ||
857 | int win_residue = range->window_len - win_offset; | ||
858 | |||
859 | /* If the write goes beyond the end of the window split it */ | ||
860 | while (val_num > win_residue) { | ||
861 | dev_dbg(map->dev, "Writing window %d/%d\n", | ||
862 | win_residue, val_len / map->format.val_bytes); | ||
863 | ret = _regmap_raw_write(map, reg, val, win_residue * | ||
864 | map->format.val_bytes); | ||
865 | if (ret != 0) | ||
866 | return ret; | ||
867 | |||
868 | reg += win_residue; | ||
869 | val_num -= win_residue; | ||
870 | val += win_residue * map->format.val_bytes; | ||
871 | val_len -= win_residue * map->format.val_bytes; | ||
872 | |||
873 | win_offset = (reg - range->range_min) % | ||
874 | range->window_len; | ||
875 | win_residue = range->window_len - win_offset; | ||
876 | } | ||
877 | |||
878 | ret = _regmap_select_page(map, ®, range, val_num); | ||
879 | if (ret != 0) | ||
880 | return ret; | ||
881 | } | ||
831 | 882 | ||
832 | map->format.format_reg(map->work_buf, reg, map->reg_shift); | 883 | map->format.format_reg(map->work_buf, reg, map->reg_shift); |
833 | 884 | ||
@@ -876,6 +927,7 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, | |||
876 | int _regmap_write(struct regmap *map, unsigned int reg, | 927 | int _regmap_write(struct regmap *map, unsigned int reg, |
877 | unsigned int val) | 928 | unsigned int val) |
878 | { | 929 | { |
930 | struct regmap_range_node *range; | ||
879 | int ret; | 931 | int ret; |
880 | BUG_ON(!map->format.format_write && !map->format.format_val); | 932 | BUG_ON(!map->format.format_write && !map->format.format_val); |
881 | 933 | ||
@@ -897,9 +949,12 @@ int _regmap_write(struct regmap *map, unsigned int reg, | |||
897 | trace_regmap_reg_write(map->dev, reg, val); | 949 | trace_regmap_reg_write(map->dev, reg, val); |
898 | 950 | ||
899 | if (map->format.format_write) { | 951 | if (map->format.format_write) { |
900 | ret = _regmap_select_page(map, ®, 1); | 952 | range = _regmap_range_lookup(map, reg); |
901 | if (ret < 0) | 953 | if (range) { |
902 | return ret; | 954 | ret = _regmap_select_page(map, ®, range, 1); |
955 | if (ret != 0) | ||
956 | return ret; | ||
957 | } | ||
903 | 958 | ||
904 | map->format.format_write(map, reg, val); | 959 | map->format.format_write(map, reg, val); |
905 | 960 | ||
@@ -1055,12 +1110,17 @@ EXPORT_SYMBOL_GPL(regmap_bulk_write); | |||
1055 | static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, | 1110 | static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, |
1056 | unsigned int val_len) | 1111 | unsigned int val_len) |
1057 | { | 1112 | { |
1113 | struct regmap_range_node *range; | ||
1058 | u8 *u8 = map->work_buf; | 1114 | u8 *u8 = map->work_buf; |
1059 | int ret; | 1115 | int ret; |
1060 | 1116 | ||
1061 | ret = _regmap_select_page(map, ®, val_len / map->format.val_bytes); | 1117 | range = _regmap_range_lookup(map, reg); |
1062 | if (ret < 0) | 1118 | if (range) { |
1063 | return ret; | 1119 | ret = _regmap_select_page(map, ®, range, |
1120 | val_len / map->format.val_bytes); | ||
1121 | if (ret != 0) | ||
1122 | return ret; | ||
1123 | } | ||
1064 | 1124 | ||
1065 | map->format.format_reg(map->work_buf, reg, map->reg_shift); | 1125 | map->format.format_reg(map->work_buf, reg, map->reg_shift); |
1066 | 1126 | ||
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 3804a0af3ef1..9fe4f1865558 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c | |||
@@ -935,7 +935,7 @@ aoe_end_request(struct aoedev *d, struct request *rq, int fastfail) | |||
935 | 935 | ||
936 | /* cf. http://lkml.org/lkml/2006/10/31/28 */ | 936 | /* cf. http://lkml.org/lkml/2006/10/31/28 */ |
937 | if (!fastfail) | 937 | if (!fastfail) |
938 | q->request_fn(q); | 938 | __blk_run_queue(q); |
939 | } | 939 | } |
940 | 940 | ||
941 | static void | 941 | static void |
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 1c49d7173966..2ddd64a9ffde 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
@@ -4330,6 +4330,7 @@ out_unreg_region: | |||
4330 | out_unreg_blkdev: | 4330 | out_unreg_blkdev: |
4331 | unregister_blkdev(FLOPPY_MAJOR, "fd"); | 4331 | unregister_blkdev(FLOPPY_MAJOR, "fd"); |
4332 | out_put_disk: | 4332 | out_put_disk: |
4333 | destroy_workqueue(floppy_wq); | ||
4333 | for (drive = 0; drive < N_DRIVE; drive++) { | 4334 | for (drive = 0; drive < N_DRIVE; drive++) { |
4334 | if (!disks[drive]) | 4335 | if (!disks[drive]) |
4335 | break; | 4336 | break; |
@@ -4340,7 +4341,6 @@ out_put_disk: | |||
4340 | } | 4341 | } |
4341 | put_disk(disks[drive]); | 4342 | put_disk(disks[drive]); |
4342 | } | 4343 | } |
4343 | destroy_workqueue(floppy_wq); | ||
4344 | return err; | 4344 | return err; |
4345 | } | 4345 | } |
4346 | 4346 | ||
@@ -4555,6 +4555,8 @@ static void __exit floppy_module_exit(void) | |||
4555 | unregister_blkdev(FLOPPY_MAJOR, "fd"); | 4555 | unregister_blkdev(FLOPPY_MAJOR, "fd"); |
4556 | platform_driver_unregister(&floppy_driver); | 4556 | platform_driver_unregister(&floppy_driver); |
4557 | 4557 | ||
4558 | destroy_workqueue(floppy_wq); | ||
4559 | |||
4558 | for (drive = 0; drive < N_DRIVE; drive++) { | 4560 | for (drive = 0; drive < N_DRIVE; drive++) { |
4559 | del_timer_sync(&motor_off_timer[drive]); | 4561 | del_timer_sync(&motor_off_timer[drive]); |
4560 | 4562 | ||
@@ -4578,7 +4580,6 @@ static void __exit floppy_module_exit(void) | |||
4578 | 4580 | ||
4579 | cancel_delayed_work_sync(&fd_timeout); | 4581 | cancel_delayed_work_sync(&fd_timeout); |
4580 | cancel_delayed_work_sync(&fd_timer); | 4582 | cancel_delayed_work_sync(&fd_timer); |
4581 | destroy_workqueue(floppy_wq); | ||
4582 | 4583 | ||
4583 | if (atomic_read(&usage_count)) | 4584 | if (atomic_read(&usage_count)) |
4584 | floppy_release_irq_and_dma(); | 4585 | floppy_release_irq_and_dma(); |
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index adc6f36564cf..9694dd99bbbc 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c | |||
@@ -559,7 +559,7 @@ static void mtip_timeout_function(unsigned long int data) | |||
559 | struct mtip_cmd *command; | 559 | struct mtip_cmd *command; |
560 | int tag, cmdto_cnt = 0; | 560 | int tag, cmdto_cnt = 0; |
561 | unsigned int bit, group; | 561 | unsigned int bit, group; |
562 | unsigned int num_command_slots = port->dd->slot_groups * 32; | 562 | unsigned int num_command_slots; |
563 | unsigned long to, tagaccum[SLOTBITS_IN_LONGS]; | 563 | unsigned long to, tagaccum[SLOTBITS_IN_LONGS]; |
564 | 564 | ||
565 | if (unlikely(!port)) | 565 | if (unlikely(!port)) |
@@ -572,6 +572,7 @@ static void mtip_timeout_function(unsigned long int data) | |||
572 | } | 572 | } |
573 | /* clear the tag accumulator */ | 573 | /* clear the tag accumulator */ |
574 | memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long)); | 574 | memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long)); |
575 | num_command_slots = port->dd->slot_groups * 32; | ||
575 | 576 | ||
576 | for (tag = 0; tag < num_command_slots; tag++) { | 577 | for (tag = 0; tag < num_command_slots; tag++) { |
577 | /* | 578 | /* |
@@ -2218,8 +2219,8 @@ static int exec_drive_taskfile(struct driver_data *dd, | |||
2218 | fis.device); | 2219 | fis.device); |
2219 | 2220 | ||
2220 | /* check for erase mode support during secure erase.*/ | 2221 | /* check for erase mode support during secure erase.*/ |
2221 | if ((fis.command == ATA_CMD_SEC_ERASE_UNIT) | 2222 | if ((fis.command == ATA_CMD_SEC_ERASE_UNIT) && outbuf && |
2222 | && (outbuf[0] & MTIP_SEC_ERASE_MODE)) { | 2223 | (outbuf[0] & MTIP_SEC_ERASE_MODE)) { |
2223 | erasemode = 1; | 2224 | erasemode = 1; |
2224 | } | 2225 | } |
2225 | 2226 | ||
@@ -2439,7 +2440,7 @@ static int mtip_hw_ioctl(struct driver_data *dd, unsigned int cmd, | |||
2439 | * return value | 2440 | * return value |
2440 | * None | 2441 | * None |
2441 | */ | 2442 | */ |
2442 | static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, | 2443 | static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector, |
2443 | int nsect, int nents, int tag, void *callback, | 2444 | int nsect, int nents, int tag, void *callback, |
2444 | void *data, int dir) | 2445 | void *data, int dir) |
2445 | { | 2446 | { |
@@ -2447,6 +2448,7 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, | |||
2447 | struct mtip_port *port = dd->port; | 2448 | struct mtip_port *port = dd->port; |
2448 | struct mtip_cmd *command = &port->commands[tag]; | 2449 | struct mtip_cmd *command = &port->commands[tag]; |
2449 | int dma_dir = (dir == READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | 2450 | int dma_dir = (dir == READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; |
2451 | u64 start = sector; | ||
2450 | 2452 | ||
2451 | /* Map the scatter list for DMA access */ | 2453 | /* Map the scatter list for DMA access */ |
2452 | nents = dma_map_sg(&dd->pdev->dev, command->sg, nents, dma_dir); | 2454 | nents = dma_map_sg(&dd->pdev->dev, command->sg, nents, dma_dir); |
@@ -2465,8 +2467,12 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, | |||
2465 | fis->opts = 1 << 7; | 2467 | fis->opts = 1 << 7; |
2466 | fis->command = | 2468 | fis->command = |
2467 | (dir == READ ? ATA_CMD_FPDMA_READ : ATA_CMD_FPDMA_WRITE); | 2469 | (dir == READ ? ATA_CMD_FPDMA_READ : ATA_CMD_FPDMA_WRITE); |
2468 | *((unsigned int *) &fis->lba_low) = (start & 0xFFFFFF); | 2470 | fis->lba_low = start & 0xFF; |
2469 | *((unsigned int *) &fis->lba_low_ex) = ((start >> 24) & 0xFFFFFF); | 2471 | fis->lba_mid = (start >> 8) & 0xFF; |
2472 | fis->lba_hi = (start >> 16) & 0xFF; | ||
2473 | fis->lba_low_ex = (start >> 24) & 0xFF; | ||
2474 | fis->lba_mid_ex = (start >> 32) & 0xFF; | ||
2475 | fis->lba_hi_ex = (start >> 40) & 0xFF; | ||
2470 | fis->device = 1 << 6; | 2476 | fis->device = 1 << 6; |
2471 | fis->features = nsect & 0xFF; | 2477 | fis->features = nsect & 0xFF; |
2472 | fis->features_ex = (nsect >> 8) & 0xFF; | 2478 | fis->features_ex = (nsect >> 8) & 0xFF; |
diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index 5f4a917bd8bb..b1742640556a 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h | |||
@@ -34,7 +34,7 @@ | |||
34 | #define PCIE_CONFIG_EXT_DEVICE_CONTROL_OFFSET 0x48 | 34 | #define PCIE_CONFIG_EXT_DEVICE_CONTROL_OFFSET 0x48 |
35 | 35 | ||
36 | /* check for erase mode support during secure erase */ | 36 | /* check for erase mode support during secure erase */ |
37 | #define MTIP_SEC_ERASE_MODE 0x3 | 37 | #define MTIP_SEC_ERASE_MODE 0x2 |
38 | 38 | ||
39 | /* # of times to retry timed out/failed IOs */ | 39 | /* # of times to retry timed out/failed IOs */ |
40 | #define MTIP_MAX_RETRIES 2 | 40 | #define MTIP_MAX_RETRIES 2 |
@@ -155,14 +155,14 @@ enum { | |||
155 | MTIP_DDF_REBUILD_FAILED_BIT = 8, | 155 | MTIP_DDF_REBUILD_FAILED_BIT = 8, |
156 | }; | 156 | }; |
157 | 157 | ||
158 | __packed struct smart_attr{ | 158 | struct smart_attr { |
159 | u8 attr_id; | 159 | u8 attr_id; |
160 | u16 flags; | 160 | u16 flags; |
161 | u8 cur; | 161 | u8 cur; |
162 | u8 worst; | 162 | u8 worst; |
163 | u32 data; | 163 | u32 data; |
164 | u8 res[3]; | 164 | u8 res[3]; |
165 | }; | 165 | } __packed; |
166 | 166 | ||
167 | /* Register Frame Information Structure (FIS), host to device. */ | 167 | /* Register Frame Information Structure (FIS), host to device. */ |
168 | struct host_to_dev_fis { | 168 | struct host_to_dev_fis { |
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h index 8d4804732bac..8c4139647efc 100644 --- a/drivers/edac/amd64_edac.h +++ b/drivers/edac/amd64_edac.h | |||
@@ -33,7 +33,7 @@ | |||
33 | * detection. The mods to Rev F required more family | 33 | * detection. The mods to Rev F required more family |
34 | * information detection. | 34 | * information detection. |
35 | * | 35 | * |
36 | * Changes/Fixes by Borislav Petkov <borislav.petkov@amd.com>: | 36 | * Changes/Fixes by Borislav Petkov <bp@alien8.de>: |
37 | * - misc fixes and code cleanups | 37 | * - misc fixes and code cleanups |
38 | * | 38 | * |
39 | * This module is based on the following documents | 39 | * This module is based on the following documents |
diff --git a/drivers/edac/edac_stub.c b/drivers/edac/edac_stub.c index 6c86f6e54558..351945fa2ecd 100644 --- a/drivers/edac/edac_stub.c +++ b/drivers/edac/edac_stub.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * 2007 (c) MontaVista Software, Inc. | 6 | * 2007 (c) MontaVista Software, Inc. |
7 | * 2010 (c) Advanced Micro Devices Inc. | 7 | * 2010 (c) Advanced Micro Devices Inc. |
8 | * Borislav Petkov <borislav.petkov@amd.com> | 8 | * Borislav Petkov <bp@alien8.de> |
9 | * | 9 | * |
10 | * This file is licensed under the terms of the GNU General Public | 10 | * This file is licensed under the terms of the GNU General Public |
11 | * License version 2. This program is licensed "as is" without any | 11 | * License version 2. This program is licensed "as is" without any |
diff --git a/drivers/edac/mce_amd_inj.c b/drivers/edac/mce_amd_inj.c index 66b5151c1080..2ae78f20cc28 100644 --- a/drivers/edac/mce_amd_inj.c +++ b/drivers/edac/mce_amd_inj.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * This file may be distributed under the terms of the GNU General Public | 6 | * This file may be distributed under the terms of the GNU General Public |
7 | * License version 2. | 7 | * License version 2. |
8 | * | 8 | * |
9 | * Copyright (c) 2010: Borislav Petkov <borislav.petkov@amd.com> | 9 | * Copyright (c) 2010: Borislav Petkov <bp@alien8.de> |
10 | * Advanced Micro Devices Inc. | 10 | * Advanced Micro Devices Inc. |
11 | */ | 11 | */ |
12 | 12 | ||
@@ -168,6 +168,6 @@ module_init(edac_init_mce_inject); | |||
168 | module_exit(edac_exit_mce_inject); | 168 | module_exit(edac_exit_mce_inject); |
169 | 169 | ||
170 | MODULE_LICENSE("GPL"); | 170 | MODULE_LICENSE("GPL"); |
171 | MODULE_AUTHOR("Borislav Petkov <borislav.petkov@amd.com>"); | 171 | MODULE_AUTHOR("Borislav Petkov <bp@alien8.de>"); |
172 | MODULE_AUTHOR("AMD Inc."); | 172 | MODULE_AUTHOR("AMD Inc."); |
173 | MODULE_DESCRIPTION("MCE injection facility for testing MCE decoding"); | 173 | MODULE_DESCRIPTION("MCE injection facility for testing MCE decoding"); |
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index 1162d6b3bf85..bb1b392f5cda 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c | |||
@@ -1546,6 +1546,8 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev) | |||
1546 | struct sbp2_logical_unit *lu = sdev->hostdata; | 1546 | struct sbp2_logical_unit *lu = sdev->hostdata; |
1547 | 1547 | ||
1548 | sdev->use_10_for_rw = 1; | 1548 | sdev->use_10_for_rw = 1; |
1549 | sdev->no_report_opcodes = 1; | ||
1550 | sdev->no_write_same = 1; | ||
1549 | 1551 | ||
1550 | if (sbp2_param_exclusive_login) | 1552 | if (sbp2_param_exclusive_login) |
1551 | sdev->manage_start_stop = 1; | 1553 | sdev->manage_start_stop = 1; |
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index f11d8e3b4041..47150f5ded04 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -466,7 +466,7 @@ config GPIO_ADP5588_IRQ | |||
466 | 466 | ||
467 | config GPIO_ADNP | 467 | config GPIO_ADNP |
468 | tristate "Avionic Design N-bit GPIO expander" | 468 | tristate "Avionic Design N-bit GPIO expander" |
469 | depends on I2C && OF | 469 | depends on I2C && OF_GPIO |
470 | help | 470 | help |
471 | This option enables support for N GPIOs found on Avionic Design | 471 | This option enables support for N GPIOs found on Avionic Design |
472 | I2C GPIO expanders. The register space will be extended by powers | 472 | I2C GPIO expanders. The register space will be extended by powers |
diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c index 0f425189de11..ce1c84760076 100644 --- a/drivers/gpio/gpio-mcp23s08.c +++ b/drivers/gpio/gpio-mcp23s08.c | |||
@@ -77,7 +77,7 @@ struct mcp23s08_driver_data { | |||
77 | 77 | ||
78 | /*----------------------------------------------------------------------*/ | 78 | /*----------------------------------------------------------------------*/ |
79 | 79 | ||
80 | #ifdef CONFIG_I2C | 80 | #if IS_ENABLED(CONFIG_I2C) |
81 | 81 | ||
82 | static int mcp23008_read(struct mcp23s08 *mcp, unsigned reg) | 82 | static int mcp23008_read(struct mcp23s08 *mcp, unsigned reg) |
83 | { | 83 | { |
@@ -399,7 +399,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, | |||
399 | break; | 399 | break; |
400 | #endif /* CONFIG_SPI_MASTER */ | 400 | #endif /* CONFIG_SPI_MASTER */ |
401 | 401 | ||
402 | #ifdef CONFIG_I2C | 402 | #if IS_ENABLED(CONFIG_I2C) |
403 | case MCP_TYPE_008: | 403 | case MCP_TYPE_008: |
404 | mcp->ops = &mcp23008_ops; | 404 | mcp->ops = &mcp23008_ops; |
405 | mcp->chip.ngpio = 8; | 405 | mcp->chip.ngpio = 8; |
@@ -473,7 +473,7 @@ fail: | |||
473 | 473 | ||
474 | /*----------------------------------------------------------------------*/ | 474 | /*----------------------------------------------------------------------*/ |
475 | 475 | ||
476 | #ifdef CONFIG_I2C | 476 | #if IS_ENABLED(CONFIG_I2C) |
477 | 477 | ||
478 | static int __devinit mcp230xx_probe(struct i2c_client *client, | 478 | static int __devinit mcp230xx_probe(struct i2c_client *client, |
479 | const struct i2c_device_id *id) | 479 | const struct i2c_device_id *id) |
diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index cf7afb9eb61a..be65c0451ad5 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c | |||
@@ -92,6 +92,11 @@ static inline void __iomem *mvebu_gpioreg_out(struct mvebu_gpio_chip *mvchip) | |||
92 | return mvchip->membase + GPIO_OUT_OFF; | 92 | return mvchip->membase + GPIO_OUT_OFF; |
93 | } | 93 | } |
94 | 94 | ||
95 | static inline void __iomem *mvebu_gpioreg_blink(struct mvebu_gpio_chip *mvchip) | ||
96 | { | ||
97 | return mvchip->membase + GPIO_BLINK_EN_OFF; | ||
98 | } | ||
99 | |||
95 | static inline void __iomem *mvebu_gpioreg_io_conf(struct mvebu_gpio_chip *mvchip) | 100 | static inline void __iomem *mvebu_gpioreg_io_conf(struct mvebu_gpio_chip *mvchip) |
96 | { | 101 | { |
97 | return mvchip->membase + GPIO_IO_CONF_OFF; | 102 | return mvchip->membase + GPIO_IO_CONF_OFF; |
@@ -206,6 +211,23 @@ static int mvebu_gpio_get(struct gpio_chip *chip, unsigned pin) | |||
206 | return (u >> pin) & 1; | 211 | return (u >> pin) & 1; |
207 | } | 212 | } |
208 | 213 | ||
214 | static void mvebu_gpio_blink(struct gpio_chip *chip, unsigned pin, int value) | ||
215 | { | ||
216 | struct mvebu_gpio_chip *mvchip = | ||
217 | container_of(chip, struct mvebu_gpio_chip, chip); | ||
218 | unsigned long flags; | ||
219 | u32 u; | ||
220 | |||
221 | spin_lock_irqsave(&mvchip->lock, flags); | ||
222 | u = readl_relaxed(mvebu_gpioreg_blink(mvchip)); | ||
223 | if (value) | ||
224 | u |= 1 << pin; | ||
225 | else | ||
226 | u &= ~(1 << pin); | ||
227 | writel_relaxed(u, mvebu_gpioreg_blink(mvchip)); | ||
228 | spin_unlock_irqrestore(&mvchip->lock, flags); | ||
229 | } | ||
230 | |||
209 | static int mvebu_gpio_direction_input(struct gpio_chip *chip, unsigned pin) | 231 | static int mvebu_gpio_direction_input(struct gpio_chip *chip, unsigned pin) |
210 | { | 232 | { |
211 | struct mvebu_gpio_chip *mvchip = | 233 | struct mvebu_gpio_chip *mvchip = |
@@ -244,6 +266,7 @@ static int mvebu_gpio_direction_output(struct gpio_chip *chip, unsigned pin, | |||
244 | if (ret) | 266 | if (ret) |
245 | return ret; | 267 | return ret; |
246 | 268 | ||
269 | mvebu_gpio_blink(chip, pin, 0); | ||
247 | mvebu_gpio_set(chip, pin, value); | 270 | mvebu_gpio_set(chip, pin, value); |
248 | 271 | ||
249 | spin_lock_irqsave(&mvchip->lock, flags); | 272 | spin_lock_irqsave(&mvchip->lock, flags); |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index 05a909a17cee..15b182c84ce8 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c | |||
@@ -49,13 +49,7 @@ nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc) | |||
49 | if (chan->vblank.crtc != crtc) | 49 | if (chan->vblank.crtc != crtc) |
50 | continue; | 50 | continue; |
51 | 51 | ||
52 | if (nv_device(priv)->chipset == 0x50) { | 52 | if (nv_device(priv)->chipset >= 0xc0) { |
53 | nv_wr32(priv, 0x001704, chan->vblank.channel); | ||
54 | nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma); | ||
55 | bar->flush(bar); | ||
56 | nv_wr32(priv, 0x001570, chan->vblank.offset); | ||
57 | nv_wr32(priv, 0x001574, chan->vblank.value); | ||
58 | } else { | ||
59 | nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel); | 53 | nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel); |
60 | bar->flush(bar); | 54 | bar->flush(bar); |
61 | nv_wr32(priv, 0x06000c, | 55 | nv_wr32(priv, 0x06000c, |
@@ -63,6 +57,17 @@ nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc) | |||
63 | nv_wr32(priv, 0x060010, | 57 | nv_wr32(priv, 0x060010, |
64 | lower_32_bits(chan->vblank.offset)); | 58 | lower_32_bits(chan->vblank.offset)); |
65 | nv_wr32(priv, 0x060014, chan->vblank.value); | 59 | nv_wr32(priv, 0x060014, chan->vblank.value); |
60 | } else { | ||
61 | nv_wr32(priv, 0x001704, chan->vblank.channel); | ||
62 | nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma); | ||
63 | bar->flush(bar); | ||
64 | if (nv_device(priv)->chipset == 0x50) { | ||
65 | nv_wr32(priv, 0x001570, chan->vblank.offset); | ||
66 | nv_wr32(priv, 0x001574, chan->vblank.value); | ||
67 | } else { | ||
68 | nv_wr32(priv, 0x060010, chan->vblank.offset); | ||
69 | nv_wr32(priv, 0x060014, chan->vblank.value); | ||
70 | } | ||
66 | } | 71 | } |
67 | 72 | ||
68 | list_del(&chan->vblank.head); | 73 | list_del(&chan->vblank.head); |
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c index e45035efb8ca..7bbb1e1b7a8d 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c | |||
@@ -669,21 +669,27 @@ nv40_grctx_fill(struct nouveau_device *device, struct nouveau_gpuobj *mem) | |||
669 | }); | 669 | }); |
670 | } | 670 | } |
671 | 671 | ||
672 | void | 672 | int |
673 | nv40_grctx_init(struct nouveau_device *device, u32 *size) | 673 | nv40_grctx_init(struct nouveau_device *device, u32 *size) |
674 | { | 674 | { |
675 | u32 ctxprog[256], i; | 675 | u32 *ctxprog = kmalloc(256 * 4, GFP_KERNEL), i; |
676 | struct nouveau_grctx ctx = { | 676 | struct nouveau_grctx ctx = { |
677 | .device = device, | 677 | .device = device, |
678 | .mode = NOUVEAU_GRCTX_PROG, | 678 | .mode = NOUVEAU_GRCTX_PROG, |
679 | .data = ctxprog, | 679 | .data = ctxprog, |
680 | .ctxprog_max = ARRAY_SIZE(ctxprog) | 680 | .ctxprog_max = 256, |
681 | }; | 681 | }; |
682 | 682 | ||
683 | if (!ctxprog) | ||
684 | return -ENOMEM; | ||
685 | |||
683 | nv40_grctx_generate(&ctx); | 686 | nv40_grctx_generate(&ctx); |
684 | 687 | ||
685 | nv_wr32(device, 0x400324, 0); | 688 | nv_wr32(device, 0x400324, 0); |
686 | for (i = 0; i < ctx.ctxprog_len; i++) | 689 | for (i = 0; i < ctx.ctxprog_len; i++) |
687 | nv_wr32(device, 0x400328, ctxprog[i]); | 690 | nv_wr32(device, 0x400328, ctxprog[i]); |
688 | *size = ctx.ctxvals_pos * 4; | 691 | *size = ctx.ctxvals_pos * 4; |
692 | |||
693 | kfree(ctxprog); | ||
694 | return 0; | ||
689 | } | 695 | } |
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c index 425001204a89..cc6574eeb80e 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c | |||
@@ -346,7 +346,9 @@ nv40_graph_init(struct nouveau_object *object) | |||
346 | return ret; | 346 | return ret; |
347 | 347 | ||
348 | /* generate and upload context program */ | 348 | /* generate and upload context program */ |
349 | nv40_grctx_init(nv_device(priv), &priv->size); | 349 | ret = nv40_grctx_init(nv_device(priv), &priv->size); |
350 | if (ret) | ||
351 | return ret; | ||
350 | 352 | ||
351 | /* No context present currently */ | 353 | /* No context present currently */ |
352 | nv_wr32(priv, NV40_PGRAPH_CTXCTL_CUR, 0x00000000); | 354 | nv_wr32(priv, NV40_PGRAPH_CTXCTL_CUR, 0x00000000); |
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h index d2ac975afc2e..7da35a4e7970 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h | |||
@@ -15,7 +15,7 @@ nv44_graph_class(void *priv) | |||
15 | return !(0x0baf & (1 << (device->chipset & 0x0f))); | 15 | return !(0x0baf & (1 << (device->chipset & 0x0f))); |
16 | } | 16 | } |
17 | 17 | ||
18 | void nv40_grctx_init(struct nouveau_device *, u32 *size); | 18 | int nv40_grctx_init(struct nouveau_device *, u32 *size); |
19 | void nv40_grctx_fill(struct nouveau_device *, struct nouveau_gpuobj *); | 19 | void nv40_grctx_fill(struct nouveau_device *, struct nouveau_gpuobj *); |
20 | 20 | ||
21 | #endif | 21 | #endif |
diff --git a/drivers/gpu/drm/nouveau/core/include/core/object.h b/drivers/gpu/drm/nouveau/core/include/core/object.h index 818feabbf4a0..486f1a9217fd 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/object.h +++ b/drivers/gpu/drm/nouveau/core/include/core/object.h | |||
@@ -175,14 +175,18 @@ nv_mo32(void *obj, u32 addr, u32 mask, u32 data) | |||
175 | return temp; | 175 | return temp; |
176 | } | 176 | } |
177 | 177 | ||
178 | static inline bool | 178 | static inline int |
179 | nv_strncmp(void *obj, u32 addr, u32 len, const char *str) | 179 | nv_memcmp(void *obj, u32 addr, const char *str, u32 len) |
180 | { | 180 | { |
181 | unsigned char c1, c2; | ||
182 | |||
181 | while (len--) { | 183 | while (len--) { |
182 | if (nv_ro08(obj, addr++) != *(str++)) | 184 | c1 = nv_ro08(obj, addr++); |
183 | return false; | 185 | c2 = *(str++); |
186 | if (c1 != c2) | ||
187 | return c1 - c2; | ||
184 | } | 188 | } |
185 | return true; | 189 | return 0; |
186 | } | 190 | } |
187 | 191 | ||
188 | #endif | 192 | #endif |
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h index 39e73b91d360..41b7a6a76f19 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h | |||
@@ -54,6 +54,7 @@ int nv04_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *, | |||
54 | int clk, struct nouveau_pll_vals *); | 54 | int clk, struct nouveau_pll_vals *); |
55 | int nv04_clock_pll_prog(struct nouveau_clock *, u32 reg1, | 55 | int nv04_clock_pll_prog(struct nouveau_clock *, u32 reg1, |
56 | struct nouveau_pll_vals *); | 56 | struct nouveau_pll_vals *); |
57 | 57 | int nva3_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *, | |
58 | int clk, struct nouveau_pll_vals *); | ||
58 | 59 | ||
59 | #endif | 60 | #endif |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c b/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c index 7d750382a833..c51197157749 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c | |||
@@ -64,7 +64,7 @@ dcb_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) | |||
64 | } | 64 | } |
65 | } else | 65 | } else |
66 | if (*ver >= 0x15) { | 66 | if (*ver >= 0x15) { |
67 | if (!nv_strncmp(bios, dcb - 7, 7, "DEV_REC")) { | 67 | if (!nv_memcmp(bios, dcb - 7, "DEV_REC", 7)) { |
68 | u16 i2c = nv_ro16(bios, dcb + 2); | 68 | u16 i2c = nv_ro16(bios, dcb + 2); |
69 | *hdr = 4; | 69 | *hdr = 4; |
70 | *cnt = (i2c - dcb) / 10; | 70 | *cnt = (i2c - dcb) / 10; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c index cc8d7d162d7c..9068c98b96f6 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c +++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c | |||
@@ -66,6 +66,24 @@ nva3_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq) | |||
66 | return ret; | 66 | return ret; |
67 | } | 67 | } |
68 | 68 | ||
69 | int | ||
70 | nva3_clock_pll_calc(struct nouveau_clock *clock, struct nvbios_pll *info, | ||
71 | int clk, struct nouveau_pll_vals *pv) | ||
72 | { | ||
73 | int ret, N, M, P; | ||
74 | |||
75 | ret = nva3_pll_calc(clock, info, clk, &N, NULL, &M, &P); | ||
76 | |||
77 | if (ret > 0) { | ||
78 | pv->refclk = info->refclk; | ||
79 | pv->N1 = N; | ||
80 | pv->M1 = M; | ||
81 | pv->log2P = P; | ||
82 | } | ||
83 | return ret; | ||
84 | } | ||
85 | |||
86 | |||
69 | static int | 87 | static int |
70 | nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | 88 | nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, |
71 | struct nouveau_oclass *oclass, void *data, u32 size, | 89 | struct nouveau_oclass *oclass, void *data, u32 size, |
@@ -80,6 +98,7 @@ nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
80 | return ret; | 98 | return ret; |
81 | 99 | ||
82 | priv->base.pll_set = nva3_clock_pll_set; | 100 | priv->base.pll_set = nva3_clock_pll_set; |
101 | priv->base.pll_calc = nva3_clock_pll_calc; | ||
83 | return 0; | 102 | return 0; |
84 | } | 103 | } |
85 | 104 | ||
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c index 5ccce0b17bf3..f6962c9b6c36 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c | |||
@@ -79,6 +79,7 @@ nvc0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
79 | return ret; | 79 | return ret; |
80 | 80 | ||
81 | priv->base.pll_set = nvc0_clock_pll_set; | 81 | priv->base.pll_set = nvc0_clock_pll_set; |
82 | priv->base.pll_calc = nva3_clock_pll_calc; | ||
82 | return 0; | 83 | return 0; |
83 | } | 84 | } |
84 | 85 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index cc79c796afee..cbf1fc60a386 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c | |||
@@ -241,6 +241,10 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) | |||
241 | 241 | ||
242 | if (unlikely(!abi16)) | 242 | if (unlikely(!abi16)) |
243 | return -ENOMEM; | 243 | return -ENOMEM; |
244 | |||
245 | if (!drm->channel) | ||
246 | return nouveau_abi16_put(abi16, -ENODEV); | ||
247 | |||
244 | client = nv_client(abi16->client); | 248 | client = nv_client(abi16->client); |
245 | 249 | ||
246 | if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0) | 250 | if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0) |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 0910125cbbc3..8503b2ea570a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c | |||
@@ -129,7 +129,8 @@ nouveau_accel_init(struct nouveau_drm *drm) | |||
129 | 129 | ||
130 | /* initialise synchronisation routines */ | 130 | /* initialise synchronisation routines */ |
131 | if (device->card_type < NV_10) ret = nv04_fence_create(drm); | 131 | if (device->card_type < NV_10) ret = nv04_fence_create(drm); |
132 | else if (device->chipset < 0x84) ret = nv10_fence_create(drm); | 132 | else if (device->card_type < NV_50) ret = nv10_fence_create(drm); |
133 | else if (device->chipset < 0x84) ret = nv50_fence_create(drm); | ||
133 | else if (device->card_type < NV_C0) ret = nv84_fence_create(drm); | 134 | else if (device->card_type < NV_C0) ret = nv84_fence_create(drm); |
134 | else ret = nvc0_fence_create(drm); | 135 | else ret = nvc0_fence_create(drm); |
135 | if (ret) { | 136 | if (ret) { |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index af31f829f4a8..219942c660d7 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -1330,6 +1330,8 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav | |||
1330 | break; | 1330 | break; |
1331 | udelay(1); | 1331 | udelay(1); |
1332 | } | 1332 | } |
1333 | } else { | ||
1334 | save->crtc_enabled[i] = false; | ||
1333 | } | 1335 | } |
1334 | } | 1336 | } |
1335 | 1337 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c index 10ea17a6b2a6..42433344cb1b 100644 --- a/drivers/gpu/drm/radeon/radeon_agp.c +++ b/drivers/gpu/drm/radeon/radeon_agp.c | |||
@@ -69,9 +69,12 @@ static struct radeon_agpmode_quirk radeon_agpmode_quirk_list[] = { | |||
69 | /* Intel 82830 830 Chipset Host Bridge / Mobility M6 LY Needs AGPMode 2 (fdo #17360)*/ | 69 | /* Intel 82830 830 Chipset Host Bridge / Mobility M6 LY Needs AGPMode 2 (fdo #17360)*/ |
70 | { PCI_VENDOR_ID_INTEL, 0x3575, PCI_VENDOR_ID_ATI, 0x4c59, | 70 | { PCI_VENDOR_ID_INTEL, 0x3575, PCI_VENDOR_ID_ATI, 0x4c59, |
71 | PCI_VENDOR_ID_DELL, 0x00e3, 2}, | 71 | PCI_VENDOR_ID_DELL, 0x00e3, 2}, |
72 | /* Intel 82852/82855 host bridge / Mobility FireGL 9000 R250 Needs AGPMode 1 (lp #296617) */ | 72 | /* Intel 82852/82855 host bridge / Mobility FireGL 9000 RV250 Needs AGPMode 1 (lp #296617) */ |
73 | { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4c66, | 73 | { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4c66, |
74 | PCI_VENDOR_ID_DELL, 0x0149, 1}, | 74 | PCI_VENDOR_ID_DELL, 0x0149, 1}, |
75 | /* Intel 82855PM host bridge / Mobility FireGL 9000 RV250 Needs AGPMode 1 for suspend/resume */ | ||
76 | { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4c66, | ||
77 | PCI_VENDOR_ID_IBM, 0x0531, 1}, | ||
75 | /* Intel 82852/82855 host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (deb #467460) */ | 78 | /* Intel 82852/82855 host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (deb #467460) */ |
76 | { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4e50, | 79 | { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4e50, |
77 | 0x1025, 0x0061, 1}, | 80 | 0x1025, 0x0061, 1}, |
diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c index aa59a254be2c..c02bf208084f 100644 --- a/drivers/i2c/busses/i2c-at91.c +++ b/drivers/i2c/busses/i2c-at91.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #define AT91_TWI_STOP 0x0002 /* Send a Stop Condition */ | 39 | #define AT91_TWI_STOP 0x0002 /* Send a Stop Condition */ |
40 | #define AT91_TWI_MSEN 0x0004 /* Master Transfer Enable */ | 40 | #define AT91_TWI_MSEN 0x0004 /* Master Transfer Enable */ |
41 | #define AT91_TWI_SVDIS 0x0020 /* Slave Transfer Disable */ | 41 | #define AT91_TWI_SVDIS 0x0020 /* Slave Transfer Disable */ |
42 | #define AT91_TWI_QUICK 0x0040 /* SMBus quick command */ | ||
42 | #define AT91_TWI_SWRST 0x0080 /* Software Reset */ | 43 | #define AT91_TWI_SWRST 0x0080 /* Software Reset */ |
43 | 44 | ||
44 | #define AT91_TWI_MMR 0x0004 /* Master Mode Register */ | 45 | #define AT91_TWI_MMR 0x0004 /* Master Mode Register */ |
@@ -212,7 +213,11 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev) | |||
212 | 213 | ||
213 | INIT_COMPLETION(dev->cmd_complete); | 214 | INIT_COMPLETION(dev->cmd_complete); |
214 | dev->transfer_status = 0; | 215 | dev->transfer_status = 0; |
215 | if (dev->msg->flags & I2C_M_RD) { | 216 | |
217 | if (!dev->buf_len) { | ||
218 | at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_QUICK); | ||
219 | at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_TXCOMP); | ||
220 | } else if (dev->msg->flags & I2C_M_RD) { | ||
216 | unsigned start_flags = AT91_TWI_START; | 221 | unsigned start_flags = AT91_TWI_START; |
217 | 222 | ||
218 | if (at91_twi_read(dev, AT91_TWI_SR) & AT91_TWI_RXRDY) { | 223 | if (at91_twi_read(dev, AT91_TWI_SR) & AT91_TWI_RXRDY) { |
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index 286ca1917820..0670da79ee5e 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c | |||
@@ -287,12 +287,14 @@ read_init_dma_fail: | |||
287 | select_init_dma_fail: | 287 | select_init_dma_fail: |
288 | dma_unmap_sg(i2c->dev, &i2c->sg_io[0], 1, DMA_TO_DEVICE); | 288 | dma_unmap_sg(i2c->dev, &i2c->sg_io[0], 1, DMA_TO_DEVICE); |
289 | select_init_pio_fail: | 289 | select_init_pio_fail: |
290 | dmaengine_terminate_all(i2c->dmach); | ||
290 | return -EINVAL; | 291 | return -EINVAL; |
291 | 292 | ||
292 | /* Write failpath. */ | 293 | /* Write failpath. */ |
293 | write_init_dma_fail: | 294 | write_init_dma_fail: |
294 | dma_unmap_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE); | 295 | dma_unmap_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE); |
295 | write_init_pio_fail: | 296 | write_init_pio_fail: |
297 | dmaengine_terminate_all(i2c->dmach); | ||
296 | return -EINVAL; | 298 | return -EINVAL; |
297 | } | 299 | } |
298 | 300 | ||
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index db31eaed6ea5..3525c9e62cb0 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c | |||
@@ -43,7 +43,6 @@ | |||
43 | #include <linux/slab.h> | 43 | #include <linux/slab.h> |
44 | #include <linux/i2c-omap.h> | 44 | #include <linux/i2c-omap.h> |
45 | #include <linux/pm_runtime.h> | 45 | #include <linux/pm_runtime.h> |
46 | #include <linux/pm_qos.h> | ||
47 | 46 | ||
48 | /* I2C controller revisions */ | 47 | /* I2C controller revisions */ |
49 | #define OMAP_I2C_OMAP1_REV_2 0x20 | 48 | #define OMAP_I2C_OMAP1_REV_2 0x20 |
@@ -187,8 +186,9 @@ struct omap_i2c_dev { | |||
187 | int reg_shift; /* bit shift for I2C register addresses */ | 186 | int reg_shift; /* bit shift for I2C register addresses */ |
188 | struct completion cmd_complete; | 187 | struct completion cmd_complete; |
189 | struct resource *ioarea; | 188 | struct resource *ioarea; |
190 | u32 latency; /* maximum MPU wkup latency */ | 189 | u32 latency; /* maximum mpu wkup latency */ |
191 | struct pm_qos_request pm_qos_request; | 190 | void (*set_mpu_wkup_lat)(struct device *dev, |
191 | long latency); | ||
192 | u32 speed; /* Speed of bus in kHz */ | 192 | u32 speed; /* Speed of bus in kHz */ |
193 | u32 dtrev; /* extra revision from DT */ | 193 | u32 dtrev; /* extra revision from DT */ |
194 | u32 flags; | 194 | u32 flags; |
@@ -494,7 +494,9 @@ static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx) | |||
494 | dev->b_hw = 1; /* Enable hardware fixes */ | 494 | dev->b_hw = 1; /* Enable hardware fixes */ |
495 | 495 | ||
496 | /* calculate wakeup latency constraint for MPU */ | 496 | /* calculate wakeup latency constraint for MPU */ |
497 | dev->latency = (1000000 * dev->threshold) / (1000 * dev->speed / 8); | 497 | if (dev->set_mpu_wkup_lat != NULL) |
498 | dev->latency = (1000000 * dev->threshold) / | ||
499 | (1000 * dev->speed / 8); | ||
498 | } | 500 | } |
499 | 501 | ||
500 | /* | 502 | /* |
@@ -522,6 +524,9 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, | |||
522 | dev->buf = msg->buf; | 524 | dev->buf = msg->buf; |
523 | dev->buf_len = msg->len; | 525 | dev->buf_len = msg->len; |
524 | 526 | ||
527 | /* make sure writes to dev->buf_len are ordered */ | ||
528 | barrier(); | ||
529 | |||
525 | omap_i2c_write_reg(dev, OMAP_I2C_CNT_REG, dev->buf_len); | 530 | omap_i2c_write_reg(dev, OMAP_I2C_CNT_REG, dev->buf_len); |
526 | 531 | ||
527 | /* Clear the FIFO Buffers */ | 532 | /* Clear the FIFO Buffers */ |
@@ -579,7 +584,6 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, | |||
579 | */ | 584 | */ |
580 | timeout = wait_for_completion_timeout(&dev->cmd_complete, | 585 | timeout = wait_for_completion_timeout(&dev->cmd_complete, |
581 | OMAP_I2C_TIMEOUT); | 586 | OMAP_I2C_TIMEOUT); |
582 | dev->buf_len = 0; | ||
583 | if (timeout == 0) { | 587 | if (timeout == 0) { |
584 | dev_err(dev->dev, "controller timed out\n"); | 588 | dev_err(dev->dev, "controller timed out\n"); |
585 | omap_i2c_init(dev); | 589 | omap_i2c_init(dev); |
@@ -629,16 +633,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) | |||
629 | if (r < 0) | 633 | if (r < 0) |
630 | goto out; | 634 | goto out; |
631 | 635 | ||
632 | /* | 636 | if (dev->set_mpu_wkup_lat != NULL) |
633 | * When waiting for completion of a i2c transfer, we need to | 637 | dev->set_mpu_wkup_lat(dev->dev, dev->latency); |
634 | * set a wake up latency constraint for the MPU. This is to | ||
635 | * ensure quick enough wakeup from idle, when transfer | ||
636 | * completes. | ||
637 | */ | ||
638 | if (dev->latency) | ||
639 | pm_qos_add_request(&dev->pm_qos_request, | ||
640 | PM_QOS_CPU_DMA_LATENCY, | ||
641 | dev->latency); | ||
642 | 638 | ||
643 | for (i = 0; i < num; i++) { | 639 | for (i = 0; i < num; i++) { |
644 | r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1))); | 640 | r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1))); |
@@ -646,8 +642,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) | |||
646 | break; | 642 | break; |
647 | } | 643 | } |
648 | 644 | ||
649 | if (dev->latency) | 645 | if (dev->set_mpu_wkup_lat != NULL) |
650 | pm_qos_remove_request(&dev->pm_qos_request); | 646 | dev->set_mpu_wkup_lat(dev->dev, -1); |
651 | 647 | ||
652 | if (r == 0) | 648 | if (r == 0) |
653 | r = num; | 649 | r = num; |
@@ -1104,6 +1100,7 @@ omap_i2c_probe(struct platform_device *pdev) | |||
1104 | } else if (pdata != NULL) { | 1100 | } else if (pdata != NULL) { |
1105 | dev->speed = pdata->clkrate; | 1101 | dev->speed = pdata->clkrate; |
1106 | dev->flags = pdata->flags; | 1102 | dev->flags = pdata->flags; |
1103 | dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat; | ||
1107 | dev->dtrev = pdata->rev; | 1104 | dev->dtrev = pdata->rev; |
1108 | } | 1105 | } |
1109 | 1106 | ||
@@ -1159,8 +1156,9 @@ omap_i2c_probe(struct platform_device *pdev) | |||
1159 | dev->b_hw = 1; /* Enable hardware fixes */ | 1156 | dev->b_hw = 1; /* Enable hardware fixes */ |
1160 | 1157 | ||
1161 | /* calculate wakeup latency constraint for MPU */ | 1158 | /* calculate wakeup latency constraint for MPU */ |
1162 | dev->latency = (1000000 * dev->fifo_size) / | 1159 | if (dev->set_mpu_wkup_lat != NULL) |
1163 | (1000 * dev->speed / 8); | 1160 | dev->latency = (1000000 * dev->fifo_size) / |
1161 | (1000 * dev->speed / 8); | ||
1164 | } | 1162 | } |
1165 | 1163 | ||
1166 | /* reset ASAP, clearing any IRQs */ | 1164 | /* reset ASAP, clearing any IRQs */ |
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 3e0335f1fc60..9d902725bac9 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c | |||
@@ -806,6 +806,7 @@ static int s3c24xx_i2c_parse_dt_gpio(struct s3c24xx_i2c *i2c) | |||
806 | dev_err(i2c->dev, "invalid gpio[%d]: %d\n", idx, gpio); | 806 | dev_err(i2c->dev, "invalid gpio[%d]: %d\n", idx, gpio); |
807 | goto free_gpio; | 807 | goto free_gpio; |
808 | } | 808 | } |
809 | i2c->gpios[idx] = gpio; | ||
809 | 810 | ||
810 | ret = gpio_request(gpio, "i2c-bus"); | 811 | ret = gpio_request(gpio, "i2c-bus"); |
811 | if (ret) { | 812 | if (ret) { |
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c index c0ec7d42c3be..1abbc170d8b7 100644 --- a/drivers/input/input-mt.c +++ b/drivers/input/input-mt.c | |||
@@ -26,10 +26,14 @@ static void copy_abs(struct input_dev *dev, unsigned int dst, unsigned int src) | |||
26 | * input_mt_init_slots() - initialize MT input slots | 26 | * input_mt_init_slots() - initialize MT input slots |
27 | * @dev: input device supporting MT events and finger tracking | 27 | * @dev: input device supporting MT events and finger tracking |
28 | * @num_slots: number of slots used by the device | 28 | * @num_slots: number of slots used by the device |
29 | * @flags: mt tasks to handle in core | ||
29 | * | 30 | * |
30 | * This function allocates all necessary memory for MT slot handling | 31 | * This function allocates all necessary memory for MT slot handling |
31 | * in the input device, prepares the ABS_MT_SLOT and | 32 | * in the input device, prepares the ABS_MT_SLOT and |
32 | * ABS_MT_TRACKING_ID events for use and sets up appropriate buffers. | 33 | * ABS_MT_TRACKING_ID events for use and sets up appropriate buffers. |
34 | * Depending on the flags set, it also performs pointer emulation and | ||
35 | * frame synchronization. | ||
36 | * | ||
33 | * May be called repeatedly. Returns -EINVAL if attempting to | 37 | * May be called repeatedly. Returns -EINVAL if attempting to |
34 | * reinitialize with a different number of slots. | 38 | * reinitialize with a different number of slots. |
35 | */ | 39 | */ |
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 7c0f1ecfdd7a..104a7c3153c0 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
@@ -72,6 +72,16 @@ config INPUT_AD714X_SPI | |||
72 | To compile this driver as a module, choose M here: the | 72 | To compile this driver as a module, choose M here: the |
73 | module will be called ad714x-spi. | 73 | module will be called ad714x-spi. |
74 | 74 | ||
75 | config INPUT_ARIZONA_HAPTICS | ||
76 | tristate "Arizona haptics support" | ||
77 | depends on MFD_ARIZONA && SND_SOC | ||
78 | select INPUT_FF_MEMLESS | ||
79 | help | ||
80 | Say Y to enable support for the haptics module in Arizona CODECs. | ||
81 | |||
82 | To compile this driver as a module, choose M here: the | ||
83 | module will be called arizona-haptics. | ||
84 | |||
75 | config INPUT_BMA150 | 85 | config INPUT_BMA150 |
76 | tristate "BMA150/SMB380 acceleration sensor support" | 86 | tristate "BMA150/SMB380 acceleration sensor support" |
77 | depends on I2C | 87 | depends on I2C |
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 83fe6f5b77d1..5ea769eda999 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile | |||
@@ -14,6 +14,7 @@ obj-$(CONFIG_INPUT_ADXL34X) += adxl34x.o | |||
14 | obj-$(CONFIG_INPUT_ADXL34X_I2C) += adxl34x-i2c.o | 14 | obj-$(CONFIG_INPUT_ADXL34X_I2C) += adxl34x-i2c.o |
15 | obj-$(CONFIG_INPUT_ADXL34X_SPI) += adxl34x-spi.o | 15 | obj-$(CONFIG_INPUT_ADXL34X_SPI) += adxl34x-spi.o |
16 | obj-$(CONFIG_INPUT_APANEL) += apanel.o | 16 | obj-$(CONFIG_INPUT_APANEL) += apanel.o |
17 | obj-$(CONFIG_INPUT_ARIZONA_HAPTICS) += arizona-haptics.o | ||
17 | obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o | 18 | obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o |
18 | obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o | 19 | obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o |
19 | obj-$(CONFIG_INPUT_BFIN_ROTARY) += bfin_rotary.o | 20 | obj-$(CONFIG_INPUT_BFIN_ROTARY) += bfin_rotary.o |
diff --git a/drivers/input/misc/arizona-haptics.c b/drivers/input/misc/arizona-haptics.c new file mode 100644 index 000000000000..7a04f54ef961 --- /dev/null +++ b/drivers/input/misc/arizona-haptics.c | |||
@@ -0,0 +1,255 @@ | |||
1 | /* | ||
2 | * Arizona haptics driver | ||
3 | * | ||
4 | * Copyright 2012 Wolfson Microelectronics plc | ||
5 | * | ||
6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/input.h> | ||
16 | #include <linux/slab.h> | ||
17 | |||
18 | #include <sound/soc.h> | ||
19 | #include <sound/soc-dapm.h> | ||
20 | |||
21 | #include <linux/mfd/arizona/core.h> | ||
22 | #include <linux/mfd/arizona/pdata.h> | ||
23 | #include <linux/mfd/arizona/registers.h> | ||
24 | |||
25 | struct arizona_haptics { | ||
26 | struct arizona *arizona; | ||
27 | struct input_dev *input_dev; | ||
28 | struct work_struct work; | ||
29 | |||
30 | struct mutex mutex; | ||
31 | u8 intensity; | ||
32 | }; | ||
33 | |||
34 | static void arizona_haptics_work(struct work_struct *work) | ||
35 | { | ||
36 | struct arizona_haptics *haptics = container_of(work, | ||
37 | struct arizona_haptics, | ||
38 | work); | ||
39 | struct arizona *arizona = haptics->arizona; | ||
40 | struct mutex *dapm_mutex = &arizona->dapm->card->dapm_mutex; | ||
41 | int ret; | ||
42 | |||
43 | if (!haptics->arizona->dapm) { | ||
44 | dev_err(arizona->dev, "No DAPM context\n"); | ||
45 | return; | ||
46 | } | ||
47 | |||
48 | if (haptics->intensity) { | ||
49 | ret = regmap_update_bits(arizona->regmap, | ||
50 | ARIZONA_HAPTICS_PHASE_2_INTENSITY, | ||
51 | ARIZONA_PHASE2_INTENSITY_MASK, | ||
52 | haptics->intensity); | ||
53 | if (ret != 0) { | ||
54 | dev_err(arizona->dev, "Failed to set intensity: %d\n", | ||
55 | ret); | ||
56 | return; | ||
57 | } | ||
58 | |||
59 | /* This enable sequence will be a noop if already enabled */ | ||
60 | ret = regmap_update_bits(arizona->regmap, | ||
61 | ARIZONA_HAPTICS_CONTROL_1, | ||
62 | ARIZONA_HAP_CTRL_MASK, | ||
63 | 1 << ARIZONA_HAP_CTRL_SHIFT); | ||
64 | if (ret != 0) { | ||
65 | dev_err(arizona->dev, "Failed to start haptics: %d\n", | ||
66 | ret); | ||
67 | return; | ||
68 | } | ||
69 | |||
70 | mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | ||
71 | |||
72 | ret = snd_soc_dapm_enable_pin(arizona->dapm, "HAPTICS"); | ||
73 | if (ret != 0) { | ||
74 | dev_err(arizona->dev, "Failed to start HAPTICS: %d\n", | ||
75 | ret); | ||
76 | mutex_unlock(dapm_mutex); | ||
77 | return; | ||
78 | } | ||
79 | |||
80 | ret = snd_soc_dapm_sync(arizona->dapm); | ||
81 | if (ret != 0) { | ||
82 | dev_err(arizona->dev, "Failed to sync DAPM: %d\n", | ||
83 | ret); | ||
84 | mutex_unlock(dapm_mutex); | ||
85 | return; | ||
86 | } | ||
87 | |||
88 | mutex_unlock(dapm_mutex); | ||
89 | |||
90 | } else { | ||
91 | /* This disable sequence will be a noop if already enabled */ | ||
92 | mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | ||
93 | |||
94 | ret = snd_soc_dapm_disable_pin(arizona->dapm, "HAPTICS"); | ||
95 | if (ret != 0) { | ||
96 | dev_err(arizona->dev, "Failed to disable HAPTICS: %d\n", | ||
97 | ret); | ||
98 | mutex_unlock(dapm_mutex); | ||
99 | return; | ||
100 | } | ||
101 | |||
102 | ret = snd_soc_dapm_sync(arizona->dapm); | ||
103 | if (ret != 0) { | ||
104 | dev_err(arizona->dev, "Failed to sync DAPM: %d\n", | ||
105 | ret); | ||
106 | mutex_unlock(dapm_mutex); | ||
107 | return; | ||
108 | } | ||
109 | |||
110 | mutex_unlock(dapm_mutex); | ||
111 | |||
112 | ret = regmap_update_bits(arizona->regmap, | ||
113 | ARIZONA_HAPTICS_CONTROL_1, | ||
114 | ARIZONA_HAP_CTRL_MASK, | ||
115 | 1 << ARIZONA_HAP_CTRL_SHIFT); | ||
116 | if (ret != 0) { | ||
117 | dev_err(arizona->dev, "Failed to stop haptics: %d\n", | ||
118 | ret); | ||
119 | return; | ||
120 | } | ||
121 | } | ||
122 | } | ||
123 | |||
124 | static int arizona_haptics_play(struct input_dev *input, void *data, | ||
125 | struct ff_effect *effect) | ||
126 | { | ||
127 | struct arizona_haptics *haptics = input_get_drvdata(input); | ||
128 | struct arizona *arizona = haptics->arizona; | ||
129 | |||
130 | if (!arizona->dapm) { | ||
131 | dev_err(arizona->dev, "No DAPM context\n"); | ||
132 | return -EBUSY; | ||
133 | } | ||
134 | |||
135 | if (effect->u.rumble.strong_magnitude) { | ||
136 | /* Scale the magnitude into the range the device supports */ | ||
137 | if (arizona->pdata.hap_act) { | ||
138 | haptics->intensity = | ||
139 | effect->u.rumble.strong_magnitude >> 9; | ||
140 | if (effect->direction < 0x8000) | ||
141 | haptics->intensity += 0x7f; | ||
142 | } else { | ||
143 | haptics->intensity = | ||
144 | effect->u.rumble.strong_magnitude >> 8; | ||
145 | } | ||
146 | } else { | ||
147 | haptics->intensity = 0; | ||
148 | } | ||
149 | |||
150 | schedule_work(&haptics->work); | ||
151 | |||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | static void arizona_haptics_close(struct input_dev *input) | ||
156 | { | ||
157 | struct arizona_haptics *haptics = input_get_drvdata(input); | ||
158 | struct mutex *dapm_mutex = &haptics->arizona->dapm->card->dapm_mutex; | ||
159 | |||
160 | cancel_work_sync(&haptics->work); | ||
161 | |||
162 | mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | ||
163 | |||
164 | if (haptics->arizona->dapm) | ||
165 | snd_soc_dapm_disable_pin(haptics->arizona->dapm, "HAPTICS"); | ||
166 | |||
167 | mutex_unlock(dapm_mutex); | ||
168 | } | ||
169 | |||
170 | static int arizona_haptics_probe(struct platform_device *pdev) | ||
171 | { | ||
172 | struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); | ||
173 | struct arizona_haptics *haptics; | ||
174 | int ret; | ||
175 | |||
176 | haptics = devm_kzalloc(&pdev->dev, sizeof(*haptics), GFP_KERNEL); | ||
177 | if (!haptics) | ||
178 | return -ENOMEM; | ||
179 | |||
180 | haptics->arizona = arizona; | ||
181 | |||
182 | ret = regmap_update_bits(arizona->regmap, ARIZONA_HAPTICS_CONTROL_1, | ||
183 | ARIZONA_HAP_ACT, arizona->pdata.hap_act); | ||
184 | if (ret != 0) { | ||
185 | dev_err(arizona->dev, "Failed to set haptics actuator: %d\n", | ||
186 | ret); | ||
187 | return ret; | ||
188 | } | ||
189 | |||
190 | INIT_WORK(&haptics->work, arizona_haptics_work); | ||
191 | |||
192 | haptics->input_dev = input_allocate_device(); | ||
193 | if (haptics->input_dev == NULL) { | ||
194 | dev_err(arizona->dev, "Failed to allocate input device\n"); | ||
195 | return -ENOMEM; | ||
196 | } | ||
197 | |||
198 | input_set_drvdata(haptics->input_dev, haptics); | ||
199 | |||
200 | haptics->input_dev->name = "arizona:haptics"; | ||
201 | haptics->input_dev->dev.parent = pdev->dev.parent; | ||
202 | haptics->input_dev->close = arizona_haptics_close; | ||
203 | __set_bit(FF_RUMBLE, haptics->input_dev->ffbit); | ||
204 | |||
205 | ret = input_ff_create_memless(haptics->input_dev, NULL, | ||
206 | arizona_haptics_play); | ||
207 | if (ret < 0) { | ||
208 | dev_err(arizona->dev, "input_ff_create_memless() failed: %d\n", | ||
209 | ret); | ||
210 | goto err_ialloc; | ||
211 | } | ||
212 | |||
213 | ret = input_register_device(haptics->input_dev); | ||
214 | if (ret < 0) { | ||
215 | dev_err(arizona->dev, "couldn't register input device: %d\n", | ||
216 | ret); | ||
217 | goto err_iff; | ||
218 | } | ||
219 | |||
220 | platform_set_drvdata(pdev, haptics); | ||
221 | |||
222 | return 0; | ||
223 | |||
224 | err_iff: | ||
225 | if (haptics->input_dev) | ||
226 | input_ff_destroy(haptics->input_dev); | ||
227 | err_ialloc: | ||
228 | input_free_device(haptics->input_dev); | ||
229 | |||
230 | return ret; | ||
231 | } | ||
232 | |||
233 | static int arizona_haptics_remove(struct platform_device *pdev) | ||
234 | { | ||
235 | struct arizona_haptics *haptics = platform_get_drvdata(pdev); | ||
236 | |||
237 | input_unregister_device(haptics->input_dev); | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | static struct platform_driver arizona_haptics_driver = { | ||
243 | .probe = arizona_haptics_probe, | ||
244 | .remove = arizona_haptics_remove, | ||
245 | .driver = { | ||
246 | .name = "arizona-haptics", | ||
247 | .owner = THIS_MODULE, | ||
248 | }, | ||
249 | }; | ||
250 | module_platform_driver(arizona_haptics_driver); | ||
251 | |||
252 | MODULE_ALIAS("platform:arizona-haptics"); | ||
253 | MODULE_DESCRIPTION("Arizona haptics driver"); | ||
254 | MODULE_LICENSE("GPL"); | ||
255 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | ||
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 8f02e3d0e712..4c842c320c2e 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c | |||
@@ -12,8 +12,8 @@ | |||
12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
13 | 13 | ||
14 | #define MOUSEDEV_MINOR_BASE 32 | 14 | #define MOUSEDEV_MINOR_BASE 32 |
15 | #define MOUSEDEV_MINORS 32 | 15 | #define MOUSEDEV_MINORS 31 |
16 | #define MOUSEDEV_MIX 31 | 16 | #define MOUSEDEV_MIX 63 |
17 | 17 | ||
18 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index f02028ec3db6..78e5d9ab0ba7 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
@@ -955,7 +955,8 @@ static int ads7846_resume(struct device *dev) | |||
955 | 955 | ||
956 | static SIMPLE_DEV_PM_OPS(ads7846_pm, ads7846_suspend, ads7846_resume); | 956 | static SIMPLE_DEV_PM_OPS(ads7846_pm, ads7846_suspend, ads7846_resume); |
957 | 957 | ||
958 | static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads7846 *ts) | 958 | static int __devinit ads7846_setup_pendown(struct spi_device *spi, |
959 | struct ads7846 *ts) | ||
959 | { | 960 | { |
960 | struct ads7846_platform_data *pdata = spi->dev.platform_data; | 961 | struct ads7846_platform_data *pdata = spi->dev.platform_data; |
961 | int err; | 962 | int err; |
@@ -981,6 +982,9 @@ static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads784 | |||
981 | 982 | ||
982 | ts->gpio_pendown = pdata->gpio_pendown; | 983 | ts->gpio_pendown = pdata->gpio_pendown; |
983 | 984 | ||
985 | if (pdata->gpio_pendown_debounce) | ||
986 | gpio_set_debounce(pdata->gpio_pendown, | ||
987 | pdata->gpio_pendown_debounce); | ||
984 | } else { | 988 | } else { |
985 | dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n"); | 989 | dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n"); |
986 | return -EINVAL; | 990 | return -EINVAL; |
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index d4a4cd445cab..0badfa48b32b 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
@@ -4108,7 +4108,7 @@ static void swap_pci_ref(struct pci_dev **from, struct pci_dev *to) | |||
4108 | static int intel_iommu_add_device(struct device *dev) | 4108 | static int intel_iommu_add_device(struct device *dev) |
4109 | { | 4109 | { |
4110 | struct pci_dev *pdev = to_pci_dev(dev); | 4110 | struct pci_dev *pdev = to_pci_dev(dev); |
4111 | struct pci_dev *bridge, *dma_pdev; | 4111 | struct pci_dev *bridge, *dma_pdev = NULL; |
4112 | struct iommu_group *group; | 4112 | struct iommu_group *group; |
4113 | int ret; | 4113 | int ret; |
4114 | 4114 | ||
@@ -4122,7 +4122,7 @@ static int intel_iommu_add_device(struct device *dev) | |||
4122 | dma_pdev = pci_get_domain_bus_and_slot( | 4122 | dma_pdev = pci_get_domain_bus_and_slot( |
4123 | pci_domain_nr(pdev->bus), | 4123 | pci_domain_nr(pdev->bus), |
4124 | bridge->subordinate->number, 0); | 4124 | bridge->subordinate->number, 0); |
4125 | else | 4125 | if (!dma_pdev) |
4126 | dma_pdev = pci_dev_get(bridge); | 4126 | dma_pdev = pci_dev_get(bridge); |
4127 | } else | 4127 | } else |
4128 | dma_pdev = pci_dev_get(pdev); | 4128 | dma_pdev = pci_dev_get(pdev); |
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index a649f146d17b..c0f7a4266263 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c | |||
@@ -1054,6 +1054,7 @@ static int smmu_debugfs_stats_show(struct seq_file *s, void *v) | |||
1054 | stats[i], val, offs); | 1054 | stats[i], val, offs); |
1055 | } | 1055 | } |
1056 | seq_printf(s, "\n"); | 1056 | seq_printf(s, "\n"); |
1057 | dput(dent); | ||
1057 | 1058 | ||
1058 | return 0; | 1059 | return 0; |
1059 | } | 1060 | } |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 02db9183ca01..77e6eff41cae 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -740,8 +740,14 @@ static void rq_completed(struct mapped_device *md, int rw, int run_queue) | |||
740 | if (!md_in_flight(md)) | 740 | if (!md_in_flight(md)) |
741 | wake_up(&md->wait); | 741 | wake_up(&md->wait); |
742 | 742 | ||
743 | /* | ||
744 | * Run this off this callpath, as drivers could invoke end_io while | ||
745 | * inside their request_fn (and holding the queue lock). Calling | ||
746 | * back into ->request_fn() could deadlock attempting to grab the | ||
747 | * queue lock again. | ||
748 | */ | ||
743 | if (run_queue) | 749 | if (run_queue) |
744 | blk_run_queue(md->queue); | 750 | blk_run_queue_async(md->queue); |
745 | 751 | ||
746 | /* | 752 | /* |
747 | * dm_put() must be at the end of this function. See the comment above | 753 | * dm_put() must be at the end of this function. See the comment above |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 9ab768acfb62..61200717687b 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -1817,10 +1817,10 @@ retry: | |||
1817 | memset(bbp, 0xff, PAGE_SIZE); | 1817 | memset(bbp, 0xff, PAGE_SIZE); |
1818 | 1818 | ||
1819 | for (i = 0 ; i < bb->count ; i++) { | 1819 | for (i = 0 ; i < bb->count ; i++) { |
1820 | u64 internal_bb = *p++; | 1820 | u64 internal_bb = p[i]; |
1821 | u64 store_bb = ((BB_OFFSET(internal_bb) << 10) | 1821 | u64 store_bb = ((BB_OFFSET(internal_bb) << 10) |
1822 | | BB_LEN(internal_bb)); | 1822 | | BB_LEN(internal_bb)); |
1823 | *bbp++ = cpu_to_le64(store_bb); | 1823 | bbp[i] = cpu_to_le64(store_bb); |
1824 | } | 1824 | } |
1825 | bb->changed = 0; | 1825 | bb->changed = 0; |
1826 | if (read_seqretry(&bb->lock, seq)) | 1826 | if (read_seqretry(&bb->lock, seq)) |
@@ -5294,7 +5294,7 @@ void md_stop_writes(struct mddev *mddev) | |||
5294 | } | 5294 | } |
5295 | EXPORT_SYMBOL_GPL(md_stop_writes); | 5295 | EXPORT_SYMBOL_GPL(md_stop_writes); |
5296 | 5296 | ||
5297 | void md_stop(struct mddev *mddev) | 5297 | static void __md_stop(struct mddev *mddev) |
5298 | { | 5298 | { |
5299 | mddev->ready = 0; | 5299 | mddev->ready = 0; |
5300 | mddev->pers->stop(mddev); | 5300 | mddev->pers->stop(mddev); |
@@ -5304,6 +5304,18 @@ void md_stop(struct mddev *mddev) | |||
5304 | mddev->pers = NULL; | 5304 | mddev->pers = NULL; |
5305 | clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); | 5305 | clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); |
5306 | } | 5306 | } |
5307 | |||
5308 | void md_stop(struct mddev *mddev) | ||
5309 | { | ||
5310 | /* stop the array and free an attached data structures. | ||
5311 | * This is called from dm-raid | ||
5312 | */ | ||
5313 | __md_stop(mddev); | ||
5314 | bitmap_destroy(mddev); | ||
5315 | if (mddev->bio_set) | ||
5316 | bioset_free(mddev->bio_set); | ||
5317 | } | ||
5318 | |||
5307 | EXPORT_SYMBOL_GPL(md_stop); | 5319 | EXPORT_SYMBOL_GPL(md_stop); |
5308 | 5320 | ||
5309 | static int md_set_readonly(struct mddev *mddev, struct block_device *bdev) | 5321 | static int md_set_readonly(struct mddev *mddev, struct block_device *bdev) |
@@ -5364,7 +5376,7 @@ static int do_md_stop(struct mddev * mddev, int mode, | |||
5364 | set_disk_ro(disk, 0); | 5376 | set_disk_ro(disk, 0); |
5365 | 5377 | ||
5366 | __md_stop_writes(mddev); | 5378 | __md_stop_writes(mddev); |
5367 | md_stop(mddev); | 5379 | __md_stop(mddev); |
5368 | mddev->queue->merge_bvec_fn = NULL; | 5380 | mddev->queue->merge_bvec_fn = NULL; |
5369 | mddev->queue->backing_dev_info.congested_fn = NULL; | 5381 | mddev->queue->backing_dev_info.congested_fn = NULL; |
5370 | 5382 | ||
@@ -7936,9 +7948,9 @@ int md_is_badblock(struct badblocks *bb, sector_t s, int sectors, | |||
7936 | sector_t *first_bad, int *bad_sectors) | 7948 | sector_t *first_bad, int *bad_sectors) |
7937 | { | 7949 | { |
7938 | int hi; | 7950 | int hi; |
7939 | int lo = 0; | 7951 | int lo; |
7940 | u64 *p = bb->page; | 7952 | u64 *p = bb->page; |
7941 | int rv = 0; | 7953 | int rv; |
7942 | sector_t target = s + sectors; | 7954 | sector_t target = s + sectors; |
7943 | unsigned seq; | 7955 | unsigned seq; |
7944 | 7956 | ||
@@ -7953,7 +7965,8 @@ int md_is_badblock(struct badblocks *bb, sector_t s, int sectors, | |||
7953 | 7965 | ||
7954 | retry: | 7966 | retry: |
7955 | seq = read_seqbegin(&bb->lock); | 7967 | seq = read_seqbegin(&bb->lock); |
7956 | 7968 | lo = 0; | |
7969 | rv = 0; | ||
7957 | hi = bb->count; | 7970 | hi = bb->count; |
7958 | 7971 | ||
7959 | /* Binary search between lo and hi for 'target' | 7972 | /* Binary search between lo and hi for 'target' |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index d1295aff4173..0d5d0ff2c0f7 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -499,7 +499,7 @@ static void raid10_end_write_request(struct bio *bio, int error) | |||
499 | */ | 499 | */ |
500 | one_write_done(r10_bio); | 500 | one_write_done(r10_bio); |
501 | if (dec_rdev) | 501 | if (dec_rdev) |
502 | rdev_dec_pending(conf->mirrors[dev].rdev, conf->mddev); | 502 | rdev_dec_pending(rdev, conf->mddev); |
503 | } | 503 | } |
504 | 504 | ||
505 | /* | 505 | /* |
@@ -1334,18 +1334,21 @@ retry_write: | |||
1334 | blocked_rdev = rrdev; | 1334 | blocked_rdev = rrdev; |
1335 | break; | 1335 | break; |
1336 | } | 1336 | } |
1337 | if (rdev && (test_bit(Faulty, &rdev->flags) | ||
1338 | || test_bit(Unmerged, &rdev->flags))) | ||
1339 | rdev = NULL; | ||
1337 | if (rrdev && (test_bit(Faulty, &rrdev->flags) | 1340 | if (rrdev && (test_bit(Faulty, &rrdev->flags) |
1338 | || test_bit(Unmerged, &rrdev->flags))) | 1341 | || test_bit(Unmerged, &rrdev->flags))) |
1339 | rrdev = NULL; | 1342 | rrdev = NULL; |
1340 | 1343 | ||
1341 | r10_bio->devs[i].bio = NULL; | 1344 | r10_bio->devs[i].bio = NULL; |
1342 | r10_bio->devs[i].repl_bio = NULL; | 1345 | r10_bio->devs[i].repl_bio = NULL; |
1343 | if (!rdev || test_bit(Faulty, &rdev->flags) || | 1346 | |
1344 | test_bit(Unmerged, &rdev->flags)) { | 1347 | if (!rdev && !rrdev) { |
1345 | set_bit(R10BIO_Degraded, &r10_bio->state); | 1348 | set_bit(R10BIO_Degraded, &r10_bio->state); |
1346 | continue; | 1349 | continue; |
1347 | } | 1350 | } |
1348 | if (test_bit(WriteErrorSeen, &rdev->flags)) { | 1351 | if (rdev && test_bit(WriteErrorSeen, &rdev->flags)) { |
1349 | sector_t first_bad; | 1352 | sector_t first_bad; |
1350 | sector_t dev_sector = r10_bio->devs[i].addr; | 1353 | sector_t dev_sector = r10_bio->devs[i].addr; |
1351 | int bad_sectors; | 1354 | int bad_sectors; |
@@ -1387,8 +1390,10 @@ retry_write: | |||
1387 | max_sectors = good_sectors; | 1390 | max_sectors = good_sectors; |
1388 | } | 1391 | } |
1389 | } | 1392 | } |
1390 | r10_bio->devs[i].bio = bio; | 1393 | if (rdev) { |
1391 | atomic_inc(&rdev->nr_pending); | 1394 | r10_bio->devs[i].bio = bio; |
1395 | atomic_inc(&rdev->nr_pending); | ||
1396 | } | ||
1392 | if (rrdev) { | 1397 | if (rrdev) { |
1393 | r10_bio->devs[i].repl_bio = bio; | 1398 | r10_bio->devs[i].repl_bio = bio; |
1394 | atomic_inc(&rrdev->nr_pending); | 1399 | atomic_inc(&rrdev->nr_pending); |
@@ -1444,69 +1449,71 @@ retry_write: | |||
1444 | for (i = 0; i < conf->copies; i++) { | 1449 | for (i = 0; i < conf->copies; i++) { |
1445 | struct bio *mbio; | 1450 | struct bio *mbio; |
1446 | int d = r10_bio->devs[i].devnum; | 1451 | int d = r10_bio->devs[i].devnum; |
1447 | if (!r10_bio->devs[i].bio) | 1452 | if (r10_bio->devs[i].bio) { |
1448 | continue; | 1453 | struct md_rdev *rdev = conf->mirrors[d].rdev; |
1454 | mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); | ||
1455 | md_trim_bio(mbio, r10_bio->sector - bio->bi_sector, | ||
1456 | max_sectors); | ||
1457 | r10_bio->devs[i].bio = mbio; | ||
1458 | |||
1459 | mbio->bi_sector = (r10_bio->devs[i].addr+ | ||
1460 | choose_data_offset(r10_bio, | ||
1461 | rdev)); | ||
1462 | mbio->bi_bdev = rdev->bdev; | ||
1463 | mbio->bi_end_io = raid10_end_write_request; | ||
1464 | mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; | ||
1465 | mbio->bi_private = r10_bio; | ||
1449 | 1466 | ||
1450 | mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); | 1467 | atomic_inc(&r10_bio->remaining); |
1451 | md_trim_bio(mbio, r10_bio->sector - bio->bi_sector, | ||
1452 | max_sectors); | ||
1453 | r10_bio->devs[i].bio = mbio; | ||
1454 | 1468 | ||
1455 | mbio->bi_sector = (r10_bio->devs[i].addr+ | 1469 | cb = blk_check_plugged(raid10_unplug, mddev, |
1456 | choose_data_offset(r10_bio, | 1470 | sizeof(*plug)); |
1457 | conf->mirrors[d].rdev)); | 1471 | if (cb) |
1458 | mbio->bi_bdev = conf->mirrors[d].rdev->bdev; | 1472 | plug = container_of(cb, struct raid10_plug_cb, |
1459 | mbio->bi_end_io = raid10_end_write_request; | 1473 | cb); |
1460 | mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; | 1474 | else |
1461 | mbio->bi_private = r10_bio; | 1475 | plug = NULL; |
1476 | spin_lock_irqsave(&conf->device_lock, flags); | ||
1477 | if (plug) { | ||
1478 | bio_list_add(&plug->pending, mbio); | ||
1479 | plug->pending_cnt++; | ||
1480 | } else { | ||
1481 | bio_list_add(&conf->pending_bio_list, mbio); | ||
1482 | conf->pending_count++; | ||
1483 | } | ||
1484 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
1485 | if (!plug) | ||
1486 | md_wakeup_thread(mddev->thread); | ||
1487 | } | ||
1462 | 1488 | ||
1463 | atomic_inc(&r10_bio->remaining); | 1489 | if (r10_bio->devs[i].repl_bio) { |
1490 | struct md_rdev *rdev = conf->mirrors[d].replacement; | ||
1491 | if (rdev == NULL) { | ||
1492 | /* Replacement just got moved to main 'rdev' */ | ||
1493 | smp_mb(); | ||
1494 | rdev = conf->mirrors[d].rdev; | ||
1495 | } | ||
1496 | mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); | ||
1497 | md_trim_bio(mbio, r10_bio->sector - bio->bi_sector, | ||
1498 | max_sectors); | ||
1499 | r10_bio->devs[i].repl_bio = mbio; | ||
1500 | |||
1501 | mbio->bi_sector = (r10_bio->devs[i].addr + | ||
1502 | choose_data_offset( | ||
1503 | r10_bio, rdev)); | ||
1504 | mbio->bi_bdev = rdev->bdev; | ||
1505 | mbio->bi_end_io = raid10_end_write_request; | ||
1506 | mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; | ||
1507 | mbio->bi_private = r10_bio; | ||
1464 | 1508 | ||
1465 | cb = blk_check_plugged(raid10_unplug, mddev, sizeof(*plug)); | 1509 | atomic_inc(&r10_bio->remaining); |
1466 | if (cb) | 1510 | spin_lock_irqsave(&conf->device_lock, flags); |
1467 | plug = container_of(cb, struct raid10_plug_cb, cb); | ||
1468 | else | ||
1469 | plug = NULL; | ||
1470 | spin_lock_irqsave(&conf->device_lock, flags); | ||
1471 | if (plug) { | ||
1472 | bio_list_add(&plug->pending, mbio); | ||
1473 | plug->pending_cnt++; | ||
1474 | } else { | ||
1475 | bio_list_add(&conf->pending_bio_list, mbio); | 1511 | bio_list_add(&conf->pending_bio_list, mbio); |
1476 | conf->pending_count++; | 1512 | conf->pending_count++; |
1513 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
1514 | if (!mddev_check_plugged(mddev)) | ||
1515 | md_wakeup_thread(mddev->thread); | ||
1477 | } | 1516 | } |
1478 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
1479 | if (!plug) | ||
1480 | md_wakeup_thread(mddev->thread); | ||
1481 | |||
1482 | if (!r10_bio->devs[i].repl_bio) | ||
1483 | continue; | ||
1484 | |||
1485 | mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); | ||
1486 | md_trim_bio(mbio, r10_bio->sector - bio->bi_sector, | ||
1487 | max_sectors); | ||
1488 | r10_bio->devs[i].repl_bio = mbio; | ||
1489 | |||
1490 | /* We are actively writing to the original device | ||
1491 | * so it cannot disappear, so the replacement cannot | ||
1492 | * become NULL here | ||
1493 | */ | ||
1494 | mbio->bi_sector = (r10_bio->devs[i].addr + | ||
1495 | choose_data_offset( | ||
1496 | r10_bio, | ||
1497 | conf->mirrors[d].replacement)); | ||
1498 | mbio->bi_bdev = conf->mirrors[d].replacement->bdev; | ||
1499 | mbio->bi_end_io = raid10_end_write_request; | ||
1500 | mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; | ||
1501 | mbio->bi_private = r10_bio; | ||
1502 | |||
1503 | atomic_inc(&r10_bio->remaining); | ||
1504 | spin_lock_irqsave(&conf->device_lock, flags); | ||
1505 | bio_list_add(&conf->pending_bio_list, mbio); | ||
1506 | conf->pending_count++; | ||
1507 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
1508 | if (!mddev_check_plugged(mddev)) | ||
1509 | md_wakeup_thread(mddev->thread); | ||
1510 | } | 1517 | } |
1511 | 1518 | ||
1512 | /* Don't remove the bias on 'remaining' (one_write_done) until | 1519 | /* Don't remove the bias on 'remaining' (one_write_done) until |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index c5439dce0295..a4502686e7a8 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -2774,10 +2774,12 @@ static void handle_stripe_clean_event(struct r5conf *conf, | |||
2774 | dev = &sh->dev[i]; | 2774 | dev = &sh->dev[i]; |
2775 | if (!test_bit(R5_LOCKED, &dev->flags) && | 2775 | if (!test_bit(R5_LOCKED, &dev->flags) && |
2776 | (test_bit(R5_UPTODATE, &dev->flags) || | 2776 | (test_bit(R5_UPTODATE, &dev->flags) || |
2777 | test_and_clear_bit(R5_Discard, &dev->flags))) { | 2777 | test_bit(R5_Discard, &dev->flags))) { |
2778 | /* We can return any write requests */ | 2778 | /* We can return any write requests */ |
2779 | struct bio *wbi, *wbi2; | 2779 | struct bio *wbi, *wbi2; |
2780 | pr_debug("Return write for disc %d\n", i); | 2780 | pr_debug("Return write for disc %d\n", i); |
2781 | if (test_and_clear_bit(R5_Discard, &dev->flags)) | ||
2782 | clear_bit(R5_UPTODATE, &dev->flags); | ||
2781 | wbi = dev->written; | 2783 | wbi = dev->written; |
2782 | dev->written = NULL; | 2784 | dev->written = NULL; |
2783 | while (wbi && wbi->bi_sector < | 2785 | while (wbi && wbi->bi_sector < |
@@ -2795,7 +2797,8 @@ static void handle_stripe_clean_event(struct r5conf *conf, | |||
2795 | !test_bit(STRIPE_DEGRADED, &sh->state), | 2797 | !test_bit(STRIPE_DEGRADED, &sh->state), |
2796 | 0); | 2798 | 0); |
2797 | } | 2799 | } |
2798 | } | 2800 | } else if (test_bit(R5_Discard, &sh->dev[i].flags)) |
2801 | clear_bit(R5_Discard, &sh->dev[i].flags); | ||
2799 | 2802 | ||
2800 | if (test_and_clear_bit(STRIPE_FULL_WRITE, &sh->state)) | 2803 | if (test_and_clear_bit(STRIPE_FULL_WRITE, &sh->state)) |
2801 | if (atomic_dec_and_test(&conf->pending_full_writes)) | 2804 | if (atomic_dec_and_test(&conf->pending_full_writes)) |
@@ -3490,40 +3493,6 @@ static void handle_stripe(struct stripe_head *sh) | |||
3490 | handle_failed_sync(conf, sh, &s); | 3493 | handle_failed_sync(conf, sh, &s); |
3491 | } | 3494 | } |
3492 | 3495 | ||
3493 | /* | ||
3494 | * might be able to return some write requests if the parity blocks | ||
3495 | * are safe, or on a failed drive | ||
3496 | */ | ||
3497 | pdev = &sh->dev[sh->pd_idx]; | ||
3498 | s.p_failed = (s.failed >= 1 && s.failed_num[0] == sh->pd_idx) | ||
3499 | || (s.failed >= 2 && s.failed_num[1] == sh->pd_idx); | ||
3500 | qdev = &sh->dev[sh->qd_idx]; | ||
3501 | s.q_failed = (s.failed >= 1 && s.failed_num[0] == sh->qd_idx) | ||
3502 | || (s.failed >= 2 && s.failed_num[1] == sh->qd_idx) | ||
3503 | || conf->level < 6; | ||
3504 | |||
3505 | if (s.written && | ||
3506 | (s.p_failed || ((test_bit(R5_Insync, &pdev->flags) | ||
3507 | && !test_bit(R5_LOCKED, &pdev->flags) | ||
3508 | && (test_bit(R5_UPTODATE, &pdev->flags) || | ||
3509 | test_bit(R5_Discard, &pdev->flags))))) && | ||
3510 | (s.q_failed || ((test_bit(R5_Insync, &qdev->flags) | ||
3511 | && !test_bit(R5_LOCKED, &qdev->flags) | ||
3512 | && (test_bit(R5_UPTODATE, &qdev->flags) || | ||
3513 | test_bit(R5_Discard, &qdev->flags)))))) | ||
3514 | handle_stripe_clean_event(conf, sh, disks, &s.return_bi); | ||
3515 | |||
3516 | /* Now we might consider reading some blocks, either to check/generate | ||
3517 | * parity, or to satisfy requests | ||
3518 | * or to load a block that is being partially written. | ||
3519 | */ | ||
3520 | if (s.to_read || s.non_overwrite | ||
3521 | || (conf->level == 6 && s.to_write && s.failed) | ||
3522 | || (s.syncing && (s.uptodate + s.compute < disks)) | ||
3523 | || s.replacing | ||
3524 | || s.expanding) | ||
3525 | handle_stripe_fill(sh, &s, disks); | ||
3526 | |||
3527 | /* Now we check to see if any write operations have recently | 3496 | /* Now we check to see if any write operations have recently |
3528 | * completed | 3497 | * completed |
3529 | */ | 3498 | */ |
@@ -3561,6 +3530,40 @@ static void handle_stripe(struct stripe_head *sh) | |||
3561 | s.dec_preread_active = 1; | 3530 | s.dec_preread_active = 1; |
3562 | } | 3531 | } |
3563 | 3532 | ||
3533 | /* | ||
3534 | * might be able to return some write requests if the parity blocks | ||
3535 | * are safe, or on a failed drive | ||
3536 | */ | ||
3537 | pdev = &sh->dev[sh->pd_idx]; | ||
3538 | s.p_failed = (s.failed >= 1 && s.failed_num[0] == sh->pd_idx) | ||
3539 | || (s.failed >= 2 && s.failed_num[1] == sh->pd_idx); | ||
3540 | qdev = &sh->dev[sh->qd_idx]; | ||
3541 | s.q_failed = (s.failed >= 1 && s.failed_num[0] == sh->qd_idx) | ||
3542 | || (s.failed >= 2 && s.failed_num[1] == sh->qd_idx) | ||
3543 | || conf->level < 6; | ||
3544 | |||
3545 | if (s.written && | ||
3546 | (s.p_failed || ((test_bit(R5_Insync, &pdev->flags) | ||
3547 | && !test_bit(R5_LOCKED, &pdev->flags) | ||
3548 | && (test_bit(R5_UPTODATE, &pdev->flags) || | ||
3549 | test_bit(R5_Discard, &pdev->flags))))) && | ||
3550 | (s.q_failed || ((test_bit(R5_Insync, &qdev->flags) | ||
3551 | && !test_bit(R5_LOCKED, &qdev->flags) | ||
3552 | && (test_bit(R5_UPTODATE, &qdev->flags) || | ||
3553 | test_bit(R5_Discard, &qdev->flags)))))) | ||
3554 | handle_stripe_clean_event(conf, sh, disks, &s.return_bi); | ||
3555 | |||
3556 | /* Now we might consider reading some blocks, either to check/generate | ||
3557 | * parity, or to satisfy requests | ||
3558 | * or to load a block that is being partially written. | ||
3559 | */ | ||
3560 | if (s.to_read || s.non_overwrite | ||
3561 | || (conf->level == 6 && s.to_write && s.failed) | ||
3562 | || (s.syncing && (s.uptodate + s.compute < disks)) | ||
3563 | || s.replacing | ||
3564 | || s.expanding) | ||
3565 | handle_stripe_fill(sh, &s, disks); | ||
3566 | |||
3564 | /* Now to consider new write requests and what else, if anything | 3567 | /* Now to consider new write requests and what else, if anything |
3565 | * should be read. We do not handle new writes when: | 3568 | * should be read. We do not handle new writes when: |
3566 | * 1/ A 'write' operation (copy+xor) is already in flight. | 3569 | * 1/ A 'write' operation (copy+xor) is already in flight. |
@@ -5529,6 +5532,10 @@ static int run(struct mddev *mddev) | |||
5529 | * discard data disk but write parity disk | 5532 | * discard data disk but write parity disk |
5530 | */ | 5533 | */ |
5531 | stripe = stripe * PAGE_SIZE; | 5534 | stripe = stripe * PAGE_SIZE; |
5535 | /* Round up to power of 2, as discard handling | ||
5536 | * currently assumes that */ | ||
5537 | while ((stripe-1) & stripe) | ||
5538 | stripe = (stripe | (stripe-1)) + 1; | ||
5532 | mddev->queue->limits.discard_alignment = stripe; | 5539 | mddev->queue->limits.discard_alignment = stripe; |
5533 | mddev->queue->limits.discard_granularity = stripe; | 5540 | mddev->queue->limits.discard_granularity = stripe; |
5534 | /* | 5541 | /* |
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index 1b48f2094806..75619711a9e7 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c | |||
@@ -272,6 +272,7 @@ static struct mfd_cell early_devs[] = { | |||
272 | static struct mfd_cell wm5102_devs[] = { | 272 | static struct mfd_cell wm5102_devs[] = { |
273 | { .name = "arizona-extcon" }, | 273 | { .name = "arizona-extcon" }, |
274 | { .name = "arizona-gpio" }, | 274 | { .name = "arizona-gpio" }, |
275 | { .name = "arizona-haptics" }, | ||
275 | { .name = "arizona-micsupp" }, | 276 | { .name = "arizona-micsupp" }, |
276 | { .name = "arizona-pwm" }, | 277 | { .name = "arizona-pwm" }, |
277 | { .name = "wm5102-codec" }, | 278 | { .name = "wm5102-codec" }, |
@@ -280,6 +281,7 @@ static struct mfd_cell wm5102_devs[] = { | |||
280 | static struct mfd_cell wm5110_devs[] = { | 281 | static struct mfd_cell wm5110_devs[] = { |
281 | { .name = "arizona-extcon" }, | 282 | { .name = "arizona-extcon" }, |
282 | { .name = "arizona-gpio" }, | 283 | { .name = "arizona-gpio" }, |
284 | { .name = "arizona-haptics" }, | ||
283 | { .name = "arizona-micsupp" }, | 285 | { .name = "arizona-micsupp" }, |
284 | { .name = "arizona-pwm" }, | 286 | { .name = "arizona-pwm" }, |
285 | { .name = "wm5110-codec" }, | 287 | { .name = "wm5110-codec" }, |
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index 8fefc961ec06..45a20c573aa3 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c | |||
@@ -401,13 +401,19 @@ static const __devinitconst struct reg_default wm1811_reva_patch[] = { | |||
401 | */ | 401 | */ |
402 | static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) | 402 | static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) |
403 | { | 403 | { |
404 | struct wm8994_pdata *pdata = wm8994->dev->platform_data; | 404 | struct wm8994_pdata *pdata; |
405 | struct regmap_config *regmap_config; | 405 | struct regmap_config *regmap_config; |
406 | const struct reg_default *regmap_patch = NULL; | 406 | const struct reg_default *regmap_patch = NULL; |
407 | const char *devname; | 407 | const char *devname; |
408 | int ret, i, patch_regs; | 408 | int ret, i, patch_regs; |
409 | int pulls = 0; | 409 | int pulls = 0; |
410 | 410 | ||
411 | if (dev_get_platdata(wm8994->dev)) { | ||
412 | pdata = dev_get_platdata(wm8994->dev); | ||
413 | wm8994->pdata = *pdata; | ||
414 | } | ||
415 | pdata = &wm8994->pdata; | ||
416 | |||
411 | dev_set_drvdata(wm8994->dev, wm8994); | 417 | dev_set_drvdata(wm8994->dev, wm8994); |
412 | 418 | ||
413 | /* Add the on-chip regulators first for bootstrapping */ | 419 | /* Add the on-chip regulators first for bootstrapping */ |
@@ -604,24 +610,21 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) | |||
604 | } | 610 | } |
605 | } | 611 | } |
606 | 612 | ||
607 | if (pdata) { | 613 | wm8994->irq_base = pdata->irq_base; |
608 | wm8994->irq_base = pdata->irq_base; | 614 | wm8994->gpio_base = pdata->gpio_base; |
609 | wm8994->gpio_base = pdata->gpio_base; | 615 | |
610 | 616 | /* GPIO configuration is only applied if it's non-zero */ | |
611 | /* GPIO configuration is only applied if it's non-zero */ | 617 | for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) { |
612 | for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) { | 618 | if (pdata->gpio_defaults[i]) { |
613 | if (pdata->gpio_defaults[i]) { | 619 | wm8994_set_bits(wm8994, WM8994_GPIO_1 + i, |
614 | wm8994_set_bits(wm8994, WM8994_GPIO_1 + i, | 620 | 0xffff, pdata->gpio_defaults[i]); |
615 | 0xffff, | ||
616 | pdata->gpio_defaults[i]); | ||
617 | } | ||
618 | } | 621 | } |
622 | } | ||
619 | 623 | ||
620 | wm8994->ldo_ena_always_driven = pdata->ldo_ena_always_driven; | 624 | wm8994->ldo_ena_always_driven = pdata->ldo_ena_always_driven; |
621 | 625 | ||
622 | if (pdata->spkmode_pu) | 626 | if (pdata->spkmode_pu) |
623 | pulls |= WM8994_SPKMODE_PU; | 627 | pulls |= WM8994_SPKMODE_PU; |
624 | } | ||
625 | 628 | ||
626 | /* Disable unneeded pulls */ | 629 | /* Disable unneeded pulls */ |
627 | wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2, | 630 | wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2, |
diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c index 5bb187781074..d07a9eda7fff 100644 --- a/drivers/misc/atmel-ssc.c +++ b/drivers/misc/atmel-ssc.c | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | 20 | ||
21 | #include <linux/of.h> | ||
22 | |||
21 | /* Serialize access to ssc_list and user count */ | 23 | /* Serialize access to ssc_list and user count */ |
22 | static DEFINE_SPINLOCK(user_lock); | 24 | static DEFINE_SPINLOCK(user_lock); |
23 | static LIST_HEAD(ssc_list); | 25 | static LIST_HEAD(ssc_list); |
@@ -29,7 +31,13 @@ struct ssc_device *ssc_request(unsigned int ssc_num) | |||
29 | 31 | ||
30 | spin_lock(&user_lock); | 32 | spin_lock(&user_lock); |
31 | list_for_each_entry(ssc, &ssc_list, list) { | 33 | list_for_each_entry(ssc, &ssc_list, list) { |
32 | if (ssc->pdev->id == ssc_num) { | 34 | if (ssc->pdev->dev.of_node) { |
35 | if (of_alias_get_id(ssc->pdev->dev.of_node, "ssc") | ||
36 | == ssc_num) { | ||
37 | ssc_valid = 1; | ||
38 | break; | ||
39 | } | ||
40 | } else if (ssc->pdev->id == ssc_num) { | ||
33 | ssc_valid = 1; | 41 | ssc_valid = 1; |
34 | break; | 42 | break; |
35 | } | 43 | } |
@@ -68,39 +76,93 @@ void ssc_free(struct ssc_device *ssc) | |||
68 | } | 76 | } |
69 | EXPORT_SYMBOL(ssc_free); | 77 | EXPORT_SYMBOL(ssc_free); |
70 | 78 | ||
71 | static int __init ssc_probe(struct platform_device *pdev) | 79 | static struct atmel_ssc_platform_data at91rm9200_config = { |
80 | .use_dma = 0, | ||
81 | }; | ||
82 | |||
83 | static struct atmel_ssc_platform_data at91sam9g45_config = { | ||
84 | .use_dma = 1, | ||
85 | }; | ||
86 | |||
87 | static const struct platform_device_id atmel_ssc_devtypes[] = { | ||
88 | { | ||
89 | .name = "at91rm9200_ssc", | ||
90 | .driver_data = (unsigned long) &at91rm9200_config, | ||
91 | }, { | ||
92 | .name = "at91sam9g45_ssc", | ||
93 | .driver_data = (unsigned long) &at91sam9g45_config, | ||
94 | }, { | ||
95 | /* sentinel */ | ||
96 | } | ||
97 | }; | ||
98 | |||
99 | #ifdef CONFIG_OF | ||
100 | static const struct of_device_id atmel_ssc_dt_ids[] = { | ||
101 | { | ||
102 | .compatible = "atmel,at91rm9200-ssc", | ||
103 | .data = &at91rm9200_config, | ||
104 | }, { | ||
105 | .compatible = "atmel,at91sam9g45-ssc", | ||
106 | .data = &at91sam9g45_config, | ||
107 | }, { | ||
108 | /* sentinel */ | ||
109 | } | ||
110 | }; | ||
111 | MODULE_DEVICE_TABLE(of, atmel_ssc_dt_ids); | ||
112 | #endif | ||
113 | |||
114 | static inline const struct atmel_ssc_platform_data * __init | ||
115 | atmel_ssc_get_driver_data(struct platform_device *pdev) | ||
116 | { | ||
117 | if (pdev->dev.of_node) { | ||
118 | const struct of_device_id *match; | ||
119 | match = of_match_node(atmel_ssc_dt_ids, pdev->dev.of_node); | ||
120 | if (match == NULL) | ||
121 | return NULL; | ||
122 | return match->data; | ||
123 | } | ||
124 | |||
125 | return (struct atmel_ssc_platform_data *) | ||
126 | platform_get_device_id(pdev)->driver_data; | ||
127 | } | ||
128 | |||
129 | static int ssc_probe(struct platform_device *pdev) | ||
72 | { | 130 | { |
73 | int retval = 0; | ||
74 | struct resource *regs; | 131 | struct resource *regs; |
75 | struct ssc_device *ssc; | 132 | struct ssc_device *ssc; |
133 | const struct atmel_ssc_platform_data *plat_dat; | ||
76 | 134 | ||
77 | ssc = kzalloc(sizeof(struct ssc_device), GFP_KERNEL); | 135 | ssc = devm_kzalloc(&pdev->dev, sizeof(struct ssc_device), GFP_KERNEL); |
78 | if (!ssc) { | 136 | if (!ssc) { |
79 | dev_dbg(&pdev->dev, "out of memory\n"); | 137 | dev_dbg(&pdev->dev, "out of memory\n"); |
80 | retval = -ENOMEM; | 138 | return -ENOMEM; |
81 | goto out; | ||
82 | } | 139 | } |
83 | 140 | ||
141 | ssc->pdev = pdev; | ||
142 | |||
143 | plat_dat = atmel_ssc_get_driver_data(pdev); | ||
144 | if (!plat_dat) | ||
145 | return -ENODEV; | ||
146 | ssc->pdata = (struct atmel_ssc_platform_data *)plat_dat; | ||
147 | |||
84 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 148 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
85 | if (!regs) { | 149 | if (!regs) { |
86 | dev_dbg(&pdev->dev, "no mmio resource defined\n"); | 150 | dev_dbg(&pdev->dev, "no mmio resource defined\n"); |
87 | retval = -ENXIO; | 151 | return -ENXIO; |
88 | goto out_free; | ||
89 | } | 152 | } |
90 | 153 | ||
91 | ssc->clk = clk_get(&pdev->dev, "pclk"); | 154 | ssc->regs = devm_request_and_ioremap(&pdev->dev, regs); |
92 | if (IS_ERR(ssc->clk)) { | ||
93 | dev_dbg(&pdev->dev, "no pclk clock defined\n"); | ||
94 | retval = -ENXIO; | ||
95 | goto out_free; | ||
96 | } | ||
97 | |||
98 | ssc->pdev = pdev; | ||
99 | ssc->regs = ioremap(regs->start, resource_size(regs)); | ||
100 | if (!ssc->regs) { | 155 | if (!ssc->regs) { |
101 | dev_dbg(&pdev->dev, "ioremap failed\n"); | 156 | dev_dbg(&pdev->dev, "ioremap failed\n"); |
102 | retval = -EINVAL; | 157 | return -EINVAL; |
103 | goto out_clk; | 158 | } |
159 | |||
160 | ssc->phybase = regs->start; | ||
161 | |||
162 | ssc->clk = devm_clk_get(&pdev->dev, "pclk"); | ||
163 | if (IS_ERR(ssc->clk)) { | ||
164 | dev_dbg(&pdev->dev, "no pclk clock defined\n"); | ||
165 | return -ENXIO; | ||
104 | } | 166 | } |
105 | 167 | ||
106 | /* disable all interrupts */ | 168 | /* disable all interrupts */ |
@@ -112,8 +174,7 @@ static int __init ssc_probe(struct platform_device *pdev) | |||
112 | ssc->irq = platform_get_irq(pdev, 0); | 174 | ssc->irq = platform_get_irq(pdev, 0); |
113 | if (!ssc->irq) { | 175 | if (!ssc->irq) { |
114 | dev_dbg(&pdev->dev, "could not get irq\n"); | 176 | dev_dbg(&pdev->dev, "could not get irq\n"); |
115 | retval = -ENXIO; | 177 | return -ENXIO; |
116 | goto out_unmap; | ||
117 | } | 178 | } |
118 | 179 | ||
119 | spin_lock(&user_lock); | 180 | spin_lock(&user_lock); |
@@ -125,16 +186,7 @@ static int __init ssc_probe(struct platform_device *pdev) | |||
125 | dev_info(&pdev->dev, "Atmel SSC device at 0x%p (irq %d)\n", | 186 | dev_info(&pdev->dev, "Atmel SSC device at 0x%p (irq %d)\n", |
126 | ssc->regs, ssc->irq); | 187 | ssc->regs, ssc->irq); |
127 | 188 | ||
128 | goto out; | 189 | return 0; |
129 | |||
130 | out_unmap: | ||
131 | iounmap(ssc->regs); | ||
132 | out_clk: | ||
133 | clk_put(ssc->clk); | ||
134 | out_free: | ||
135 | kfree(ssc); | ||
136 | out: | ||
137 | return retval; | ||
138 | } | 190 | } |
139 | 191 | ||
140 | static int __devexit ssc_remove(struct platform_device *pdev) | 192 | static int __devexit ssc_remove(struct platform_device *pdev) |
@@ -142,34 +194,23 @@ static int __devexit ssc_remove(struct platform_device *pdev) | |||
142 | struct ssc_device *ssc = platform_get_drvdata(pdev); | 194 | struct ssc_device *ssc = platform_get_drvdata(pdev); |
143 | 195 | ||
144 | spin_lock(&user_lock); | 196 | spin_lock(&user_lock); |
145 | iounmap(ssc->regs); | ||
146 | clk_put(ssc->clk); | ||
147 | list_del(&ssc->list); | 197 | list_del(&ssc->list); |
148 | kfree(ssc); | ||
149 | spin_unlock(&user_lock); | 198 | spin_unlock(&user_lock); |
150 | 199 | ||
151 | return 0; | 200 | return 0; |
152 | } | 201 | } |
153 | 202 | ||
154 | static struct platform_driver ssc_driver = { | 203 | static struct platform_driver ssc_driver = { |
155 | .remove = __devexit_p(ssc_remove), | ||
156 | .driver = { | 204 | .driver = { |
157 | .name = "ssc", | 205 | .name = "ssc", |
158 | .owner = THIS_MODULE, | 206 | .owner = THIS_MODULE, |
207 | .of_match_table = of_match_ptr(atmel_ssc_dt_ids), | ||
159 | }, | 208 | }, |
209 | .id_table = atmel_ssc_devtypes, | ||
210 | .probe = ssc_probe, | ||
211 | .remove = __devexit_p(ssc_remove), | ||
160 | }; | 212 | }; |
161 | 213 | module_platform_driver(ssc_driver); | |
162 | static int __init ssc_init(void) | ||
163 | { | ||
164 | return platform_driver_probe(&ssc_driver, ssc_probe); | ||
165 | } | ||
166 | module_init(ssc_init); | ||
167 | |||
168 | static void __exit ssc_exit(void) | ||
169 | { | ||
170 | platform_driver_unregister(&ssc_driver); | ||
171 | } | ||
172 | module_exit(ssc_exit); | ||
173 | 214 | ||
174 | MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>"); | 215 | MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>"); |
175 | MODULE_DESCRIPTION("SSC driver for Atmel AVR32 and AT91"); | 216 | MODULE_DESCRIPTION("SSC driver for Atmel AVR32 and AT91"); |
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c index 8f52fc858e48..5a5cd2ace4a6 100644 --- a/drivers/mtd/devices/slram.c +++ b/drivers/mtd/devices/slram.c | |||
@@ -240,7 +240,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength) | |||
240 | 240 | ||
241 | if (*(szlength) != '+') { | 241 | if (*(szlength) != '+') { |
242 | devlength = simple_strtoul(szlength, &buffer, 0); | 242 | devlength = simple_strtoul(szlength, &buffer, 0); |
243 | devlength = handle_unit(devlength, buffer) - devstart; | 243 | devlength = handle_unit(devlength, buffer); |
244 | if (devlength < devstart) | 244 | if (devlength < devstart) |
245 | goto err_out; | 245 | goto err_out; |
246 | 246 | ||
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index ec6841d8e956..1a03b7f673ce 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -2983,13 +2983,15 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, | |||
2983 | /* | 2983 | /* |
2984 | * Field definitions are in the following datasheets: | 2984 | * Field definitions are in the following datasheets: |
2985 | * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32) | 2985 | * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32) |
2986 | * New style (6 byte ID): Samsung K9GAG08U0F (p.44) | 2986 | * New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44) |
2987 | * Hynix MLC (6 byte ID): Hynix H27UBG8T2B (p.22) | 2987 | * Hynix MLC (6 byte ID): Hynix H27UBG8T2B (p.22) |
2988 | * | 2988 | * |
2989 | * Check for ID length, cell type, and Hynix/Samsung ID to decide what | 2989 | * Check for ID length, non-zero 6th byte, cell type, and Hynix/Samsung |
2990 | * to do. | 2990 | * ID to decide what to do. |
2991 | */ | 2991 | */ |
2992 | if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG) { | 2992 | if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG && |
2993 | (chip->cellinfo & NAND_CI_CELLTYPE_MSK) && | ||
2994 | id_data[5] != 0x00) { | ||
2993 | /* Calc pagesize */ | 2995 | /* Calc pagesize */ |
2994 | mtd->writesize = 2048 << (extid & 0x03); | 2996 | mtd->writesize = 2048 << (extid & 0x03); |
2995 | extid >>= 2; | 2997 | extid >>= 2; |
diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c index 64be8f0848b0..d9127e2ed808 100644 --- a/drivers/mtd/ofpart.c +++ b/drivers/mtd/ofpart.c | |||
@@ -121,7 +121,7 @@ static int parse_ofoldpart_partitions(struct mtd_info *master, | |||
121 | nr_parts = plen / sizeof(part[0]); | 121 | nr_parts = plen / sizeof(part[0]); |
122 | 122 | ||
123 | *pparts = kzalloc(nr_parts * sizeof(*(*pparts)), GFP_KERNEL); | 123 | *pparts = kzalloc(nr_parts * sizeof(*(*pparts)), GFP_KERNEL); |
124 | if (!pparts) | 124 | if (!*pparts) |
125 | return -ENOMEM; | 125 | return -ENOMEM; |
126 | 126 | ||
127 | names = of_get_property(dp, "partition-names", &plen); | 127 | names = of_get_property(dp, "partition-names", &plen); |
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 7153e0d27101..b3f41f200622 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c | |||
@@ -3694,7 +3694,7 @@ static int flexonenand_check_blocks_erased(struct mtd_info *mtd, int start, int | |||
3694 | * flexonenand_set_boundary - Writes the SLC boundary | 3694 | * flexonenand_set_boundary - Writes the SLC boundary |
3695 | * @param mtd - mtd info structure | 3695 | * @param mtd - mtd info structure |
3696 | */ | 3696 | */ |
3697 | int flexonenand_set_boundary(struct mtd_info *mtd, int die, | 3697 | static int flexonenand_set_boundary(struct mtd_info *mtd, int die, |
3698 | int boundary, int lock) | 3698 | int boundary, int lock) |
3699 | { | 3699 | { |
3700 | struct onenand_chip *this = mtd->priv; | 3700 | struct onenand_chip *this = mtd->priv; |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index b2530b002125..5f5b69f37d2e 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1379,6 +1379,8 @@ static void bond_compute_features(struct bonding *bond) | |||
1379 | struct net_device *bond_dev = bond->dev; | 1379 | struct net_device *bond_dev = bond->dev; |
1380 | netdev_features_t vlan_features = BOND_VLAN_FEATURES; | 1380 | netdev_features_t vlan_features = BOND_VLAN_FEATURES; |
1381 | unsigned short max_hard_header_len = ETH_HLEN; | 1381 | unsigned short max_hard_header_len = ETH_HLEN; |
1382 | unsigned int gso_max_size = GSO_MAX_SIZE; | ||
1383 | u16 gso_max_segs = GSO_MAX_SEGS; | ||
1382 | int i; | 1384 | int i; |
1383 | unsigned int flags, dst_release_flag = IFF_XMIT_DST_RELEASE; | 1385 | unsigned int flags, dst_release_flag = IFF_XMIT_DST_RELEASE; |
1384 | 1386 | ||
@@ -1394,11 +1396,16 @@ static void bond_compute_features(struct bonding *bond) | |||
1394 | dst_release_flag &= slave->dev->priv_flags; | 1396 | dst_release_flag &= slave->dev->priv_flags; |
1395 | if (slave->dev->hard_header_len > max_hard_header_len) | 1397 | if (slave->dev->hard_header_len > max_hard_header_len) |
1396 | max_hard_header_len = slave->dev->hard_header_len; | 1398 | max_hard_header_len = slave->dev->hard_header_len; |
1399 | |||
1400 | gso_max_size = min(gso_max_size, slave->dev->gso_max_size); | ||
1401 | gso_max_segs = min(gso_max_segs, slave->dev->gso_max_segs); | ||
1397 | } | 1402 | } |
1398 | 1403 | ||
1399 | done: | 1404 | done: |
1400 | bond_dev->vlan_features = vlan_features; | 1405 | bond_dev->vlan_features = vlan_features; |
1401 | bond_dev->hard_header_len = max_hard_header_len; | 1406 | bond_dev->hard_header_len = max_hard_header_len; |
1407 | bond_dev->gso_max_segs = gso_max_segs; | ||
1408 | netif_set_gso_max_size(bond_dev, gso_max_size); | ||
1402 | 1409 | ||
1403 | flags = bond_dev->priv_flags & ~IFF_XMIT_DST_RELEASE; | 1410 | flags = bond_dev->priv_flags & ~IFF_XMIT_DST_RELEASE; |
1404 | bond_dev->priv_flags = flags | dst_release_flag; | 1411 | bond_dev->priv_flags = flags | dst_release_flag; |
diff --git a/drivers/net/ethernet/8390/ne.c b/drivers/net/ethernet/8390/ne.c index d04911d33b64..47618e505355 100644 --- a/drivers/net/ethernet/8390/ne.c +++ b/drivers/net/ethernet/8390/ne.c | |||
@@ -813,6 +813,7 @@ static int __init ne_drv_probe(struct platform_device *pdev) | |||
813 | dev->irq = irq[this_dev]; | 813 | dev->irq = irq[this_dev]; |
814 | dev->mem_end = bad[this_dev]; | 814 | dev->mem_end = bad[this_dev]; |
815 | } | 815 | } |
816 | SET_NETDEV_DEV(dev, &pdev->dev); | ||
816 | err = do_ne_probe(dev); | 817 | err = do_ne_probe(dev); |
817 | if (err) { | 818 | if (err) { |
818 | free_netdev(dev); | 819 | free_netdev(dev); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index bd1fd3d87c24..01611b33a93d 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
@@ -9545,10 +9545,13 @@ static int __devinit bnx2x_prev_unload_common(struct bnx2x *bp) | |||
9545 | */ | 9545 | */ |
9546 | static void __devinit bnx2x_prev_interrupted_dmae(struct bnx2x *bp) | 9546 | static void __devinit bnx2x_prev_interrupted_dmae(struct bnx2x *bp) |
9547 | { | 9547 | { |
9548 | u32 val = REG_RD(bp, PGLUE_B_REG_PGLUE_B_INT_STS); | 9548 | if (!CHIP_IS_E1x(bp)) { |
9549 | if (val & PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN) { | 9549 | u32 val = REG_RD(bp, PGLUE_B_REG_PGLUE_B_INT_STS); |
9550 | BNX2X_ERR("was error bit was found to be set in pglueb upon startup. Clearing"); | 9550 | if (val & PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN) { |
9551 | REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR, 1 << BP_FUNC(bp)); | 9551 | BNX2X_ERR("was error bit was found to be set in pglueb upon startup. Clearing"); |
9552 | REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR, | ||
9553 | 1 << BP_FUNC(bp)); | ||
9554 | } | ||
9552 | } | 9555 | } |
9553 | } | 9556 | } |
9554 | 9557 | ||
diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c index 1c818254b7be..b01f83a044c4 100644 --- a/drivers/net/ethernet/realtek/8139cp.c +++ b/drivers/net/ethernet/realtek/8139cp.c | |||
@@ -979,17 +979,6 @@ static void cp_init_hw (struct cp_private *cp) | |||
979 | cpw32_f (MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0))); | 979 | cpw32_f (MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0))); |
980 | cpw32_f (MAC0 + 4, le32_to_cpu (*(__le32 *) (dev->dev_addr + 4))); | 980 | cpw32_f (MAC0 + 4, le32_to_cpu (*(__le32 *) (dev->dev_addr + 4))); |
981 | 981 | ||
982 | cpw32_f(HiTxRingAddr, 0); | ||
983 | cpw32_f(HiTxRingAddr + 4, 0); | ||
984 | |||
985 | ring_dma = cp->ring_dma; | ||
986 | cpw32_f(RxRingAddr, ring_dma & 0xffffffff); | ||
987 | cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16); | ||
988 | |||
989 | ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE; | ||
990 | cpw32_f(TxRingAddr, ring_dma & 0xffffffff); | ||
991 | cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16); | ||
992 | |||
993 | cp_start_hw(cp); | 982 | cp_start_hw(cp); |
994 | cpw8(TxThresh, 0x06); /* XXX convert magic num to a constant */ | 983 | cpw8(TxThresh, 0x06); /* XXX convert magic num to a constant */ |
995 | 984 | ||
@@ -1003,6 +992,17 @@ static void cp_init_hw (struct cp_private *cp) | |||
1003 | 992 | ||
1004 | cpw8(Config5, cpr8(Config5) & PMEStatus); | 993 | cpw8(Config5, cpr8(Config5) & PMEStatus); |
1005 | 994 | ||
995 | cpw32_f(HiTxRingAddr, 0); | ||
996 | cpw32_f(HiTxRingAddr + 4, 0); | ||
997 | |||
998 | ring_dma = cp->ring_dma; | ||
999 | cpw32_f(RxRingAddr, ring_dma & 0xffffffff); | ||
1000 | cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16); | ||
1001 | |||
1002 | ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE; | ||
1003 | cpw32_f(TxRingAddr, ring_dma & 0xffffffff); | ||
1004 | cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16); | ||
1005 | |||
1006 | cpw16(MultiIntr, 0); | 1006 | cpw16(MultiIntr, 0); |
1007 | 1007 | ||
1008 | cpw8_f(Cfg9346, Cfg9346_Lock); | 1008 | cpw8_f(Cfg9346, Cfg9346_Lock); |
diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c index fb9f6b38511f..edf5edb13140 100644 --- a/drivers/net/ethernet/sis/sis900.c +++ b/drivers/net/ethernet/sis/sis900.c | |||
@@ -2479,7 +2479,7 @@ static int sis900_resume(struct pci_dev *pci_dev) | |||
2479 | netif_start_queue(net_dev); | 2479 | netif_start_queue(net_dev); |
2480 | 2480 | ||
2481 | /* Workaround for EDB */ | 2481 | /* Workaround for EDB */ |
2482 | sis900_set_mode(ioaddr, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED); | 2482 | sis900_set_mode(sis_priv, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED); |
2483 | 2483 | ||
2484 | /* Enable all known interrupts by setting the interrupt mask. */ | 2484 | /* Enable all known interrupts by setting the interrupt mask. */ |
2485 | sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE); | 2485 | sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE); |
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 77e6db9dcfed..a788501e978e 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c | |||
@@ -894,6 +894,8 @@ out: | |||
894 | return IRQ_HANDLED; | 894 | return IRQ_HANDLED; |
895 | } | 895 | } |
896 | 896 | ||
897 | static void axienet_dma_err_handler(unsigned long data); | ||
898 | |||
897 | /** | 899 | /** |
898 | * axienet_open - Driver open routine. | 900 | * axienet_open - Driver open routine. |
899 | * @ndev: Pointer to net_device structure | 901 | * @ndev: Pointer to net_device structure |
diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c index 98934bdf6acf..477d6729b17f 100644 --- a/drivers/net/ethernet/xscale/ixp4xx_eth.c +++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c | |||
@@ -1102,10 +1102,12 @@ static int init_queues(struct port *port) | |||
1102 | { | 1102 | { |
1103 | int i; | 1103 | int i; |
1104 | 1104 | ||
1105 | if (!ports_open) | 1105 | if (!ports_open) { |
1106 | if (!(dma_pool = dma_pool_create(DRV_NAME, NULL, | 1106 | dma_pool = dma_pool_create(DRV_NAME, &port->netdev->dev, |
1107 | POOL_ALLOC_SIZE, 32, 0))) | 1107 | POOL_ALLOC_SIZE, 32, 0); |
1108 | if (!dma_pool) | ||
1108 | return -ENOMEM; | 1109 | return -ENOMEM; |
1110 | } | ||
1109 | 1111 | ||
1110 | if (!(port->desc_tab = dma_pool_alloc(dma_pool, GFP_KERNEL, | 1112 | if (!(port->desc_tab = dma_pool_alloc(dma_pool, GFP_KERNEL, |
1111 | &port->desc_tab_phys))) | 1113 | &port->desc_tab_phys))) |
diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c index 5039f08f5a5b..43e9ab4f4d7e 100644 --- a/drivers/net/irda/sir_dev.c +++ b/drivers/net/irda/sir_dev.c | |||
@@ -222,7 +222,7 @@ static void sirdev_config_fsm(struct work_struct *work) | |||
222 | break; | 222 | break; |
223 | 223 | ||
224 | case SIRDEV_STATE_DONGLE_SPEED: | 224 | case SIRDEV_STATE_DONGLE_SPEED: |
225 | if (dev->dongle_drv->reset) { | 225 | if (dev->dongle_drv->set_speed) { |
226 | ret = dev->dongle_drv->set_speed(dev, fsm->param); | 226 | ret = dev->dongle_drv->set_speed(dev, fsm->param); |
227 | if (ret < 0) { | 227 | if (ret < 0) { |
228 | fsm->result = ret; | 228 | fsm->result = ret; |
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index 899274f2f9b1..2ed1140df3e9 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c | |||
@@ -185,17 +185,20 @@ static int __devinit mdio_gpio_probe(struct platform_device *pdev) | |||
185 | { | 185 | { |
186 | struct mdio_gpio_platform_data *pdata; | 186 | struct mdio_gpio_platform_data *pdata; |
187 | struct mii_bus *new_bus; | 187 | struct mii_bus *new_bus; |
188 | int ret; | 188 | int ret, bus_id; |
189 | 189 | ||
190 | if (pdev->dev.of_node) | 190 | if (pdev->dev.of_node) { |
191 | pdata = mdio_gpio_of_get_data(pdev); | 191 | pdata = mdio_gpio_of_get_data(pdev); |
192 | else | 192 | bus_id = of_alias_get_id(pdev->dev.of_node, "mdio-gpio"); |
193 | } else { | ||
193 | pdata = pdev->dev.platform_data; | 194 | pdata = pdev->dev.platform_data; |
195 | bus_id = pdev->id; | ||
196 | } | ||
194 | 197 | ||
195 | if (!pdata) | 198 | if (!pdata) |
196 | return -ENODEV; | 199 | return -ENODEV; |
197 | 200 | ||
198 | new_bus = mdio_gpio_bus_init(&pdev->dev, pdata, pdev->id); | 201 | new_bus = mdio_gpio_bus_init(&pdev->dev, pdata, bus_id); |
199 | if (!new_bus) | 202 | if (!new_bus) |
200 | return -ENODEV; | 203 | return -ENODEV; |
201 | 204 | ||
diff --git a/drivers/net/team/team_mode_broadcast.c b/drivers/net/team/team_mode_broadcast.c index 9db0171e9366..c5db428e73fa 100644 --- a/drivers/net/team/team_mode_broadcast.c +++ b/drivers/net/team/team_mode_broadcast.c | |||
@@ -29,8 +29,8 @@ static bool bc_transmit(struct team *team, struct sk_buff *skb) | |||
29 | if (last) { | 29 | if (last) { |
30 | skb2 = skb_clone(skb, GFP_ATOMIC); | 30 | skb2 = skb_clone(skb, GFP_ATOMIC); |
31 | if (skb2) { | 31 | if (skb2) { |
32 | ret = team_dev_queue_xmit(team, last, | 32 | ret = !team_dev_queue_xmit(team, last, |
33 | skb2); | 33 | skb2); |
34 | if (!sum_ret) | 34 | if (!sum_ret) |
35 | sum_ret = ret; | 35 | sum_ret = ret; |
36 | } | 36 | } |
@@ -39,7 +39,7 @@ static bool bc_transmit(struct team *team, struct sk_buff *skb) | |||
39 | } | 39 | } |
40 | } | 40 | } |
41 | if (last) { | 41 | if (last) { |
42 | ret = team_dev_queue_xmit(team, last, skb); | 42 | ret = !team_dev_queue_xmit(team, last, skb); |
43 | if (!sum_ret) | 43 | if (!sum_ret) |
44 | sum_ret = ret; | 44 | sum_ret = ret; |
45 | } | 45 | } |
diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c index 3f575afd8cfc..e9a3da588e95 100644 --- a/drivers/net/wan/ixp4xx_hss.c +++ b/drivers/net/wan/ixp4xx_hss.c | |||
@@ -969,10 +969,12 @@ static int init_hdlc_queues(struct port *port) | |||
969 | { | 969 | { |
970 | int i; | 970 | int i; |
971 | 971 | ||
972 | if (!ports_open) | 972 | if (!ports_open) { |
973 | if (!(dma_pool = dma_pool_create(DRV_NAME, NULL, | 973 | dma_pool = dma_pool_create(DRV_NAME, &port->netdev->dev, |
974 | POOL_ALLOC_SIZE, 32, 0))) | 974 | POOL_ALLOC_SIZE, 32, 0); |
975 | if (!dma_pool) | ||
975 | return -ENOMEM; | 976 | return -ENOMEM; |
977 | } | ||
976 | 978 | ||
977 | if (!(port->desc_tab = dma_pool_alloc(dma_pool, GFP_KERNEL, | 979 | if (!(port->desc_tab = dma_pool_alloc(dma_pool, GFP_KERNEL, |
978 | &port->desc_tab_phys))) | 980 | &port->desc_tab_phys))) |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 8e1559aba495..1829b445d0b0 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -1456,7 +1456,7 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type) | |||
1456 | switch (type) { | 1456 | switch (type) { |
1457 | case ATH9K_RESET_POWER_ON: | 1457 | case ATH9K_RESET_POWER_ON: |
1458 | ret = ath9k_hw_set_reset_power_on(ah); | 1458 | ret = ath9k_hw_set_reset_power_on(ah); |
1459 | if (!ret) | 1459 | if (ret) |
1460 | ah->reset_power_on = true; | 1460 | ah->reset_power_on = true; |
1461 | break; | 1461 | break; |
1462 | case ATH9K_RESET_WARM: | 1462 | case ATH9K_RESET_WARM: |
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index fa4d1b8cd9f6..2d9eee93c743 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c | |||
@@ -1354,6 +1354,20 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, | |||
1354 | vif_priv->ctx = ctx; | 1354 | vif_priv->ctx = ctx; |
1355 | ctx->vif = vif; | 1355 | ctx->vif = vif; |
1356 | 1356 | ||
1357 | /* | ||
1358 | * In SNIFFER device type, the firmware reports the FCS to | ||
1359 | * the host, rather than snipping it off. Unfortunately, | ||
1360 | * mac80211 doesn't (yet) provide a per-packet flag for | ||
1361 | * this, so that we have to set the hardware flag based | ||
1362 | * on the interfaces added. As the monitor interface can | ||
1363 | * only be present by itself, and will be removed before | ||
1364 | * other interfaces are added, this is safe. | ||
1365 | */ | ||
1366 | if (vif->type == NL80211_IFTYPE_MONITOR) | ||
1367 | priv->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS; | ||
1368 | else | ||
1369 | priv->hw->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS; | ||
1370 | |||
1357 | err = iwl_setup_interface(priv, ctx); | 1371 | err = iwl_setup_interface(priv, ctx); |
1358 | if (!err || reset) | 1372 | if (!err || reset) |
1359 | goto out; | 1373 | goto out; |
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 105e3af3c621..79a4ddc002d3 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c | |||
@@ -480,20 +480,12 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, | |||
480 | void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) | 480 | void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) |
481 | { | 481 | { |
482 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 482 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
483 | u16 rd_ptr, wr_ptr; | ||
484 | int n_bd = trans_pcie->txq[txq_id].q.n_bd; | ||
485 | 483 | ||
486 | if (!test_and_clear_bit(txq_id, trans_pcie->queue_used)) { | 484 | if (!test_and_clear_bit(txq_id, trans_pcie->queue_used)) { |
487 | WARN_ONCE(1, "queue %d not used", txq_id); | 485 | WARN_ONCE(1, "queue %d not used", txq_id); |
488 | return; | 486 | return; |
489 | } | 487 | } |
490 | 488 | ||
491 | rd_ptr = iwl_read_prph(trans, SCD_QUEUE_RDPTR(txq_id)) & (n_bd - 1); | ||
492 | wr_ptr = iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq_id)); | ||
493 | |||
494 | WARN_ONCE(rd_ptr != wr_ptr, "queue %d isn't empty: [%d,%d]", | ||
495 | txq_id, rd_ptr, wr_ptr); | ||
496 | |||
497 | iwl_txq_set_inactive(trans, txq_id); | 489 | iwl_txq_set_inactive(trans, txq_id); |
498 | IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id); | 490 | IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id); |
499 | } | 491 | } |
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index 8d465107f52b..ae9010ed58de 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c | |||
@@ -890,9 +890,6 @@ mwifiex_cmd_timeout_func(unsigned long function_context) | |||
890 | return; | 890 | return; |
891 | } | 891 | } |
892 | cmd_node = adapter->curr_cmd; | 892 | cmd_node = adapter->curr_cmd; |
893 | if (cmd_node->wait_q_enabled) | ||
894 | adapter->cmd_wait_q.status = -ETIMEDOUT; | ||
895 | |||
896 | if (cmd_node) { | 893 | if (cmd_node) { |
897 | adapter->dbg.timeout_cmd_id = | 894 | adapter->dbg.timeout_cmd_id = |
898 | adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index]; | 895 | adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index]; |
@@ -938,6 +935,14 @@ mwifiex_cmd_timeout_func(unsigned long function_context) | |||
938 | 935 | ||
939 | dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n", | 936 | dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n", |
940 | adapter->ps_mode, adapter->ps_state); | 937 | adapter->ps_mode, adapter->ps_state); |
938 | |||
939 | if (cmd_node->wait_q_enabled) { | ||
940 | adapter->cmd_wait_q.status = -ETIMEDOUT; | ||
941 | wake_up_interruptible(&adapter->cmd_wait_q.wait); | ||
942 | mwifiex_cancel_pending_ioctl(adapter); | ||
943 | /* reset cmd_sent flag to unblock new commands */ | ||
944 | adapter->cmd_sent = false; | ||
945 | } | ||
941 | } | 946 | } |
942 | if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) | 947 | if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) |
943 | mwifiex_init_fw_complete(adapter); | 948 | mwifiex_init_fw_complete(adapter); |
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index fc8a9bfa1248..82cf0fa2d9f6 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c | |||
@@ -161,7 +161,6 @@ static int mwifiex_sdio_suspend(struct device *dev) | |||
161 | struct sdio_mmc_card *card; | 161 | struct sdio_mmc_card *card; |
162 | struct mwifiex_adapter *adapter; | 162 | struct mwifiex_adapter *adapter; |
163 | mmc_pm_flag_t pm_flag = 0; | 163 | mmc_pm_flag_t pm_flag = 0; |
164 | int hs_actived = 0; | ||
165 | int i; | 164 | int i; |
166 | int ret = 0; | 165 | int ret = 0; |
167 | 166 | ||
@@ -188,12 +187,14 @@ static int mwifiex_sdio_suspend(struct device *dev) | |||
188 | adapter = card->adapter; | 187 | adapter = card->adapter; |
189 | 188 | ||
190 | /* Enable the Host Sleep */ | 189 | /* Enable the Host Sleep */ |
191 | hs_actived = mwifiex_enable_hs(adapter); | 190 | if (!mwifiex_enable_hs(adapter)) { |
192 | if (hs_actived) { | 191 | dev_err(adapter->dev, "cmd: failed to suspend\n"); |
193 | pr_debug("cmd: suspend with MMC_PM_KEEP_POWER\n"); | 192 | return -EFAULT; |
194 | ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); | ||
195 | } | 193 | } |
196 | 194 | ||
195 | dev_dbg(adapter->dev, "cmd: suspend with MMC_PM_KEEP_POWER\n"); | ||
196 | ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); | ||
197 | |||
197 | /* Indicate device suspended */ | 198 | /* Indicate device suspended */ |
198 | adapter->is_suspended = true; | 199 | adapter->is_suspended = true; |
199 | 200 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index 9970c2b1b199..b7e6607e6b6d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | |||
@@ -297,6 +297,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = { | |||
297 | /*=== Customer ID ===*/ | 297 | /*=== Customer ID ===*/ |
298 | /****** 8188CU ********/ | 298 | /****** 8188CU ********/ |
299 | {RTL_USB_DEVICE(0x050d, 0x1102, rtl92cu_hal_cfg)}, /*Belkin - Edimax*/ | 299 | {RTL_USB_DEVICE(0x050d, 0x1102, rtl92cu_hal_cfg)}, /*Belkin - Edimax*/ |
300 | {RTL_USB_DEVICE(0x050d, 0x11f2, rtl92cu_hal_cfg)}, /*Belkin - ISY*/ | ||
300 | {RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/ | 301 | {RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/ |
301 | {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ | 302 | {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ |
302 | {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ | 303 | {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ |
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index caa011008cd0..fc24eb9b3948 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
@@ -452,29 +452,85 @@ static void xennet_make_frags(struct sk_buff *skb, struct net_device *dev, | |||
452 | /* Grant backend access to each skb fragment page. */ | 452 | /* Grant backend access to each skb fragment page. */ |
453 | for (i = 0; i < frags; i++) { | 453 | for (i = 0; i < frags; i++) { |
454 | skb_frag_t *frag = skb_shinfo(skb)->frags + i; | 454 | skb_frag_t *frag = skb_shinfo(skb)->frags + i; |
455 | struct page *page = skb_frag_page(frag); | ||
455 | 456 | ||
456 | tx->flags |= XEN_NETTXF_more_data; | 457 | len = skb_frag_size(frag); |
458 | offset = frag->page_offset; | ||
457 | 459 | ||
458 | id = get_id_from_freelist(&np->tx_skb_freelist, np->tx_skbs); | 460 | /* Data must not cross a page boundary. */ |
459 | np->tx_skbs[id].skb = skb_get(skb); | 461 | BUG_ON(len + offset > PAGE_SIZE<<compound_order(page)); |
460 | tx = RING_GET_REQUEST(&np->tx, prod++); | ||
461 | tx->id = id; | ||
462 | ref = gnttab_claim_grant_reference(&np->gref_tx_head); | ||
463 | BUG_ON((signed short)ref < 0); | ||
464 | 462 | ||
465 | mfn = pfn_to_mfn(page_to_pfn(skb_frag_page(frag))); | 463 | /* Skip unused frames from start of page */ |
466 | gnttab_grant_foreign_access_ref(ref, np->xbdev->otherend_id, | 464 | page += offset >> PAGE_SHIFT; |
467 | mfn, GNTMAP_readonly); | 465 | offset &= ~PAGE_MASK; |
468 | 466 | ||
469 | tx->gref = np->grant_tx_ref[id] = ref; | 467 | while (len > 0) { |
470 | tx->offset = frag->page_offset; | 468 | unsigned long bytes; |
471 | tx->size = skb_frag_size(frag); | 469 | |
472 | tx->flags = 0; | 470 | BUG_ON(offset >= PAGE_SIZE); |
471 | |||
472 | bytes = PAGE_SIZE - offset; | ||
473 | if (bytes > len) | ||
474 | bytes = len; | ||
475 | |||
476 | tx->flags |= XEN_NETTXF_more_data; | ||
477 | |||
478 | id = get_id_from_freelist(&np->tx_skb_freelist, | ||
479 | np->tx_skbs); | ||
480 | np->tx_skbs[id].skb = skb_get(skb); | ||
481 | tx = RING_GET_REQUEST(&np->tx, prod++); | ||
482 | tx->id = id; | ||
483 | ref = gnttab_claim_grant_reference(&np->gref_tx_head); | ||
484 | BUG_ON((signed short)ref < 0); | ||
485 | |||
486 | mfn = pfn_to_mfn(page_to_pfn(page)); | ||
487 | gnttab_grant_foreign_access_ref(ref, | ||
488 | np->xbdev->otherend_id, | ||
489 | mfn, GNTMAP_readonly); | ||
490 | |||
491 | tx->gref = np->grant_tx_ref[id] = ref; | ||
492 | tx->offset = offset; | ||
493 | tx->size = bytes; | ||
494 | tx->flags = 0; | ||
495 | |||
496 | offset += bytes; | ||
497 | len -= bytes; | ||
498 | |||
499 | /* Next frame */ | ||
500 | if (offset == PAGE_SIZE && len) { | ||
501 | BUG_ON(!PageCompound(page)); | ||
502 | page++; | ||
503 | offset = 0; | ||
504 | } | ||
505 | } | ||
473 | } | 506 | } |
474 | 507 | ||
475 | np->tx.req_prod_pvt = prod; | 508 | np->tx.req_prod_pvt = prod; |
476 | } | 509 | } |
477 | 510 | ||
511 | /* | ||
512 | * Count how many ring slots are required to send the frags of this | ||
513 | * skb. Each frag might be a compound page. | ||
514 | */ | ||
515 | static int xennet_count_skb_frag_slots(struct sk_buff *skb) | ||
516 | { | ||
517 | int i, frags = skb_shinfo(skb)->nr_frags; | ||
518 | int pages = 0; | ||
519 | |||
520 | for (i = 0; i < frags; i++) { | ||
521 | skb_frag_t *frag = skb_shinfo(skb)->frags + i; | ||
522 | unsigned long size = skb_frag_size(frag); | ||
523 | unsigned long offset = frag->page_offset; | ||
524 | |||
525 | /* Skip unused frames from start of page */ | ||
526 | offset &= ~PAGE_MASK; | ||
527 | |||
528 | pages += PFN_UP(offset + size); | ||
529 | } | ||
530 | |||
531 | return pages; | ||
532 | } | ||
533 | |||
478 | static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) | 534 | static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) |
479 | { | 535 | { |
480 | unsigned short id; | 536 | unsigned short id; |
@@ -487,23 +543,23 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
487 | grant_ref_t ref; | 543 | grant_ref_t ref; |
488 | unsigned long mfn; | 544 | unsigned long mfn; |
489 | int notify; | 545 | int notify; |
490 | int frags = skb_shinfo(skb)->nr_frags; | 546 | int slots; |
491 | unsigned int offset = offset_in_page(data); | 547 | unsigned int offset = offset_in_page(data); |
492 | unsigned int len = skb_headlen(skb); | 548 | unsigned int len = skb_headlen(skb); |
493 | unsigned long flags; | 549 | unsigned long flags; |
494 | 550 | ||
495 | frags += DIV_ROUND_UP(offset + len, PAGE_SIZE); | 551 | slots = DIV_ROUND_UP(offset + len, PAGE_SIZE) + |
496 | if (unlikely(frags > MAX_SKB_FRAGS + 1)) { | 552 | xennet_count_skb_frag_slots(skb); |
497 | printk(KERN_ALERT "xennet: skb rides the rocket: %d frags\n", | 553 | if (unlikely(slots > MAX_SKB_FRAGS + 1)) { |
498 | frags); | 554 | net_alert_ratelimited( |
499 | dump_stack(); | 555 | "xennet: skb rides the rocket: %d slots\n", slots); |
500 | goto drop; | 556 | goto drop; |
501 | } | 557 | } |
502 | 558 | ||
503 | spin_lock_irqsave(&np->tx_lock, flags); | 559 | spin_lock_irqsave(&np->tx_lock, flags); |
504 | 560 | ||
505 | if (unlikely(!netif_carrier_ok(dev) || | 561 | if (unlikely(!netif_carrier_ok(dev) || |
506 | (frags > 1 && !xennet_can_sg(dev)) || | 562 | (slots > 1 && !xennet_can_sg(dev)) || |
507 | netif_needs_gso(skb, netif_skb_features(skb)))) { | 563 | netif_needs_gso(skb, netif_skb_features(skb)))) { |
508 | spin_unlock_irqrestore(&np->tx_lock, flags); | 564 | spin_unlock_irqrestore(&np->tx_lock, flags); |
509 | goto drop; | 565 | goto drop; |
diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 97c440a8cd61..30ae18a03a9c 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c | |||
@@ -698,13 +698,14 @@ static void pn533_wq_cmd(struct work_struct *work) | |||
698 | 698 | ||
699 | cmd = list_first_entry(&dev->cmd_queue, struct pn533_cmd, queue); | 699 | cmd = list_first_entry(&dev->cmd_queue, struct pn533_cmd, queue); |
700 | 700 | ||
701 | list_del(&cmd->queue); | ||
702 | |||
701 | mutex_unlock(&dev->cmd_lock); | 703 | mutex_unlock(&dev->cmd_lock); |
702 | 704 | ||
703 | __pn533_send_cmd_frame_async(dev, cmd->out_frame, cmd->in_frame, | 705 | __pn533_send_cmd_frame_async(dev, cmd->out_frame, cmd->in_frame, |
704 | cmd->in_frame_len, cmd->cmd_complete, | 706 | cmd->in_frame_len, cmd->cmd_complete, |
705 | cmd->arg, cmd->flags); | 707 | cmd->arg, cmd->flags); |
706 | 708 | ||
707 | list_del(&cmd->queue); | ||
708 | kfree(cmd); | 709 | kfree(cmd); |
709 | } | 710 | } |
710 | 711 | ||
@@ -1678,11 +1679,14 @@ static void pn533_deactivate_target(struct nfc_dev *nfc_dev, | |||
1678 | static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, | 1679 | static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, |
1679 | u8 *params, int params_len) | 1680 | u8 *params, int params_len) |
1680 | { | 1681 | { |
1681 | struct pn533_cmd_jump_dep *cmd; | ||
1682 | struct pn533_cmd_jump_dep_response *resp; | 1682 | struct pn533_cmd_jump_dep_response *resp; |
1683 | struct nfc_target nfc_target; | 1683 | struct nfc_target nfc_target; |
1684 | u8 target_gt_len; | 1684 | u8 target_gt_len; |
1685 | int rc; | 1685 | int rc; |
1686 | struct pn533_cmd_jump_dep *cmd = (struct pn533_cmd_jump_dep *)arg; | ||
1687 | u8 active = cmd->active; | ||
1688 | |||
1689 | kfree(arg); | ||
1686 | 1690 | ||
1687 | if (params_len == -ENOENT) { | 1691 | if (params_len == -ENOENT) { |
1688 | nfc_dev_dbg(&dev->interface->dev, ""); | 1692 | nfc_dev_dbg(&dev->interface->dev, ""); |
@@ -1704,7 +1708,6 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, | |||
1704 | } | 1708 | } |
1705 | 1709 | ||
1706 | resp = (struct pn533_cmd_jump_dep_response *) params; | 1710 | resp = (struct pn533_cmd_jump_dep_response *) params; |
1707 | cmd = (struct pn533_cmd_jump_dep *) arg; | ||
1708 | rc = resp->status & PN533_CMD_RET_MASK; | 1711 | rc = resp->status & PN533_CMD_RET_MASK; |
1709 | if (rc != PN533_CMD_RET_SUCCESS) { | 1712 | if (rc != PN533_CMD_RET_SUCCESS) { |
1710 | nfc_dev_err(&dev->interface->dev, | 1713 | nfc_dev_err(&dev->interface->dev, |
@@ -1734,7 +1737,7 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, | |||
1734 | if (rc == 0) | 1737 | if (rc == 0) |
1735 | rc = nfc_dep_link_is_up(dev->nfc_dev, | 1738 | rc = nfc_dep_link_is_up(dev->nfc_dev, |
1736 | dev->nfc_dev->targets[0].idx, | 1739 | dev->nfc_dev->targets[0].idx, |
1737 | !cmd->active, NFC_RF_INITIATOR); | 1740 | !active, NFC_RF_INITIATOR); |
1738 | 1741 | ||
1739 | return 0; | 1742 | return 0; |
1740 | } | 1743 | } |
@@ -1819,12 +1822,8 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target, | |||
1819 | rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame, | 1822 | rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame, |
1820 | dev->in_maxlen, pn533_in_dep_link_up_complete, | 1823 | dev->in_maxlen, pn533_in_dep_link_up_complete, |
1821 | cmd, GFP_KERNEL); | 1824 | cmd, GFP_KERNEL); |
1822 | if (rc) | 1825 | if (rc < 0) |
1823 | goto out; | 1826 | kfree(cmd); |
1824 | |||
1825 | |||
1826 | out: | ||
1827 | kfree(cmd); | ||
1828 | 1827 | ||
1829 | return rc; | 1828 | return rc; |
1830 | } | 1829 | } |
@@ -2078,8 +2077,12 @@ error: | |||
2078 | static int pn533_tm_send_complete(struct pn533 *dev, void *arg, | 2077 | static int pn533_tm_send_complete(struct pn533 *dev, void *arg, |
2079 | u8 *params, int params_len) | 2078 | u8 *params, int params_len) |
2080 | { | 2079 | { |
2080 | struct sk_buff *skb_out = arg; | ||
2081 | |||
2081 | nfc_dev_dbg(&dev->interface->dev, "%s", __func__); | 2082 | nfc_dev_dbg(&dev->interface->dev, "%s", __func__); |
2082 | 2083 | ||
2084 | dev_kfree_skb(skb_out); | ||
2085 | |||
2083 | if (params_len < 0) { | 2086 | if (params_len < 0) { |
2084 | nfc_dev_err(&dev->interface->dev, | 2087 | nfc_dev_err(&dev->interface->dev, |
2085 | "Error %d when sending data", | 2088 | "Error %d when sending data", |
@@ -2117,7 +2120,7 @@ static int pn533_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb) | |||
2117 | 2120 | ||
2118 | rc = pn533_send_cmd_frame_async(dev, out_frame, dev->in_frame, | 2121 | rc = pn533_send_cmd_frame_async(dev, out_frame, dev->in_frame, |
2119 | dev->in_maxlen, pn533_tm_send_complete, | 2122 | dev->in_maxlen, pn533_tm_send_complete, |
2120 | NULL, GFP_KERNEL); | 2123 | skb, GFP_KERNEL); |
2121 | if (rc) { | 2124 | if (rc) { |
2122 | nfc_dev_err(&dev->interface->dev, | 2125 | nfc_dev_err(&dev->interface->dev, |
2123 | "Error %d when trying to send data", rc); | 2126 | "Error %d when trying to send data", rc); |
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index d96caefd914a..aeecf0f72cad 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig | |||
@@ -178,7 +178,7 @@ config PINCTRL_COH901 | |||
178 | ports of 8 GPIO pins each. | 178 | ports of 8 GPIO pins each. |
179 | 179 | ||
180 | config PINCTRL_SAMSUNG | 180 | config PINCTRL_SAMSUNG |
181 | bool "Samsung pinctrl driver" | 181 | bool |
182 | depends on OF && GPIOLIB | 182 | depends on OF && GPIOLIB |
183 | select PINMUX | 183 | select PINMUX |
184 | select PINCONF | 184 | select PINCONF |
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index c1bafc3f3fb1..9594ab62702b 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c | |||
@@ -1972,7 +1972,7 @@ sci_io_request_frame_handler(struct isci_request *ireq, | |||
1972 | frame_index, | 1972 | frame_index, |
1973 | (void **)&frame_buffer); | 1973 | (void **)&frame_buffer); |
1974 | 1974 | ||
1975 | sci_controller_copy_sata_response(&ireq->stp.req, | 1975 | sci_controller_copy_sata_response(&ireq->stp.rsp, |
1976 | frame_header, | 1976 | frame_header, |
1977 | frame_buffer); | 1977 | frame_buffer); |
1978 | 1978 | ||
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 2936b447cae9..2c0d0ec8150b 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
@@ -55,6 +55,7 @@ | |||
55 | #include <linux/cpu.h> | 55 | #include <linux/cpu.h> |
56 | #include <linux/mutex.h> | 56 | #include <linux/mutex.h> |
57 | #include <linux/async.h> | 57 | #include <linux/async.h> |
58 | #include <asm/unaligned.h> | ||
58 | 59 | ||
59 | #include <scsi/scsi.h> | 60 | #include <scsi/scsi.h> |
60 | #include <scsi/scsi_cmnd.h> | 61 | #include <scsi/scsi_cmnd.h> |
@@ -1062,6 +1063,50 @@ int scsi_get_vpd_page(struct scsi_device *sdev, u8 page, unsigned char *buf, | |||
1062 | EXPORT_SYMBOL_GPL(scsi_get_vpd_page); | 1063 | EXPORT_SYMBOL_GPL(scsi_get_vpd_page); |
1063 | 1064 | ||
1064 | /** | 1065 | /** |
1066 | * scsi_report_opcode - Find out if a given command opcode is supported | ||
1067 | * @sdev: scsi device to query | ||
1068 | * @buffer: scratch buffer (must be at least 20 bytes long) | ||
1069 | * @len: length of buffer | ||
1070 | * @opcode: opcode for command to look up | ||
1071 | * | ||
1072 | * Uses the REPORT SUPPORTED OPERATION CODES to look up the given | ||
1073 | * opcode. Returns 0 if RSOC fails or if the command opcode is | ||
1074 | * unsupported. Returns 1 if the device claims to support the command. | ||
1075 | */ | ||
1076 | int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer, | ||
1077 | unsigned int len, unsigned char opcode) | ||
1078 | { | ||
1079 | unsigned char cmd[16]; | ||
1080 | struct scsi_sense_hdr sshdr; | ||
1081 | int result; | ||
1082 | |||
1083 | if (sdev->no_report_opcodes || sdev->scsi_level < SCSI_SPC_3) | ||
1084 | return 0; | ||
1085 | |||
1086 | memset(cmd, 0, 16); | ||
1087 | cmd[0] = MAINTENANCE_IN; | ||
1088 | cmd[1] = MI_REPORT_SUPPORTED_OPERATION_CODES; | ||
1089 | cmd[2] = 1; /* One command format */ | ||
1090 | cmd[3] = opcode; | ||
1091 | put_unaligned_be32(len, &cmd[6]); | ||
1092 | memset(buffer, 0, len); | ||
1093 | |||
1094 | result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len, | ||
1095 | &sshdr, 30 * HZ, 3, NULL); | ||
1096 | |||
1097 | if (result && scsi_sense_valid(&sshdr) && | ||
1098 | sshdr.sense_key == ILLEGAL_REQUEST && | ||
1099 | (sshdr.asc == 0x20 || sshdr.asc == 0x24) && sshdr.ascq == 0x00) | ||
1100 | return 0; | ||
1101 | |||
1102 | if ((buffer[1] & 3) == 3) /* Command supported */ | ||
1103 | return 1; | ||
1104 | |||
1105 | return 0; | ||
1106 | } | ||
1107 | EXPORT_SYMBOL(scsi_report_opcode); | ||
1108 | |||
1109 | /** | ||
1065 | * scsi_device_get - get an additional reference to a scsi_device | 1110 | * scsi_device_get - get an additional reference to a scsi_device |
1066 | * @sdev: device to get a reference to | 1111 | * @sdev: device to get a reference to |
1067 | * | 1112 | * |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index da36a3a81a9e..9032e910bca3 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -900,11 +900,23 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
900 | action = ACTION_FAIL; | 900 | action = ACTION_FAIL; |
901 | error = -EILSEQ; | 901 | error = -EILSEQ; |
902 | /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */ | 902 | /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */ |
903 | } else if ((sshdr.asc == 0x20 || sshdr.asc == 0x24) && | 903 | } else if (sshdr.asc == 0x20 || sshdr.asc == 0x24) { |
904 | (cmd->cmnd[0] == UNMAP || | 904 | switch (cmd->cmnd[0]) { |
905 | cmd->cmnd[0] == WRITE_SAME_16 || | 905 | case UNMAP: |
906 | cmd->cmnd[0] == WRITE_SAME)) { | 906 | description = "Discard failure"; |
907 | description = "Discard failure"; | 907 | break; |
908 | case WRITE_SAME: | ||
909 | case WRITE_SAME_16: | ||
910 | if (cmd->cmnd[1] & 0x8) | ||
911 | description = "Discard failure"; | ||
912 | else | ||
913 | description = | ||
914 | "Write same failure"; | ||
915 | break; | ||
916 | default: | ||
917 | description = "Invalid command failure"; | ||
918 | break; | ||
919 | } | ||
908 | action = ACTION_FAIL; | 920 | action = ACTION_FAIL; |
909 | error = -EREMOTEIO; | 921 | error = -EREMOTEIO; |
910 | } else | 922 | } else |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 12f6fdfc1147..352bc77b7c88 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -99,6 +99,7 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); | |||
99 | #endif | 99 | #endif |
100 | 100 | ||
101 | static void sd_config_discard(struct scsi_disk *, unsigned int); | 101 | static void sd_config_discard(struct scsi_disk *, unsigned int); |
102 | static void sd_config_write_same(struct scsi_disk *); | ||
102 | static int sd_revalidate_disk(struct gendisk *); | 103 | static int sd_revalidate_disk(struct gendisk *); |
103 | static void sd_unlock_native_capacity(struct gendisk *disk); | 104 | static void sd_unlock_native_capacity(struct gendisk *disk); |
104 | static int sd_probe(struct device *); | 105 | static int sd_probe(struct device *); |
@@ -395,6 +396,45 @@ sd_store_max_medium_access_timeouts(struct device *dev, | |||
395 | return err ? err : count; | 396 | return err ? err : count; |
396 | } | 397 | } |
397 | 398 | ||
399 | static ssize_t | ||
400 | sd_show_write_same_blocks(struct device *dev, struct device_attribute *attr, | ||
401 | char *buf) | ||
402 | { | ||
403 | struct scsi_disk *sdkp = to_scsi_disk(dev); | ||
404 | |||
405 | return snprintf(buf, 20, "%u\n", sdkp->max_ws_blocks); | ||
406 | } | ||
407 | |||
408 | static ssize_t | ||
409 | sd_store_write_same_blocks(struct device *dev, struct device_attribute *attr, | ||
410 | const char *buf, size_t count) | ||
411 | { | ||
412 | struct scsi_disk *sdkp = to_scsi_disk(dev); | ||
413 | struct scsi_device *sdp = sdkp->device; | ||
414 | unsigned long max; | ||
415 | int err; | ||
416 | |||
417 | if (!capable(CAP_SYS_ADMIN)) | ||
418 | return -EACCES; | ||
419 | |||
420 | if (sdp->type != TYPE_DISK) | ||
421 | return -EINVAL; | ||
422 | |||
423 | err = kstrtoul(buf, 10, &max); | ||
424 | |||
425 | if (err) | ||
426 | return err; | ||
427 | |||
428 | if (max == 0) | ||
429 | sdp->no_write_same = 1; | ||
430 | else if (max <= SD_MAX_WS16_BLOCKS) | ||
431 | sdkp->max_ws_blocks = max; | ||
432 | |||
433 | sd_config_write_same(sdkp); | ||
434 | |||
435 | return count; | ||
436 | } | ||
437 | |||
398 | static struct device_attribute sd_disk_attrs[] = { | 438 | static struct device_attribute sd_disk_attrs[] = { |
399 | __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, | 439 | __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, |
400 | sd_store_cache_type), | 440 | sd_store_cache_type), |
@@ -410,6 +450,8 @@ static struct device_attribute sd_disk_attrs[] = { | |||
410 | __ATTR(thin_provisioning, S_IRUGO, sd_show_thin_provisioning, NULL), | 450 | __ATTR(thin_provisioning, S_IRUGO, sd_show_thin_provisioning, NULL), |
411 | __ATTR(provisioning_mode, S_IRUGO|S_IWUSR, sd_show_provisioning_mode, | 451 | __ATTR(provisioning_mode, S_IRUGO|S_IWUSR, sd_show_provisioning_mode, |
412 | sd_store_provisioning_mode), | 452 | sd_store_provisioning_mode), |
453 | __ATTR(max_write_same_blocks, S_IRUGO|S_IWUSR, | ||
454 | sd_show_write_same_blocks, sd_store_write_same_blocks), | ||
413 | __ATTR(max_medium_access_timeouts, S_IRUGO|S_IWUSR, | 455 | __ATTR(max_medium_access_timeouts, S_IRUGO|S_IWUSR, |
414 | sd_show_max_medium_access_timeouts, | 456 | sd_show_max_medium_access_timeouts, |
415 | sd_store_max_medium_access_timeouts), | 457 | sd_store_max_medium_access_timeouts), |
@@ -561,19 +603,23 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode) | |||
561 | return; | 603 | return; |
562 | 604 | ||
563 | case SD_LBP_UNMAP: | 605 | case SD_LBP_UNMAP: |
564 | max_blocks = min_not_zero(sdkp->max_unmap_blocks, 0xffffffff); | 606 | max_blocks = min_not_zero(sdkp->max_unmap_blocks, |
607 | (u32)SD_MAX_WS16_BLOCKS); | ||
565 | break; | 608 | break; |
566 | 609 | ||
567 | case SD_LBP_WS16: | 610 | case SD_LBP_WS16: |
568 | max_blocks = min_not_zero(sdkp->max_ws_blocks, 0xffffffff); | 611 | max_blocks = min_not_zero(sdkp->max_ws_blocks, |
612 | (u32)SD_MAX_WS16_BLOCKS); | ||
569 | break; | 613 | break; |
570 | 614 | ||
571 | case SD_LBP_WS10: | 615 | case SD_LBP_WS10: |
572 | max_blocks = min_not_zero(sdkp->max_ws_blocks, (u32)0xffff); | 616 | max_blocks = min_not_zero(sdkp->max_ws_blocks, |
617 | (u32)SD_MAX_WS10_BLOCKS); | ||
573 | break; | 618 | break; |
574 | 619 | ||
575 | case SD_LBP_ZERO: | 620 | case SD_LBP_ZERO: |
576 | max_blocks = min_not_zero(sdkp->max_ws_blocks, (u32)0xffff); | 621 | max_blocks = min_not_zero(sdkp->max_ws_blocks, |
622 | (u32)SD_MAX_WS10_BLOCKS); | ||
577 | q->limits.discard_zeroes_data = 1; | 623 | q->limits.discard_zeroes_data = 1; |
578 | break; | 624 | break; |
579 | } | 625 | } |
@@ -583,29 +629,26 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode) | |||
583 | } | 629 | } |
584 | 630 | ||
585 | /** | 631 | /** |
586 | * scsi_setup_discard_cmnd - unmap blocks on thinly provisioned device | 632 | * sd_setup_discard_cmnd - unmap blocks on thinly provisioned device |
587 | * @sdp: scsi device to operate one | 633 | * @sdp: scsi device to operate one |
588 | * @rq: Request to prepare | 634 | * @rq: Request to prepare |
589 | * | 635 | * |
590 | * Will issue either UNMAP or WRITE SAME(16) depending on preference | 636 | * Will issue either UNMAP or WRITE SAME(16) depending on preference |
591 | * indicated by target device. | 637 | * indicated by target device. |
592 | **/ | 638 | **/ |
593 | static int scsi_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) | 639 | static int sd_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) |
594 | { | 640 | { |
595 | struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); | 641 | struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); |
596 | struct bio *bio = rq->bio; | 642 | sector_t sector = blk_rq_pos(rq); |
597 | sector_t sector = bio->bi_sector; | 643 | unsigned int nr_sectors = blk_rq_sectors(rq); |
598 | unsigned int nr_sectors = bio_sectors(bio); | 644 | unsigned int nr_bytes = blk_rq_bytes(rq); |
599 | unsigned int len; | 645 | unsigned int len; |
600 | int ret; | 646 | int ret; |
601 | char *buf; | 647 | char *buf; |
602 | struct page *page; | 648 | struct page *page; |
603 | 649 | ||
604 | if (sdkp->device->sector_size == 4096) { | 650 | sector >>= ilog2(sdp->sector_size) - 9; |
605 | sector >>= 3; | 651 | nr_sectors >>= ilog2(sdp->sector_size) - 9; |
606 | nr_sectors >>= 3; | ||
607 | } | ||
608 | |||
609 | rq->timeout = SD_TIMEOUT; | 652 | rq->timeout = SD_TIMEOUT; |
610 | 653 | ||
611 | memset(rq->cmd, 0, rq->cmd_len); | 654 | memset(rq->cmd, 0, rq->cmd_len); |
@@ -660,6 +703,7 @@ static int scsi_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) | |||
660 | blk_add_request_payload(rq, page, len); | 703 | blk_add_request_payload(rq, page, len); |
661 | ret = scsi_setup_blk_pc_cmnd(sdp, rq); | 704 | ret = scsi_setup_blk_pc_cmnd(sdp, rq); |
662 | rq->buffer = page_address(page); | 705 | rq->buffer = page_address(page); |
706 | rq->__data_len = nr_bytes; | ||
663 | 707 | ||
664 | out: | 708 | out: |
665 | if (ret != BLKPREP_OK) { | 709 | if (ret != BLKPREP_OK) { |
@@ -669,6 +713,83 @@ out: | |||
669 | return ret; | 713 | return ret; |
670 | } | 714 | } |
671 | 715 | ||
716 | static void sd_config_write_same(struct scsi_disk *sdkp) | ||
717 | { | ||
718 | struct request_queue *q = sdkp->disk->queue; | ||
719 | unsigned int logical_block_size = sdkp->device->sector_size; | ||
720 | unsigned int blocks = 0; | ||
721 | |||
722 | if (sdkp->device->no_write_same) { | ||
723 | sdkp->max_ws_blocks = 0; | ||
724 | goto out; | ||
725 | } | ||
726 | |||
727 | /* Some devices can not handle block counts above 0xffff despite | ||
728 | * supporting WRITE SAME(16). Consequently we default to 64k | ||
729 | * blocks per I/O unless the device explicitly advertises a | ||
730 | * bigger limit. | ||
731 | */ | ||
732 | if (sdkp->max_ws_blocks == 0) | ||
733 | sdkp->max_ws_blocks = SD_MAX_WS10_BLOCKS; | ||
734 | |||
735 | if (sdkp->ws16 || sdkp->max_ws_blocks > SD_MAX_WS10_BLOCKS) | ||
736 | blocks = min_not_zero(sdkp->max_ws_blocks, | ||
737 | (u32)SD_MAX_WS16_BLOCKS); | ||
738 | else | ||
739 | blocks = min_not_zero(sdkp->max_ws_blocks, | ||
740 | (u32)SD_MAX_WS10_BLOCKS); | ||
741 | |||
742 | out: | ||
743 | blk_queue_max_write_same_sectors(q, blocks * (logical_block_size >> 9)); | ||
744 | } | ||
745 | |||
746 | /** | ||
747 | * sd_setup_write_same_cmnd - write the same data to multiple blocks | ||
748 | * @sdp: scsi device to operate one | ||
749 | * @rq: Request to prepare | ||
750 | * | ||
751 | * Will issue either WRITE SAME(10) or WRITE SAME(16) depending on | ||
752 | * preference indicated by target device. | ||
753 | **/ | ||
754 | static int sd_setup_write_same_cmnd(struct scsi_device *sdp, struct request *rq) | ||
755 | { | ||
756 | struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); | ||
757 | struct bio *bio = rq->bio; | ||
758 | sector_t sector = blk_rq_pos(rq); | ||
759 | unsigned int nr_sectors = blk_rq_sectors(rq); | ||
760 | unsigned int nr_bytes = blk_rq_bytes(rq); | ||
761 | int ret; | ||
762 | |||
763 | if (sdkp->device->no_write_same) | ||
764 | return BLKPREP_KILL; | ||
765 | |||
766 | BUG_ON(bio_offset(bio) || bio_iovec(bio)->bv_len != sdp->sector_size); | ||
767 | |||
768 | sector >>= ilog2(sdp->sector_size) - 9; | ||
769 | nr_sectors >>= ilog2(sdp->sector_size) - 9; | ||
770 | |||
771 | rq->__data_len = sdp->sector_size; | ||
772 | rq->timeout = SD_WRITE_SAME_TIMEOUT; | ||
773 | memset(rq->cmd, 0, rq->cmd_len); | ||
774 | |||
775 | if (sdkp->ws16 || sector > 0xffffffff || nr_sectors > 0xffff) { | ||
776 | rq->cmd_len = 16; | ||
777 | rq->cmd[0] = WRITE_SAME_16; | ||
778 | put_unaligned_be64(sector, &rq->cmd[2]); | ||
779 | put_unaligned_be32(nr_sectors, &rq->cmd[10]); | ||
780 | } else { | ||
781 | rq->cmd_len = 10; | ||
782 | rq->cmd[0] = WRITE_SAME; | ||
783 | put_unaligned_be32(sector, &rq->cmd[2]); | ||
784 | put_unaligned_be16(nr_sectors, &rq->cmd[7]); | ||
785 | } | ||
786 | |||
787 | ret = scsi_setup_blk_pc_cmnd(sdp, rq); | ||
788 | rq->__data_len = nr_bytes; | ||
789 | |||
790 | return ret; | ||
791 | } | ||
792 | |||
672 | static int scsi_setup_flush_cmnd(struct scsi_device *sdp, struct request *rq) | 793 | static int scsi_setup_flush_cmnd(struct scsi_device *sdp, struct request *rq) |
673 | { | 794 | { |
674 | rq->timeout = SD_FLUSH_TIMEOUT; | 795 | rq->timeout = SD_FLUSH_TIMEOUT; |
@@ -712,7 +833,10 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) | |||
712 | * block PC requests to make life easier. | 833 | * block PC requests to make life easier. |
713 | */ | 834 | */ |
714 | if (rq->cmd_flags & REQ_DISCARD) { | 835 | if (rq->cmd_flags & REQ_DISCARD) { |
715 | ret = scsi_setup_discard_cmnd(sdp, rq); | 836 | ret = sd_setup_discard_cmnd(sdp, rq); |
837 | goto out; | ||
838 | } else if (rq->cmd_flags & REQ_WRITE_SAME) { | ||
839 | ret = sd_setup_write_same_cmnd(sdp, rq); | ||
716 | goto out; | 840 | goto out; |
717 | } else if (rq->cmd_flags & REQ_FLUSH) { | 841 | } else if (rq->cmd_flags & REQ_FLUSH) { |
718 | ret = scsi_setup_flush_cmnd(sdp, rq); | 842 | ret = scsi_setup_flush_cmnd(sdp, rq); |
@@ -1482,12 +1606,21 @@ static int sd_done(struct scsi_cmnd *SCpnt) | |||
1482 | unsigned int good_bytes = result ? 0 : scsi_bufflen(SCpnt); | 1606 | unsigned int good_bytes = result ? 0 : scsi_bufflen(SCpnt); |
1483 | struct scsi_sense_hdr sshdr; | 1607 | struct scsi_sense_hdr sshdr; |
1484 | struct scsi_disk *sdkp = scsi_disk(SCpnt->request->rq_disk); | 1608 | struct scsi_disk *sdkp = scsi_disk(SCpnt->request->rq_disk); |
1609 | struct request *req = SCpnt->request; | ||
1485 | int sense_valid = 0; | 1610 | int sense_valid = 0; |
1486 | int sense_deferred = 0; | 1611 | int sense_deferred = 0; |
1487 | unsigned char op = SCpnt->cmnd[0]; | 1612 | unsigned char op = SCpnt->cmnd[0]; |
1613 | unsigned char unmap = SCpnt->cmnd[1] & 8; | ||
1488 | 1614 | ||
1489 | if ((SCpnt->request->cmd_flags & REQ_DISCARD) && !result) | 1615 | if (req->cmd_flags & REQ_DISCARD || req->cmd_flags & REQ_WRITE_SAME) { |
1490 | scsi_set_resid(SCpnt, 0); | 1616 | if (!result) { |
1617 | good_bytes = blk_rq_bytes(req); | ||
1618 | scsi_set_resid(SCpnt, 0); | ||
1619 | } else { | ||
1620 | good_bytes = 0; | ||
1621 | scsi_set_resid(SCpnt, blk_rq_bytes(req)); | ||
1622 | } | ||
1623 | } | ||
1491 | 1624 | ||
1492 | if (result) { | 1625 | if (result) { |
1493 | sense_valid = scsi_command_normalize_sense(SCpnt, &sshdr); | 1626 | sense_valid = scsi_command_normalize_sense(SCpnt, &sshdr); |
@@ -1536,9 +1669,25 @@ static int sd_done(struct scsi_cmnd *SCpnt) | |||
1536 | if (sshdr.asc == 0x10) /* DIX: Host detected corruption */ | 1669 | if (sshdr.asc == 0x10) /* DIX: Host detected corruption */ |
1537 | good_bytes = sd_completed_bytes(SCpnt); | 1670 | good_bytes = sd_completed_bytes(SCpnt); |
1538 | /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */ | 1671 | /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */ |
1539 | if ((sshdr.asc == 0x20 || sshdr.asc == 0x24) && | 1672 | if (sshdr.asc == 0x20 || sshdr.asc == 0x24) { |
1540 | (op == UNMAP || op == WRITE_SAME_16 || op == WRITE_SAME)) | 1673 | switch (op) { |
1541 | sd_config_discard(sdkp, SD_LBP_DISABLE); | 1674 | case UNMAP: |
1675 | sd_config_discard(sdkp, SD_LBP_DISABLE); | ||
1676 | break; | ||
1677 | case WRITE_SAME_16: | ||
1678 | case WRITE_SAME: | ||
1679 | if (unmap) | ||
1680 | sd_config_discard(sdkp, SD_LBP_DISABLE); | ||
1681 | else { | ||
1682 | sdkp->device->no_write_same = 1; | ||
1683 | sd_config_write_same(sdkp); | ||
1684 | |||
1685 | good_bytes = 0; | ||
1686 | req->__data_len = blk_rq_bytes(req); | ||
1687 | req->cmd_flags |= REQ_QUIET; | ||
1688 | } | ||
1689 | } | ||
1690 | } | ||
1542 | break; | 1691 | break; |
1543 | default: | 1692 | default: |
1544 | break; | 1693 | break; |
@@ -2374,9 +2523,7 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) | |||
2374 | if (buffer[3] == 0x3c) { | 2523 | if (buffer[3] == 0x3c) { |
2375 | unsigned int lba_count, desc_count; | 2524 | unsigned int lba_count, desc_count; |
2376 | 2525 | ||
2377 | sdkp->max_ws_blocks = | 2526 | sdkp->max_ws_blocks = (u32)get_unaligned_be64(&buffer[36]); |
2378 | (u32) min_not_zero(get_unaligned_be64(&buffer[36]), | ||
2379 | (u64)0xffffffff); | ||
2380 | 2527 | ||
2381 | if (!sdkp->lbpme) | 2528 | if (!sdkp->lbpme) |
2382 | goto out; | 2529 | goto out; |
@@ -2469,6 +2616,13 @@ static void sd_read_block_provisioning(struct scsi_disk *sdkp) | |||
2469 | kfree(buffer); | 2616 | kfree(buffer); |
2470 | } | 2617 | } |
2471 | 2618 | ||
2619 | static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer) | ||
2620 | { | ||
2621 | if (scsi_report_opcode(sdkp->device, buffer, SD_BUF_SIZE, | ||
2622 | WRITE_SAME_16)) | ||
2623 | sdkp->ws16 = 1; | ||
2624 | } | ||
2625 | |||
2472 | static int sd_try_extended_inquiry(struct scsi_device *sdp) | 2626 | static int sd_try_extended_inquiry(struct scsi_device *sdp) |
2473 | { | 2627 | { |
2474 | /* | 2628 | /* |
@@ -2528,6 +2682,7 @@ static int sd_revalidate_disk(struct gendisk *disk) | |||
2528 | sd_read_write_protect_flag(sdkp, buffer); | 2682 | sd_read_write_protect_flag(sdkp, buffer); |
2529 | sd_read_cache_type(sdkp, buffer); | 2683 | sd_read_cache_type(sdkp, buffer); |
2530 | sd_read_app_tag_own(sdkp, buffer); | 2684 | sd_read_app_tag_own(sdkp, buffer); |
2685 | sd_read_write_same(sdkp, buffer); | ||
2531 | } | 2686 | } |
2532 | 2687 | ||
2533 | sdkp->first_scan = 0; | 2688 | sdkp->first_scan = 0; |
@@ -2545,6 +2700,7 @@ static int sd_revalidate_disk(struct gendisk *disk) | |||
2545 | blk_queue_flush(sdkp->disk->queue, flush); | 2700 | blk_queue_flush(sdkp->disk->queue, flush); |
2546 | 2701 | ||
2547 | set_capacity(disk, sdkp->capacity); | 2702 | set_capacity(disk, sdkp->capacity); |
2703 | sd_config_write_same(sdkp); | ||
2548 | kfree(buffer); | 2704 | kfree(buffer); |
2549 | 2705 | ||
2550 | out: | 2706 | out: |
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index 47c52a6d733c..74a1e4ca5401 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h | |||
@@ -14,6 +14,7 @@ | |||
14 | #define SD_TIMEOUT (30 * HZ) | 14 | #define SD_TIMEOUT (30 * HZ) |
15 | #define SD_MOD_TIMEOUT (75 * HZ) | 15 | #define SD_MOD_TIMEOUT (75 * HZ) |
16 | #define SD_FLUSH_TIMEOUT (60 * HZ) | 16 | #define SD_FLUSH_TIMEOUT (60 * HZ) |
17 | #define SD_WRITE_SAME_TIMEOUT (120 * HZ) | ||
17 | 18 | ||
18 | /* | 19 | /* |
19 | * Number of allowed retries | 20 | * Number of allowed retries |
@@ -39,6 +40,11 @@ enum { | |||
39 | }; | 40 | }; |
40 | 41 | ||
41 | enum { | 42 | enum { |
43 | SD_MAX_WS10_BLOCKS = 0xffff, | ||
44 | SD_MAX_WS16_BLOCKS = 0x7fffff, | ||
45 | }; | ||
46 | |||
47 | enum { | ||
42 | SD_LBP_FULL = 0, /* Full logical block provisioning */ | 48 | SD_LBP_FULL = 0, /* Full logical block provisioning */ |
43 | SD_LBP_UNMAP, /* Use UNMAP command */ | 49 | SD_LBP_UNMAP, /* Use UNMAP command */ |
44 | SD_LBP_WS16, /* Use WRITE SAME(16) with UNMAP bit */ | 50 | SD_LBP_WS16, /* Use WRITE SAME(16) with UNMAP bit */ |
@@ -77,6 +83,7 @@ struct scsi_disk { | |||
77 | unsigned lbpws : 1; | 83 | unsigned lbpws : 1; |
78 | unsigned lbpws10 : 1; | 84 | unsigned lbpws10 : 1; |
79 | unsigned lbpvpd : 1; | 85 | unsigned lbpvpd : 1; |
86 | unsigned ws16 : 1; | ||
80 | }; | 87 | }; |
81 | #define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev) | 88 | #define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev) |
82 | 89 | ||
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index a3d54366afcc..92f35abee92d 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c | |||
@@ -186,6 +186,12 @@ static int slave_configure(struct scsi_device *sdev) | |||
186 | /* Some devices don't handle VPD pages correctly */ | 186 | /* Some devices don't handle VPD pages correctly */ |
187 | sdev->skip_vpd_pages = 1; | 187 | sdev->skip_vpd_pages = 1; |
188 | 188 | ||
189 | /* Do not attempt to use REPORT SUPPORTED OPERATION CODES */ | ||
190 | sdev->no_report_opcodes = 1; | ||
191 | |||
192 | /* Do not attempt to use WRITE SAME */ | ||
193 | sdev->no_write_same = 1; | ||
194 | |||
189 | /* Some disks return the total number of blocks in response | 195 | /* Some disks return the total number of blocks in response |
190 | * to READ CAPACITY rather than the highest block number. | 196 | * to READ CAPACITY rather than the highest block number. |
191 | * If this device makes that mistake, tell the sd driver. */ | 197 | * If this device makes that mistake, tell the sd driver. */ |
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index d64ac3842884..bee92846cfab 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c | |||
@@ -365,11 +365,20 @@ struct platform_device *dsi_get_dsidev_from_id(int module) | |||
365 | struct omap_dss_output *out; | 365 | struct omap_dss_output *out; |
366 | enum omap_dss_output_id id; | 366 | enum omap_dss_output_id id; |
367 | 367 | ||
368 | id = module == 0 ? OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2; | 368 | switch (module) { |
369 | case 0: | ||
370 | id = OMAP_DSS_OUTPUT_DSI1; | ||
371 | break; | ||
372 | case 1: | ||
373 | id = OMAP_DSS_OUTPUT_DSI2; | ||
374 | break; | ||
375 | default: | ||
376 | return NULL; | ||
377 | } | ||
369 | 378 | ||
370 | out = omap_dss_get_output(id); | 379 | out = omap_dss_get_output(id); |
371 | 380 | ||
372 | return out->pdev; | 381 | return out ? out->pdev : NULL; |
373 | } | 382 | } |
374 | 383 | ||
375 | static inline void dsi_write_reg(struct platform_device *dsidev, | 384 | static inline void dsi_write_reg(struct platform_device *dsidev, |
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 2ab1c3e96553..5f6eea801b06 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c | |||
@@ -697,11 +697,15 @@ static int dss_get_clocks(void) | |||
697 | 697 | ||
698 | dss.dss_clk = clk; | 698 | dss.dss_clk = clk; |
699 | 699 | ||
700 | clk = clk_get(NULL, dss.feat->clk_name); | 700 | if (dss.feat->clk_name) { |
701 | if (IS_ERR(clk)) { | 701 | clk = clk_get(NULL, dss.feat->clk_name); |
702 | DSSERR("Failed to get %s\n", dss.feat->clk_name); | 702 | if (IS_ERR(clk)) { |
703 | r = PTR_ERR(clk); | 703 | DSSERR("Failed to get %s\n", dss.feat->clk_name); |
704 | goto err; | 704 | r = PTR_ERR(clk); |
705 | goto err; | ||
706 | } | ||
707 | } else { | ||
708 | clk = NULL; | ||
705 | } | 709 | } |
706 | 710 | ||
707 | dss.dpll4_m4_ck = clk; | 711 | dss.dpll4_m4_ck = clk; |
@@ -805,10 +809,10 @@ static int __init dss_init_features(struct device *dev) | |||
805 | 809 | ||
806 | if (cpu_is_omap24xx()) | 810 | if (cpu_is_omap24xx()) |
807 | src = &omap24xx_dss_feats; | 811 | src = &omap24xx_dss_feats; |
808 | else if (cpu_is_omap34xx()) | ||
809 | src = &omap34xx_dss_feats; | ||
810 | else if (cpu_is_omap3630()) | 812 | else if (cpu_is_omap3630()) |
811 | src = &omap3630_dss_feats; | 813 | src = &omap3630_dss_feats; |
814 | else if (cpu_is_omap34xx()) | ||
815 | src = &omap34xx_dss_feats; | ||
812 | else if (cpu_is_omap44xx()) | 816 | else if (cpu_is_omap44xx()) |
813 | src = &omap44xx_dss_feats; | 817 | src = &omap44xx_dss_feats; |
814 | else if (soc_is_omap54xx()) | 818 | else if (soc_is_omap54xx()) |
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index a48a7dd75b33..8c9b8b3b7f77 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c | |||
@@ -644,8 +644,10 @@ static void hdmi_dump_regs(struct seq_file *s) | |||
644 | { | 644 | { |
645 | mutex_lock(&hdmi.lock); | 645 | mutex_lock(&hdmi.lock); |
646 | 646 | ||
647 | if (hdmi_runtime_get()) | 647 | if (hdmi_runtime_get()) { |
648 | mutex_unlock(&hdmi.lock); | ||
648 | return; | 649 | return; |
650 | } | ||
649 | 651 | ||
650 | hdmi.ip_data.ops->dump_wrapper(&hdmi.ip_data, s); | 652 | hdmi.ip_data.ops->dump_wrapper(&hdmi.ip_data, s); |
651 | hdmi.ip_data.ops->dump_pll(&hdmi.ip_data, s); | 653 | hdmi.ip_data.ops->dump_pll(&hdmi.ip_data, s); |
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c index 606b89f12351..d630b26a005c 100644 --- a/drivers/video/omap2/omapfb/omapfb-ioctl.c +++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c | |||
@@ -787,7 +787,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) | |||
787 | 787 | ||
788 | case OMAPFB_WAITFORVSYNC: | 788 | case OMAPFB_WAITFORVSYNC: |
789 | DBG("ioctl WAITFORVSYNC\n"); | 789 | DBG("ioctl WAITFORVSYNC\n"); |
790 | if (!display && !display->output && !display->output->manager) { | 790 | if (!display || !display->output || !display->output->manager) { |
791 | r = -EINVAL; | 791 | r = -EINVAL; |
792 | break; | 792 | break; |
793 | } | 793 | } |
diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c index 8adb9cc267f9..71f5c459b088 100644 --- a/drivers/xen/privcmd.c +++ b/drivers/xen/privcmd.c | |||
@@ -361,13 +361,13 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version) | |||
361 | down_write(&mm->mmap_sem); | 361 | down_write(&mm->mmap_sem); |
362 | 362 | ||
363 | vma = find_vma(mm, m.addr); | 363 | vma = find_vma(mm, m.addr); |
364 | ret = -EINVAL; | ||
365 | if (!vma || | 364 | if (!vma || |
366 | vma->vm_ops != &privcmd_vm_ops || | 365 | vma->vm_ops != &privcmd_vm_ops || |
367 | (m.addr != vma->vm_start) || | 366 | (m.addr != vma->vm_start) || |
368 | ((m.addr + (nr_pages << PAGE_SHIFT)) != vma->vm_end) || | 367 | ((m.addr + (nr_pages << PAGE_SHIFT)) != vma->vm_end) || |
369 | !privcmd_enforce_singleshot_mapping(vma)) { | 368 | !privcmd_enforce_singleshot_mapping(vma)) { |
370 | up_write(&mm->mmap_sem); | 369 | up_write(&mm->mmap_sem); |
370 | ret = -EINVAL; | ||
371 | goto out; | 371 | goto out; |
372 | } | 372 | } |
373 | 373 | ||
@@ -383,12 +383,16 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version) | |||
383 | 383 | ||
384 | up_write(&mm->mmap_sem); | 384 | up_write(&mm->mmap_sem); |
385 | 385 | ||
386 | if (state.global_error && (version == 1)) { | 386 | if (version == 1) { |
387 | /* Write back errors in second pass. */ | 387 | if (state.global_error) { |
388 | state.user_mfn = (xen_pfn_t *)m.arr; | 388 | /* Write back errors in second pass. */ |
389 | state.err = err_array; | 389 | state.user_mfn = (xen_pfn_t *)m.arr; |
390 | ret = traverse_pages(m.num, sizeof(xen_pfn_t), | 390 | state.err = err_array; |
391 | &pagelist, mmap_return_errors_v1, &state); | 391 | ret = traverse_pages(m.num, sizeof(xen_pfn_t), |
392 | &pagelist, mmap_return_errors_v1, &state); | ||
393 | } else | ||
394 | ret = 0; | ||
395 | |||
392 | } else if (version == 2) { | 396 | } else if (version == 2) { |
393 | ret = __copy_to_user(m.err, err_array, m.num * sizeof(int)); | 397 | ret = __copy_to_user(m.err, err_array, m.num * sizeof(int)); |
394 | if (ret) | 398 | if (ret) |
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c index 7320a66e958f..22548f56197b 100644 --- a/fs/ext3/balloc.c +++ b/fs/ext3/balloc.c | |||
@@ -2101,8 +2101,9 @@ int ext3_trim_fs(struct super_block *sb, struct fstrim_range *range) | |||
2101 | end = start + (range->len >> sb->s_blocksize_bits) - 1; | 2101 | end = start + (range->len >> sb->s_blocksize_bits) - 1; |
2102 | minlen = range->minlen >> sb->s_blocksize_bits; | 2102 | minlen = range->minlen >> sb->s_blocksize_bits; |
2103 | 2103 | ||
2104 | if (unlikely(minlen > EXT3_BLOCKS_PER_GROUP(sb)) || | 2104 | if (minlen > EXT3_BLOCKS_PER_GROUP(sb) || |
2105 | unlikely(start >= max_blks)) | 2105 | start >= max_blks || |
2106 | range->len < sb->s_blocksize) | ||
2106 | return -EINVAL; | 2107 | return -EINVAL; |
2107 | if (end >= max_blks) | 2108 | if (end >= max_blks) |
2108 | end = max_blks - 1; | 2109 | end = max_blks - 1; |
@@ -685,7 +685,6 @@ void do_close_on_exec(struct files_struct *files) | |||
685 | struct fdtable *fdt; | 685 | struct fdtable *fdt; |
686 | 686 | ||
687 | /* exec unshares first */ | 687 | /* exec unshares first */ |
688 | BUG_ON(atomic_read(&files->count) != 1); | ||
689 | spin_lock(&files->file_lock); | 688 | spin_lock(&files->file_lock); |
690 | for (i = 0; ; i++) { | 689 | for (i = 0; ; i++) { |
691 | unsigned long set; | 690 | unsigned long set; |
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c index 60ef3fb707ff..1506673c087e 100644 --- a/fs/jffs2/file.c +++ b/fs/jffs2/file.c | |||
@@ -138,33 +138,39 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, | |||
138 | struct page *pg; | 138 | struct page *pg; |
139 | struct inode *inode = mapping->host; | 139 | struct inode *inode = mapping->host; |
140 | struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); | 140 | struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); |
141 | struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); | ||
142 | struct jffs2_raw_inode ri; | ||
143 | uint32_t alloc_len = 0; | ||
141 | pgoff_t index = pos >> PAGE_CACHE_SHIFT; | 144 | pgoff_t index = pos >> PAGE_CACHE_SHIFT; |
142 | uint32_t pageofs = index << PAGE_CACHE_SHIFT; | 145 | uint32_t pageofs = index << PAGE_CACHE_SHIFT; |
143 | int ret = 0; | 146 | int ret = 0; |
144 | 147 | ||
148 | jffs2_dbg(1, "%s()\n", __func__); | ||
149 | |||
150 | if (pageofs > inode->i_size) { | ||
151 | ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len, | ||
152 | ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); | ||
153 | if (ret) | ||
154 | return ret; | ||
155 | } | ||
156 | |||
157 | mutex_lock(&f->sem); | ||
145 | pg = grab_cache_page_write_begin(mapping, index, flags); | 158 | pg = grab_cache_page_write_begin(mapping, index, flags); |
146 | if (!pg) | 159 | if (!pg) { |
160 | if (alloc_len) | ||
161 | jffs2_complete_reservation(c); | ||
162 | mutex_unlock(&f->sem); | ||
147 | return -ENOMEM; | 163 | return -ENOMEM; |
164 | } | ||
148 | *pagep = pg; | 165 | *pagep = pg; |
149 | 166 | ||
150 | jffs2_dbg(1, "%s()\n", __func__); | 167 | if (alloc_len) { |
151 | |||
152 | if (pageofs > inode->i_size) { | ||
153 | /* Make new hole frag from old EOF to new page */ | 168 | /* Make new hole frag from old EOF to new page */ |
154 | struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); | ||
155 | struct jffs2_raw_inode ri; | ||
156 | struct jffs2_full_dnode *fn; | 169 | struct jffs2_full_dnode *fn; |
157 | uint32_t alloc_len; | ||
158 | 170 | ||
159 | jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n", | 171 | jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n", |
160 | (unsigned int)inode->i_size, pageofs); | 172 | (unsigned int)inode->i_size, pageofs); |
161 | 173 | ||
162 | ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len, | ||
163 | ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); | ||
164 | if (ret) | ||
165 | goto out_page; | ||
166 | |||
167 | mutex_lock(&f->sem); | ||
168 | memset(&ri, 0, sizeof(ri)); | 174 | memset(&ri, 0, sizeof(ri)); |
169 | 175 | ||
170 | ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); | 176 | ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); |
@@ -191,7 +197,6 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, | |||
191 | if (IS_ERR(fn)) { | 197 | if (IS_ERR(fn)) { |
192 | ret = PTR_ERR(fn); | 198 | ret = PTR_ERR(fn); |
193 | jffs2_complete_reservation(c); | 199 | jffs2_complete_reservation(c); |
194 | mutex_unlock(&f->sem); | ||
195 | goto out_page; | 200 | goto out_page; |
196 | } | 201 | } |
197 | ret = jffs2_add_full_dnode_to_inode(c, f, fn); | 202 | ret = jffs2_add_full_dnode_to_inode(c, f, fn); |
@@ -206,12 +211,10 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, | |||
206 | jffs2_mark_node_obsolete(c, fn->raw); | 211 | jffs2_mark_node_obsolete(c, fn->raw); |
207 | jffs2_free_full_dnode(fn); | 212 | jffs2_free_full_dnode(fn); |
208 | jffs2_complete_reservation(c); | 213 | jffs2_complete_reservation(c); |
209 | mutex_unlock(&f->sem); | ||
210 | goto out_page; | 214 | goto out_page; |
211 | } | 215 | } |
212 | jffs2_complete_reservation(c); | 216 | jffs2_complete_reservation(c); |
213 | inode->i_size = pageofs; | 217 | inode->i_size = pageofs; |
214 | mutex_unlock(&f->sem); | ||
215 | } | 218 | } |
216 | 219 | ||
217 | /* | 220 | /* |
@@ -220,18 +223,18 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, | |||
220 | * case of a short-copy. | 223 | * case of a short-copy. |
221 | */ | 224 | */ |
222 | if (!PageUptodate(pg)) { | 225 | if (!PageUptodate(pg)) { |
223 | mutex_lock(&f->sem); | ||
224 | ret = jffs2_do_readpage_nolock(inode, pg); | 226 | ret = jffs2_do_readpage_nolock(inode, pg); |
225 | mutex_unlock(&f->sem); | ||
226 | if (ret) | 227 | if (ret) |
227 | goto out_page; | 228 | goto out_page; |
228 | } | 229 | } |
230 | mutex_unlock(&f->sem); | ||
229 | jffs2_dbg(1, "end write_begin(). pg->flags %lx\n", pg->flags); | 231 | jffs2_dbg(1, "end write_begin(). pg->flags %lx\n", pg->flags); |
230 | return ret; | 232 | return ret; |
231 | 233 | ||
232 | out_page: | 234 | out_page: |
233 | unlock_page(pg); | 235 | unlock_page(pg); |
234 | page_cache_release(pg); | 236 | page_cache_release(pg); |
237 | mutex_unlock(&f->sem); | ||
235 | return ret; | 238 | return ret; |
236 | } | 239 | } |
237 | 240 | ||
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 721d692fa8d4..6fcaeb8c902e 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
@@ -258,7 +258,8 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, | |||
258 | if (ret) | 258 | if (ret) |
259 | goto out_close_fd; | 259 | goto out_close_fd; |
260 | 260 | ||
261 | fd_install(fd, f); | 261 | if (fd != FAN_NOFD) |
262 | fd_install(fd, f); | ||
262 | return fanotify_event_metadata.event_len; | 263 | return fanotify_event_metadata.event_len; |
263 | 264 | ||
264 | out_close_fd: | 265 | out_close_fd: |
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index f27f01a98aa2..d83736fbc26c 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -1782,8 +1782,9 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, | |||
1782 | 1782 | ||
1783 | BUG_ON(!th->t_trans_id); | 1783 | BUG_ON(!th->t_trans_id); |
1784 | 1784 | ||
1785 | dquot_initialize(inode); | 1785 | reiserfs_write_unlock(inode->i_sb); |
1786 | err = dquot_alloc_inode(inode); | 1786 | err = dquot_alloc_inode(inode); |
1787 | reiserfs_write_lock(inode->i_sb); | ||
1787 | if (err) | 1788 | if (err) |
1788 | goto out_end_trans; | 1789 | goto out_end_trans; |
1789 | if (!dir->i_nlink) { | 1790 | if (!dir->i_nlink) { |
@@ -1979,8 +1980,10 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, | |||
1979 | 1980 | ||
1980 | out_end_trans: | 1981 | out_end_trans: |
1981 | journal_end(th, th->t_super, th->t_blocks_allocated); | 1982 | journal_end(th, th->t_super, th->t_blocks_allocated); |
1983 | reiserfs_write_unlock(inode->i_sb); | ||
1982 | /* Drop can be outside and it needs more credits so it's better to have it outside */ | 1984 | /* Drop can be outside and it needs more credits so it's better to have it outside */ |
1983 | dquot_drop(inode); | 1985 | dquot_drop(inode); |
1986 | reiserfs_write_lock(inode->i_sb); | ||
1984 | inode->i_flags |= S_NOQUOTA; | 1987 | inode->i_flags |= S_NOQUOTA; |
1985 | make_bad_inode(inode); | 1988 | make_bad_inode(inode); |
1986 | 1989 | ||
@@ -3103,10 +3106,9 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
3103 | /* must be turned off for recursive notify_change calls */ | 3106 | /* must be turned off for recursive notify_change calls */ |
3104 | ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID); | 3107 | ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID); |
3105 | 3108 | ||
3106 | depth = reiserfs_write_lock_once(inode->i_sb); | ||
3107 | if (is_quota_modification(inode, attr)) | 3109 | if (is_quota_modification(inode, attr)) |
3108 | dquot_initialize(inode); | 3110 | dquot_initialize(inode); |
3109 | 3111 | depth = reiserfs_write_lock_once(inode->i_sb); | |
3110 | if (attr->ia_valid & ATTR_SIZE) { | 3112 | if (attr->ia_valid & ATTR_SIZE) { |
3111 | /* version 2 items will be caught by the s_maxbytes check | 3113 | /* version 2 items will be caught by the s_maxbytes check |
3112 | ** done for us in vmtruncate | 3114 | ** done for us in vmtruncate |
@@ -3170,7 +3172,9 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
3170 | error = journal_begin(&th, inode->i_sb, jbegin_count); | 3172 | error = journal_begin(&th, inode->i_sb, jbegin_count); |
3171 | if (error) | 3173 | if (error) |
3172 | goto out; | 3174 | goto out; |
3175 | reiserfs_write_unlock_once(inode->i_sb, depth); | ||
3173 | error = dquot_transfer(inode, attr); | 3176 | error = dquot_transfer(inode, attr); |
3177 | depth = reiserfs_write_lock_once(inode->i_sb); | ||
3174 | if (error) { | 3178 | if (error) { |
3175 | journal_end(&th, inode->i_sb, jbegin_count); | 3179 | journal_end(&th, inode->i_sb, jbegin_count); |
3176 | goto out; | 3180 | goto out; |
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c index f8afa4b162b8..2f40a4c70a4d 100644 --- a/fs/reiserfs/stree.c +++ b/fs/reiserfs/stree.c | |||
@@ -1968,7 +1968,9 @@ int reiserfs_paste_into_item(struct reiserfs_transaction_handle *th, struct tree | |||
1968 | key2type(&(key->on_disk_key))); | 1968 | key2type(&(key->on_disk_key))); |
1969 | #endif | 1969 | #endif |
1970 | 1970 | ||
1971 | reiserfs_write_unlock(inode->i_sb); | ||
1971 | retval = dquot_alloc_space_nodirty(inode, pasted_size); | 1972 | retval = dquot_alloc_space_nodirty(inode, pasted_size); |
1973 | reiserfs_write_lock(inode->i_sb); | ||
1972 | if (retval) { | 1974 | if (retval) { |
1973 | pathrelse(search_path); | 1975 | pathrelse(search_path); |
1974 | return retval; | 1976 | return retval; |
@@ -2061,9 +2063,11 @@ int reiserfs_insert_item(struct reiserfs_transaction_handle *th, | |||
2061 | "reiserquota insert_item(): allocating %u id=%u type=%c", | 2063 | "reiserquota insert_item(): allocating %u id=%u type=%c", |
2062 | quota_bytes, inode->i_uid, head2type(ih)); | 2064 | quota_bytes, inode->i_uid, head2type(ih)); |
2063 | #endif | 2065 | #endif |
2066 | reiserfs_write_unlock(inode->i_sb); | ||
2064 | /* We can't dirty inode here. It would be immediately written but | 2067 | /* We can't dirty inode here. It would be immediately written but |
2065 | * appropriate stat item isn't inserted yet... */ | 2068 | * appropriate stat item isn't inserted yet... */ |
2066 | retval = dquot_alloc_space_nodirty(inode, quota_bytes); | 2069 | retval = dquot_alloc_space_nodirty(inode, quota_bytes); |
2070 | reiserfs_write_lock(inode->i_sb); | ||
2067 | if (retval) { | 2071 | if (retval) { |
2068 | pathrelse(path); | 2072 | pathrelse(path); |
2069 | return retval; | 2073 | return retval; |
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 1078ae179993..418bdc3a57da 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -298,7 +298,9 @@ static int finish_unfinished(struct super_block *s) | |||
298 | retval = remove_save_link_only(s, &save_link_key, 0); | 298 | retval = remove_save_link_only(s, &save_link_key, 0); |
299 | continue; | 299 | continue; |
300 | } | 300 | } |
301 | reiserfs_write_unlock(s); | ||
301 | dquot_initialize(inode); | 302 | dquot_initialize(inode); |
303 | reiserfs_write_lock(s); | ||
302 | 304 | ||
303 | if (truncate && S_ISDIR(inode->i_mode)) { | 305 | if (truncate && S_ISDIR(inode->i_mode)) { |
304 | /* We got a truncate request for a dir which is impossible. | 306 | /* We got a truncate request for a dir which is impossible. |
@@ -1335,7 +1337,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) | |||
1335 | kfree(qf_names[i]); | 1337 | kfree(qf_names[i]); |
1336 | #endif | 1338 | #endif |
1337 | err = -EINVAL; | 1339 | err = -EINVAL; |
1338 | goto out_err; | 1340 | goto out_unlock; |
1339 | } | 1341 | } |
1340 | #ifdef CONFIG_QUOTA | 1342 | #ifdef CONFIG_QUOTA |
1341 | handle_quota_files(s, qf_names, &qfmt); | 1343 | handle_quota_files(s, qf_names, &qfmt); |
@@ -1379,7 +1381,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) | |||
1379 | if (blocks) { | 1381 | if (blocks) { |
1380 | err = reiserfs_resize(s, blocks); | 1382 | err = reiserfs_resize(s, blocks); |
1381 | if (err != 0) | 1383 | if (err != 0) |
1382 | goto out_err; | 1384 | goto out_unlock; |
1383 | } | 1385 | } |
1384 | 1386 | ||
1385 | if (*mount_flags & MS_RDONLY) { | 1387 | if (*mount_flags & MS_RDONLY) { |
@@ -1389,9 +1391,15 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) | |||
1389 | /* it is read-only already */ | 1391 | /* it is read-only already */ |
1390 | goto out_ok; | 1392 | goto out_ok; |
1391 | 1393 | ||
1394 | /* | ||
1395 | * Drop write lock. Quota will retake it when needed and lock | ||
1396 | * ordering requires calling dquot_suspend() without it. | ||
1397 | */ | ||
1398 | reiserfs_write_unlock(s); | ||
1392 | err = dquot_suspend(s, -1); | 1399 | err = dquot_suspend(s, -1); |
1393 | if (err < 0) | 1400 | if (err < 0) |
1394 | goto out_err; | 1401 | goto out_err; |
1402 | reiserfs_write_lock(s); | ||
1395 | 1403 | ||
1396 | /* try to remount file system with read-only permissions */ | 1404 | /* try to remount file system with read-only permissions */ |
1397 | if (sb_umount_state(rs) == REISERFS_VALID_FS | 1405 | if (sb_umount_state(rs) == REISERFS_VALID_FS |
@@ -1401,7 +1409,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) | |||
1401 | 1409 | ||
1402 | err = journal_begin(&th, s, 10); | 1410 | err = journal_begin(&th, s, 10); |
1403 | if (err) | 1411 | if (err) |
1404 | goto out_err; | 1412 | goto out_unlock; |
1405 | 1413 | ||
1406 | /* Mounting a rw partition read-only. */ | 1414 | /* Mounting a rw partition read-only. */ |
1407 | reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); | 1415 | reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); |
@@ -1416,7 +1424,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) | |||
1416 | 1424 | ||
1417 | if (reiserfs_is_journal_aborted(journal)) { | 1425 | if (reiserfs_is_journal_aborted(journal)) { |
1418 | err = journal->j_errno; | 1426 | err = journal->j_errno; |
1419 | goto out_err; | 1427 | goto out_unlock; |
1420 | } | 1428 | } |
1421 | 1429 | ||
1422 | handle_data_mode(s, mount_options); | 1430 | handle_data_mode(s, mount_options); |
@@ -1425,7 +1433,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) | |||
1425 | s->s_flags &= ~MS_RDONLY; /* now it is safe to call journal_begin */ | 1433 | s->s_flags &= ~MS_RDONLY; /* now it is safe to call journal_begin */ |
1426 | err = journal_begin(&th, s, 10); | 1434 | err = journal_begin(&th, s, 10); |
1427 | if (err) | 1435 | if (err) |
1428 | goto out_err; | 1436 | goto out_unlock; |
1429 | 1437 | ||
1430 | /* Mount a partition which is read-only, read-write */ | 1438 | /* Mount a partition which is read-only, read-write */ |
1431 | reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); | 1439 | reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); |
@@ -1442,10 +1450,16 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) | |||
1442 | SB_JOURNAL(s)->j_must_wait = 1; | 1450 | SB_JOURNAL(s)->j_must_wait = 1; |
1443 | err = journal_end(&th, s, 10); | 1451 | err = journal_end(&th, s, 10); |
1444 | if (err) | 1452 | if (err) |
1445 | goto out_err; | 1453 | goto out_unlock; |
1446 | 1454 | ||
1447 | if (!(*mount_flags & MS_RDONLY)) { | 1455 | if (!(*mount_flags & MS_RDONLY)) { |
1456 | /* | ||
1457 | * Drop write lock. Quota will retake it when needed and lock | ||
1458 | * ordering requires calling dquot_resume() without it. | ||
1459 | */ | ||
1460 | reiserfs_write_unlock(s); | ||
1448 | dquot_resume(s, -1); | 1461 | dquot_resume(s, -1); |
1462 | reiserfs_write_lock(s); | ||
1449 | finish_unfinished(s); | 1463 | finish_unfinished(s); |
1450 | reiserfs_xattr_init(s, *mount_flags); | 1464 | reiserfs_xattr_init(s, *mount_flags); |
1451 | } | 1465 | } |
@@ -1455,9 +1469,10 @@ out_ok: | |||
1455 | reiserfs_write_unlock(s); | 1469 | reiserfs_write_unlock(s); |
1456 | return 0; | 1470 | return 0; |
1457 | 1471 | ||
1472 | out_unlock: | ||
1473 | reiserfs_write_unlock(s); | ||
1458 | out_err: | 1474 | out_err: |
1459 | kfree(new_opts); | 1475 | kfree(new_opts); |
1460 | reiserfs_write_unlock(s); | ||
1461 | return err; | 1476 | return err; |
1462 | } | 1477 | } |
1463 | 1478 | ||
@@ -2095,13 +2110,15 @@ static int reiserfs_write_dquot(struct dquot *dquot) | |||
2095 | REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); | 2110 | REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); |
2096 | if (ret) | 2111 | if (ret) |
2097 | goto out; | 2112 | goto out; |
2113 | reiserfs_write_unlock(dquot->dq_sb); | ||
2098 | ret = dquot_commit(dquot); | 2114 | ret = dquot_commit(dquot); |
2115 | reiserfs_write_lock(dquot->dq_sb); | ||
2099 | err = | 2116 | err = |
2100 | journal_end(&th, dquot->dq_sb, | 2117 | journal_end(&th, dquot->dq_sb, |
2101 | REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); | 2118 | REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); |
2102 | if (!ret && err) | 2119 | if (!ret && err) |
2103 | ret = err; | 2120 | ret = err; |
2104 | out: | 2121 | out: |
2105 | reiserfs_write_unlock(dquot->dq_sb); | 2122 | reiserfs_write_unlock(dquot->dq_sb); |
2106 | return ret; | 2123 | return ret; |
2107 | } | 2124 | } |
@@ -2117,13 +2134,15 @@ static int reiserfs_acquire_dquot(struct dquot *dquot) | |||
2117 | REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb)); | 2134 | REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb)); |
2118 | if (ret) | 2135 | if (ret) |
2119 | goto out; | 2136 | goto out; |
2137 | reiserfs_write_unlock(dquot->dq_sb); | ||
2120 | ret = dquot_acquire(dquot); | 2138 | ret = dquot_acquire(dquot); |
2139 | reiserfs_write_lock(dquot->dq_sb); | ||
2121 | err = | 2140 | err = |
2122 | journal_end(&th, dquot->dq_sb, | 2141 | journal_end(&th, dquot->dq_sb, |
2123 | REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb)); | 2142 | REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb)); |
2124 | if (!ret && err) | 2143 | if (!ret && err) |
2125 | ret = err; | 2144 | ret = err; |
2126 | out: | 2145 | out: |
2127 | reiserfs_write_unlock(dquot->dq_sb); | 2146 | reiserfs_write_unlock(dquot->dq_sb); |
2128 | return ret; | 2147 | return ret; |
2129 | } | 2148 | } |
@@ -2137,19 +2156,21 @@ static int reiserfs_release_dquot(struct dquot *dquot) | |||
2137 | ret = | 2156 | ret = |
2138 | journal_begin(&th, dquot->dq_sb, | 2157 | journal_begin(&th, dquot->dq_sb, |
2139 | REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb)); | 2158 | REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb)); |
2159 | reiserfs_write_unlock(dquot->dq_sb); | ||
2140 | if (ret) { | 2160 | if (ret) { |
2141 | /* Release dquot anyway to avoid endless cycle in dqput() */ | 2161 | /* Release dquot anyway to avoid endless cycle in dqput() */ |
2142 | dquot_release(dquot); | 2162 | dquot_release(dquot); |
2143 | goto out; | 2163 | goto out; |
2144 | } | 2164 | } |
2145 | ret = dquot_release(dquot); | 2165 | ret = dquot_release(dquot); |
2166 | reiserfs_write_lock(dquot->dq_sb); | ||
2146 | err = | 2167 | err = |
2147 | journal_end(&th, dquot->dq_sb, | 2168 | journal_end(&th, dquot->dq_sb, |
2148 | REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb)); | 2169 | REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb)); |
2149 | if (!ret && err) | 2170 | if (!ret && err) |
2150 | ret = err; | 2171 | ret = err; |
2151 | out: | ||
2152 | reiserfs_write_unlock(dquot->dq_sb); | 2172 | reiserfs_write_unlock(dquot->dq_sb); |
2173 | out: | ||
2153 | return ret; | 2174 | return ret; |
2154 | } | 2175 | } |
2155 | 2176 | ||
@@ -2174,11 +2195,13 @@ static int reiserfs_write_info(struct super_block *sb, int type) | |||
2174 | ret = journal_begin(&th, sb, 2); | 2195 | ret = journal_begin(&th, sb, 2); |
2175 | if (ret) | 2196 | if (ret) |
2176 | goto out; | 2197 | goto out; |
2198 | reiserfs_write_unlock(sb); | ||
2177 | ret = dquot_commit_info(sb, type); | 2199 | ret = dquot_commit_info(sb, type); |
2200 | reiserfs_write_lock(sb); | ||
2178 | err = journal_end(&th, sb, 2); | 2201 | err = journal_end(&th, sb, 2); |
2179 | if (!ret && err) | 2202 | if (!ret && err) |
2180 | ret = err; | 2203 | ret = err; |
2181 | out: | 2204 | out: |
2182 | reiserfs_write_unlock(sb); | 2205 | reiserfs_write_unlock(sb); |
2183 | return ret; | 2206 | return ret; |
2184 | } | 2207 | } |
@@ -2203,8 +2226,11 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, | |||
2203 | struct reiserfs_transaction_handle th; | 2226 | struct reiserfs_transaction_handle th; |
2204 | int opt = type == USRQUOTA ? REISERFS_USRQUOTA : REISERFS_GRPQUOTA; | 2227 | int opt = type == USRQUOTA ? REISERFS_USRQUOTA : REISERFS_GRPQUOTA; |
2205 | 2228 | ||
2206 | if (!(REISERFS_SB(sb)->s_mount_opt & (1 << opt))) | 2229 | reiserfs_write_lock(sb); |
2207 | return -EINVAL; | 2230 | if (!(REISERFS_SB(sb)->s_mount_opt & (1 << opt))) { |
2231 | err = -EINVAL; | ||
2232 | goto out; | ||
2233 | } | ||
2208 | 2234 | ||
2209 | /* Quotafile not on the same filesystem? */ | 2235 | /* Quotafile not on the same filesystem? */ |
2210 | if (path->dentry->d_sb != sb) { | 2236 | if (path->dentry->d_sb != sb) { |
@@ -2246,8 +2272,10 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, | |||
2246 | if (err) | 2272 | if (err) |
2247 | goto out; | 2273 | goto out; |
2248 | } | 2274 | } |
2249 | err = dquot_quota_on(sb, type, format_id, path); | 2275 | reiserfs_write_unlock(sb); |
2276 | return dquot_quota_on(sb, type, format_id, path); | ||
2250 | out: | 2277 | out: |
2278 | reiserfs_write_unlock(sb); | ||
2251 | return err; | 2279 | return err; |
2252 | } | 2280 | } |
2253 | 2281 | ||
@@ -2320,7 +2348,9 @@ static ssize_t reiserfs_quota_write(struct super_block *sb, int type, | |||
2320 | tocopy = sb->s_blocksize - offset < towrite ? | 2348 | tocopy = sb->s_blocksize - offset < towrite ? |
2321 | sb->s_blocksize - offset : towrite; | 2349 | sb->s_blocksize - offset : towrite; |
2322 | tmp_bh.b_state = 0; | 2350 | tmp_bh.b_state = 0; |
2351 | reiserfs_write_lock(sb); | ||
2323 | err = reiserfs_get_block(inode, blk, &tmp_bh, GET_BLOCK_CREATE); | 2352 | err = reiserfs_get_block(inode, blk, &tmp_bh, GET_BLOCK_CREATE); |
2353 | reiserfs_write_unlock(sb); | ||
2324 | if (err) | 2354 | if (err) |
2325 | goto out; | 2355 | goto out; |
2326 | if (offset || tocopy != sb->s_blocksize) | 2356 | if (offset || tocopy != sb->s_blocksize) |
@@ -2336,10 +2366,12 @@ static ssize_t reiserfs_quota_write(struct super_block *sb, int type, | |||
2336 | flush_dcache_page(bh->b_page); | 2366 | flush_dcache_page(bh->b_page); |
2337 | set_buffer_uptodate(bh); | 2367 | set_buffer_uptodate(bh); |
2338 | unlock_buffer(bh); | 2368 | unlock_buffer(bh); |
2369 | reiserfs_write_lock(sb); | ||
2339 | reiserfs_prepare_for_journal(sb, bh, 1); | 2370 | reiserfs_prepare_for_journal(sb, bh, 1); |
2340 | journal_mark_dirty(current->journal_info, sb, bh); | 2371 | journal_mark_dirty(current->journal_info, sb, bh); |
2341 | if (!journal_quota) | 2372 | if (!journal_quota) |
2342 | reiserfs_add_ordered_list(inode, bh); | 2373 | reiserfs_add_ordered_list(inode, bh); |
2374 | reiserfs_write_unlock(sb); | ||
2343 | brelse(bh); | 2375 | brelse(bh); |
2344 | offset = 0; | 2376 | offset = 0; |
2345 | towrite -= tocopy; | 2377 | towrite -= tocopy; |
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index e562dd43f41f..e57e2daa357c 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c | |||
@@ -481,11 +481,17 @@ static inline int bio_add_buffer(struct bio *bio, struct buffer_head *bh) | |||
481 | * | 481 | * |
482 | * The fix is two passes across the ioend list - one to start writeback on the | 482 | * The fix is two passes across the ioend list - one to start writeback on the |
483 | * buffer_heads, and then submit them for I/O on the second pass. | 483 | * buffer_heads, and then submit them for I/O on the second pass. |
484 | * | ||
485 | * If @fail is non-zero, it means that we have a situation where some part of | ||
486 | * the submission process has failed after we have marked paged for writeback | ||
487 | * and unlocked them. In this situation, we need to fail the ioend chain rather | ||
488 | * than submit it to IO. This typically only happens on a filesystem shutdown. | ||
484 | */ | 489 | */ |
485 | STATIC void | 490 | STATIC void |
486 | xfs_submit_ioend( | 491 | xfs_submit_ioend( |
487 | struct writeback_control *wbc, | 492 | struct writeback_control *wbc, |
488 | xfs_ioend_t *ioend) | 493 | xfs_ioend_t *ioend, |
494 | int fail) | ||
489 | { | 495 | { |
490 | xfs_ioend_t *head = ioend; | 496 | xfs_ioend_t *head = ioend; |
491 | xfs_ioend_t *next; | 497 | xfs_ioend_t *next; |
@@ -506,6 +512,18 @@ xfs_submit_ioend( | |||
506 | next = ioend->io_list; | 512 | next = ioend->io_list; |
507 | bio = NULL; | 513 | bio = NULL; |
508 | 514 | ||
515 | /* | ||
516 | * If we are failing the IO now, just mark the ioend with an | ||
517 | * error and finish it. This will run IO completion immediately | ||
518 | * as there is only one reference to the ioend at this point in | ||
519 | * time. | ||
520 | */ | ||
521 | if (fail) { | ||
522 | ioend->io_error = -fail; | ||
523 | xfs_finish_ioend(ioend); | ||
524 | continue; | ||
525 | } | ||
526 | |||
509 | for (bh = ioend->io_buffer_head; bh; bh = bh->b_private) { | 527 | for (bh = ioend->io_buffer_head; bh; bh = bh->b_private) { |
510 | 528 | ||
511 | if (!bio) { | 529 | if (!bio) { |
@@ -1060,7 +1078,18 @@ xfs_vm_writepage( | |||
1060 | 1078 | ||
1061 | xfs_start_page_writeback(page, 1, count); | 1079 | xfs_start_page_writeback(page, 1, count); |
1062 | 1080 | ||
1063 | if (ioend && imap_valid) { | 1081 | /* if there is no IO to be submitted for this page, we are done */ |
1082 | if (!ioend) | ||
1083 | return 0; | ||
1084 | |||
1085 | ASSERT(iohead); | ||
1086 | |||
1087 | /* | ||
1088 | * Any errors from this point onwards need tobe reported through the IO | ||
1089 | * completion path as we have marked the initial page as under writeback | ||
1090 | * and unlocked it. | ||
1091 | */ | ||
1092 | if (imap_valid) { | ||
1064 | xfs_off_t end_index; | 1093 | xfs_off_t end_index; |
1065 | 1094 | ||
1066 | end_index = imap.br_startoff + imap.br_blockcount; | 1095 | end_index = imap.br_startoff + imap.br_blockcount; |
@@ -1079,20 +1108,15 @@ xfs_vm_writepage( | |||
1079 | wbc, end_index); | 1108 | wbc, end_index); |
1080 | } | 1109 | } |
1081 | 1110 | ||
1082 | if (iohead) { | ||
1083 | /* | ||
1084 | * Reserve log space if we might write beyond the on-disk | ||
1085 | * inode size. | ||
1086 | */ | ||
1087 | if (ioend->io_type != XFS_IO_UNWRITTEN && | ||
1088 | xfs_ioend_is_append(ioend)) { | ||
1089 | err = xfs_setfilesize_trans_alloc(ioend); | ||
1090 | if (err) | ||
1091 | goto error; | ||
1092 | } | ||
1093 | 1111 | ||
1094 | xfs_submit_ioend(wbc, iohead); | 1112 | /* |
1095 | } | 1113 | * Reserve log space if we might write beyond the on-disk inode size. |
1114 | */ | ||
1115 | err = 0; | ||
1116 | if (ioend->io_type != XFS_IO_UNWRITTEN && xfs_ioend_is_append(ioend)) | ||
1117 | err = xfs_setfilesize_trans_alloc(ioend); | ||
1118 | |||
1119 | xfs_submit_ioend(wbc, iohead, err); | ||
1096 | 1120 | ||
1097 | return 0; | 1121 | return 0; |
1098 | 1122 | ||
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c index d330111ca738..70eec1829776 100644 --- a/fs/xfs/xfs_attr_leaf.c +++ b/fs/xfs/xfs_attr_leaf.c | |||
@@ -1291,6 +1291,7 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, | |||
1291 | leaf2 = blk2->bp->b_addr; | 1291 | leaf2 = blk2->bp->b_addr; |
1292 | ASSERT(leaf1->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); | 1292 | ASSERT(leaf1->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); |
1293 | ASSERT(leaf2->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); | 1293 | ASSERT(leaf2->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); |
1294 | ASSERT(leaf2->hdr.count == 0); | ||
1294 | args = state->args; | 1295 | args = state->args; |
1295 | 1296 | ||
1296 | trace_xfs_attr_leaf_rebalance(args); | 1297 | trace_xfs_attr_leaf_rebalance(args); |
@@ -1361,6 +1362,7 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, | |||
1361 | * I assert that since all callers pass in an empty | 1362 | * I assert that since all callers pass in an empty |
1362 | * second buffer, this code should never execute. | 1363 | * second buffer, this code should never execute. |
1363 | */ | 1364 | */ |
1365 | ASSERT(0); | ||
1364 | 1366 | ||
1365 | /* | 1367 | /* |
1366 | * Figure the total bytes to be added to the destination leaf. | 1368 | * Figure the total bytes to be added to the destination leaf. |
@@ -1422,10 +1424,24 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, | |||
1422 | args->index2 = 0; | 1424 | args->index2 = 0; |
1423 | args->blkno2 = blk2->blkno; | 1425 | args->blkno2 = blk2->blkno; |
1424 | } else { | 1426 | } else { |
1427 | /* | ||
1428 | * On a double leaf split, the original attr location | ||
1429 | * is already stored in blkno2/index2, so don't | ||
1430 | * overwrite it overwise we corrupt the tree. | ||
1431 | */ | ||
1425 | blk2->index = blk1->index | 1432 | blk2->index = blk1->index |
1426 | - be16_to_cpu(leaf1->hdr.count); | 1433 | - be16_to_cpu(leaf1->hdr.count); |
1427 | args->index = args->index2 = blk2->index; | 1434 | args->index = blk2->index; |
1428 | args->blkno = args->blkno2 = blk2->blkno; | 1435 | args->blkno = blk2->blkno; |
1436 | if (!state->extravalid) { | ||
1437 | /* | ||
1438 | * set the new attr location to match the old | ||
1439 | * one and let the higher level split code | ||
1440 | * decide where in the leaf to place it. | ||
1441 | */ | ||
1442 | args->index2 = blk2->index; | ||
1443 | args->blkno2 = blk2->blkno; | ||
1444 | } | ||
1429 | } | 1445 | } |
1430 | } else { | 1446 | } else { |
1431 | ASSERT(state->inleaf == 1); | 1447 | ASSERT(state->inleaf == 1); |
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 933b7930b863..4b0b8dd1b7b0 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c | |||
@@ -1197,9 +1197,14 @@ xfs_buf_bio_end_io( | |||
1197 | { | 1197 | { |
1198 | xfs_buf_t *bp = (xfs_buf_t *)bio->bi_private; | 1198 | xfs_buf_t *bp = (xfs_buf_t *)bio->bi_private; |
1199 | 1199 | ||
1200 | xfs_buf_ioerror(bp, -error); | 1200 | /* |
1201 | * don't overwrite existing errors - otherwise we can lose errors on | ||
1202 | * buffers that require multiple bios to complete. | ||
1203 | */ | ||
1204 | if (!bp->b_error) | ||
1205 | xfs_buf_ioerror(bp, -error); | ||
1201 | 1206 | ||
1202 | if (!error && xfs_buf_is_vmapped(bp) && (bp->b_flags & XBF_READ)) | 1207 | if (!bp->b_error && xfs_buf_is_vmapped(bp) && (bp->b_flags & XBF_READ)) |
1203 | invalidate_kernel_vmap_range(bp->b_addr, xfs_buf_vmap_len(bp)); | 1208 | invalidate_kernel_vmap_range(bp->b_addr, xfs_buf_vmap_len(bp)); |
1204 | 1209 | ||
1205 | _xfs_buf_ioend(bp, 1); | 1210 | _xfs_buf_ioend(bp, 1); |
@@ -1279,6 +1284,11 @@ next_chunk: | |||
1279 | if (size) | 1284 | if (size) |
1280 | goto next_chunk; | 1285 | goto next_chunk; |
1281 | } else { | 1286 | } else { |
1287 | /* | ||
1288 | * This is guaranteed not to be the last io reference count | ||
1289 | * because the caller (xfs_buf_iorequest) holds a count itself. | ||
1290 | */ | ||
1291 | atomic_dec(&bp->b_io_remaining); | ||
1282 | xfs_buf_ioerror(bp, EIO); | 1292 | xfs_buf_ioerror(bp, EIO); |
1283 | bio_put(bio); | 1293 | bio_put(bio); |
1284 | } | 1294 | } |
diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h index af1cbaf535ed..c5c35e629426 100644 --- a/include/drm/drm_pciids.h +++ b/include/drm/drm_pciids.h | |||
@@ -210,6 +210,7 @@ | |||
210 | {0x1002, 0x6798, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ | 210 | {0x1002, 0x6798, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ |
211 | {0x1002, 0x6799, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ | 211 | {0x1002, 0x6799, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ |
212 | {0x1002, 0x679A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ | 212 | {0x1002, 0x679A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ |
213 | {0x1002, 0x679B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ | ||
213 | {0x1002, 0x679E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ | 214 | {0x1002, 0x679E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ |
214 | {0x1002, 0x679F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ | 215 | {0x1002, 0x679F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ |
215 | {0x1002, 0x6800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 216 | {0x1002, 0x6800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
diff --git a/include/linux/atmel-ssc.h b/include/linux/atmel-ssc.h index 4eb31752e2b7..deb0ae58b99b 100644 --- a/include/linux/atmel-ssc.h +++ b/include/linux/atmel-ssc.h | |||
@@ -5,10 +5,16 @@ | |||
5 | #include <linux/list.h> | 5 | #include <linux/list.h> |
6 | #include <linux/io.h> | 6 | #include <linux/io.h> |
7 | 7 | ||
8 | struct atmel_ssc_platform_data { | ||
9 | int use_dma; | ||
10 | }; | ||
11 | |||
8 | struct ssc_device { | 12 | struct ssc_device { |
9 | struct list_head list; | 13 | struct list_head list; |
14 | resource_size_t phybase; | ||
10 | void __iomem *regs; | 15 | void __iomem *regs; |
11 | struct platform_device *pdev; | 16 | struct platform_device *pdev; |
17 | struct atmel_ssc_platform_data *pdata; | ||
12 | struct clk *clk; | 18 | struct clk *clk; |
13 | int user; | 19 | int user; |
14 | int irq; | 20 | int irq; |
diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h index df804ba73e0b..92a0dc75bc74 100644 --- a/include/linux/i2c-omap.h +++ b/include/linux/i2c-omap.h | |||
@@ -34,6 +34,7 @@ struct omap_i2c_bus_platform_data { | |||
34 | u32 clkrate; | 34 | u32 clkrate; |
35 | u32 rev; | 35 | u32 rev; |
36 | u32 flags; | 36 | u32 flags; |
37 | void (*set_mpu_wkup_lat)(struct device *dev, long set); | ||
37 | }; | 38 | }; |
38 | 39 | ||
39 | #endif | 40 | #endif |
diff --git a/include/linux/mfd/arizona/core.h b/include/linux/mfd/arizona/core.h index dd231ac0bb1f..a580363a7d29 100644 --- a/include/linux/mfd/arizona/core.h +++ b/include/linux/mfd/arizona/core.h | |||
@@ -78,6 +78,8 @@ enum arizona_type { | |||
78 | 78 | ||
79 | #define ARIZONA_NUM_IRQ 50 | 79 | #define ARIZONA_NUM_IRQ 50 |
80 | 80 | ||
81 | struct snd_soc_dapm_context; | ||
82 | |||
81 | struct arizona { | 83 | struct arizona { |
82 | struct regmap *regmap; | 84 | struct regmap *regmap; |
83 | struct device *dev; | 85 | struct device *dev; |
@@ -98,6 +100,8 @@ struct arizona { | |||
98 | 100 | ||
99 | struct mutex clk_lock; | 101 | struct mutex clk_lock; |
100 | int clk32k_ref; | 102 | int clk32k_ref; |
103 | |||
104 | struct snd_soc_dapm_context *dapm; | ||
101 | }; | 105 | }; |
102 | 106 | ||
103 | int arizona_clk32k_enable(struct arizona *arizona); | 107 | int arizona_clk32k_enable(struct arizona *arizona); |
diff --git a/include/linux/mfd/arizona/pdata.h b/include/linux/mfd/arizona/pdata.h index 7ab442905a57..8b1d1daaae16 100644 --- a/include/linux/mfd/arizona/pdata.h +++ b/include/linux/mfd/arizona/pdata.h | |||
@@ -62,6 +62,9 @@ | |||
62 | 62 | ||
63 | #define ARIZONA_MAX_OUTPUT 6 | 63 | #define ARIZONA_MAX_OUTPUT 6 |
64 | 64 | ||
65 | #define ARIZONA_HAP_ACT_ERM 0 | ||
66 | #define ARIZONA_HAP_ACT_LRA 2 | ||
67 | |||
65 | #define ARIZONA_MAX_PDM_SPK 2 | 68 | #define ARIZONA_MAX_PDM_SPK 2 |
66 | 69 | ||
67 | struct regulator_init_data; | 70 | struct regulator_init_data; |
@@ -114,6 +117,9 @@ struct arizona_pdata { | |||
114 | 117 | ||
115 | /** PDM speaker format */ | 118 | /** PDM speaker format */ |
116 | unsigned int spk_fmt[ARIZONA_MAX_PDM_SPK]; | 119 | unsigned int spk_fmt[ARIZONA_MAX_PDM_SPK]; |
120 | |||
121 | /** Haptic actuator type */ | ||
122 | unsigned int hap_act; | ||
117 | }; | 123 | }; |
118 | 124 | ||
119 | #endif | 125 | #endif |
diff --git a/include/linux/mfd/wm8994/core.h b/include/linux/mfd/wm8994/core.h index 1f173306bf05..ae5c249530b4 100644 --- a/include/linux/mfd/wm8994/core.h +++ b/include/linux/mfd/wm8994/core.h | |||
@@ -19,6 +19,8 @@ | |||
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/regmap.h> | 20 | #include <linux/regmap.h> |
21 | 21 | ||
22 | #include <linux/mfd/wm8994/pdata.h> | ||
23 | |||
22 | enum wm8994_type { | 24 | enum wm8994_type { |
23 | WM8994 = 0, | 25 | WM8994 = 0, |
24 | WM8958 = 1, | 26 | WM8958 = 1, |
@@ -55,6 +57,8 @@ struct regulator_bulk_data; | |||
55 | struct wm8994 { | 57 | struct wm8994 { |
56 | struct mutex irq_lock; | 58 | struct mutex irq_lock; |
57 | 59 | ||
60 | struct wm8994_pdata pdata; | ||
61 | |||
58 | enum wm8994_type type; | 62 | enum wm8994_type type; |
59 | int revision; | 63 | int revision; |
60 | int cust_id; | 64 | int cust_id; |
diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h index fc87be4fdc25..8e21a094836d 100644 --- a/include/linux/mfd/wm8994/pdata.h +++ b/include/linux/mfd/wm8994/pdata.h | |||
@@ -176,6 +176,11 @@ struct wm8994_pdata { | |||
176 | unsigned int lineout1fb:1; | 176 | unsigned int lineout1fb:1; |
177 | unsigned int lineout2fb:1; | 177 | unsigned int lineout2fb:1; |
178 | 178 | ||
179 | /* Delay between detecting a jack and starting microphone | ||
180 | * detect (specified in ms) | ||
181 | */ | ||
182 | int micdet_delay; | ||
183 | |||
179 | /* IRQ for microphone detection if brought out directly as a | 184 | /* IRQ for microphone detection if brought out directly as a |
180 | * signal. | 185 | * signal. |
181 | */ | 186 | */ |
diff --git a/include/linux/of_address.h b/include/linux/of_address.h index e20e3af68fb6..0506eb53519b 100644 --- a/include/linux/of_address.h +++ b/include/linux/of_address.h | |||
@@ -42,10 +42,12 @@ static inline struct device_node *of_find_matching_node_by_address( | |||
42 | { | 42 | { |
43 | return NULL; | 43 | return NULL; |
44 | } | 44 | } |
45 | #ifndef of_iomap | ||
45 | static inline void __iomem *of_iomap(struct device_node *device, int index) | 46 | static inline void __iomem *of_iomap(struct device_node *device, int index) |
46 | { | 47 | { |
47 | return NULL; | 48 | return NULL; |
48 | } | 49 | } |
50 | #endif | ||
49 | static inline const __be32 *of_get_address(struct device_node *dev, int index, | 51 | static inline const __be32 *of_get_address(struct device_node *dev, int index, |
50 | u64 *size, unsigned int *flags) | 52 | u64 *size, unsigned int *flags) |
51 | { | 53 | { |
diff --git a/include/linux/platform_data/asoc-s3c.h b/include/linux/platform_data/asoc-s3c.h index aa9875f77c40..88272591a895 100644 --- a/include/linux/platform_data/asoc-s3c.h +++ b/include/linux/platform_data/asoc-s3c.h | |||
@@ -38,12 +38,6 @@ struct samsung_i2s { | |||
38 | #define QUIRK_NEED_RSTCLR (1 << 3) | 38 | #define QUIRK_NEED_RSTCLR (1 << 3) |
39 | /* Quirks of the I2S controller */ | 39 | /* Quirks of the I2S controller */ |
40 | u32 quirks; | 40 | u32 quirks; |
41 | |||
42 | /* | ||
43 | * Array of clock names that can be used to generate I2S signals. | ||
44 | * Also corresponds to clocks of I2SMOD[10] | ||
45 | */ | ||
46 | const char **src_clk; | ||
47 | dma_addr_t idma_addr; | 41 | dma_addr_t idma_addr; |
48 | }; | 42 | }; |
49 | 43 | ||
diff --git a/include/linux/platform_data/davinci_asp.h b/include/linux/platform_data/davinci_asp.h index d0c5825876f8..f3d6e4f20962 100644 --- a/include/linux/platform_data/davinci_asp.h +++ b/include/linux/platform_data/davinci_asp.h | |||
@@ -16,6 +16,8 @@ | |||
16 | #ifndef __DAVINCI_ASP_H | 16 | #ifndef __DAVINCI_ASP_H |
17 | #define __DAVINCI_ASP_H | 17 | #define __DAVINCI_ASP_H |
18 | 18 | ||
19 | #include <linux/genalloc.h> | ||
20 | |||
19 | struct snd_platform_data { | 21 | struct snd_platform_data { |
20 | u32 tx_dma_offset; | 22 | u32 tx_dma_offset; |
21 | u32 rx_dma_offset; | 23 | u32 rx_dma_offset; |
@@ -30,6 +32,7 @@ struct snd_platform_data { | |||
30 | unsigned enable_channel_combine:1; | 32 | unsigned enable_channel_combine:1; |
31 | unsigned sram_size_playback; | 33 | unsigned sram_size_playback; |
32 | unsigned sram_size_capture; | 34 | unsigned sram_size_capture; |
35 | struct gen_pool *sram_pool; | ||
33 | 36 | ||
34 | /* | 37 | /* |
35 | * If McBSP peripheral gets the clock from an external pin, | 38 | * If McBSP peripheral gets the clock from an external pin, |
diff --git a/include/linux/regmap.h b/include/linux/regmap.h index e3bcc3f4dcb8..9f228d7f7ac4 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h | |||
@@ -133,7 +133,7 @@ struct regmap_config { | |||
133 | enum regmap_endian val_format_endian; | 133 | enum regmap_endian val_format_endian; |
134 | 134 | ||
135 | const struct regmap_range_cfg *ranges; | 135 | const struct regmap_range_cfg *ranges; |
136 | unsigned int n_ranges; | 136 | unsigned int num_ranges; |
137 | }; | 137 | }; |
138 | 138 | ||
139 | /** | 139 | /** |
@@ -142,6 +142,8 @@ struct regmap_config { | |||
142 | * 1. page selector register update; | 142 | * 1. page selector register update; |
143 | * 2. access through data window registers. | 143 | * 2. access through data window registers. |
144 | * | 144 | * |
145 | * @name: Descriptive name for diagnostics | ||
146 | * | ||
145 | * @range_min: Address of the lowest register address in virtual range. | 147 | * @range_min: Address of the lowest register address in virtual range. |
146 | * @range_max: Address of the highest register in virtual range. | 148 | * @range_max: Address of the highest register in virtual range. |
147 | * | 149 | * |
@@ -153,6 +155,8 @@ struct regmap_config { | |||
153 | * @window_len: Number of registers in data window. | 155 | * @window_len: Number of registers in data window. |
154 | */ | 156 | */ |
155 | struct regmap_range_cfg { | 157 | struct regmap_range_cfg { |
158 | const char *name; | ||
159 | |||
156 | /* Registers of virtual address range */ | 160 | /* Registers of virtual address range */ |
157 | unsigned int range_min; | 161 | unsigned int range_min; |
158 | unsigned int range_max; | 162 | unsigned int range_max; |
diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h index c64de9dd7631..2f694f3846a9 100644 --- a/include/linux/spi/ads7846.h +++ b/include/linux/spi/ads7846.h | |||
@@ -46,8 +46,9 @@ struct ads7846_platform_data { | |||
46 | u16 debounce_rep; /* additional consecutive good readings | 46 | u16 debounce_rep; /* additional consecutive good readings |
47 | * required after the first two */ | 47 | * required after the first two */ |
48 | int gpio_pendown; /* the GPIO used to decide the pendown | 48 | int gpio_pendown; /* the GPIO used to decide the pendown |
49 | * state if get_pendown_state == NULL | 49 | * state if get_pendown_state == NULL */ |
50 | */ | 50 | int gpio_pendown_debounce; /* platform specific debounce time for |
51 | * the gpio_pendown */ | ||
51 | int (*get_pendown_state)(void); | 52 | int (*get_pendown_state)(void); |
52 | int (*filter_init) (const struct ads7846_platform_data *pdata, | 53 | int (*filter_init) (const struct ads7846_platform_data *pdata, |
53 | void **filter_data); | 54 | void **filter_data); |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 6f0ba01afe73..63445ede48bb 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -1351,7 +1351,7 @@ struct xfrm6_tunnel { | |||
1351 | }; | 1351 | }; |
1352 | 1352 | ||
1353 | extern void xfrm_init(void); | 1353 | extern void xfrm_init(void); |
1354 | extern void xfrm4_init(int rt_hash_size); | 1354 | extern void xfrm4_init(void); |
1355 | extern int xfrm_state_init(struct net *net); | 1355 | extern int xfrm_state_init(struct net *net); |
1356 | extern void xfrm_state_fini(struct net *net); | 1356 | extern void xfrm_state_fini(struct net *net); |
1357 | extern void xfrm4_state_init(void); | 1357 | extern void xfrm4_state_init(void); |
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 88fae8d20154..55367b04dc94 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h | |||
@@ -135,6 +135,8 @@ struct scsi_device { | |||
135 | * because we did a bus reset. */ | 135 | * because we did a bus reset. */ |
136 | unsigned use_10_for_rw:1; /* first try 10-byte read / write */ | 136 | unsigned use_10_for_rw:1; /* first try 10-byte read / write */ |
137 | unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */ | 137 | unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */ |
138 | unsigned no_report_opcodes:1; /* no REPORT SUPPORTED OPERATION CODES */ | ||
139 | unsigned no_write_same:1; /* no WRITE SAME command */ | ||
138 | unsigned skip_ms_page_8:1; /* do not use MODE SENSE page 0x08 */ | 140 | unsigned skip_ms_page_8:1; /* do not use MODE SENSE page 0x08 */ |
139 | unsigned skip_ms_page_3f:1; /* do not use MODE SENSE page 0x3f */ | 141 | unsigned skip_ms_page_3f:1; /* do not use MODE SENSE page 0x3f */ |
140 | unsigned skip_vpd_pages:1; /* do not read VPD pages */ | 142 | unsigned skip_vpd_pages:1; /* do not read VPD pages */ |
@@ -362,6 +364,8 @@ extern int scsi_test_unit_ready(struct scsi_device *sdev, int timeout, | |||
362 | int retries, struct scsi_sense_hdr *sshdr); | 364 | int retries, struct scsi_sense_hdr *sshdr); |
363 | extern int scsi_get_vpd_page(struct scsi_device *, u8 page, unsigned char *buf, | 365 | extern int scsi_get_vpd_page(struct scsi_device *, u8 page, unsigned char *buf, |
364 | int buf_len); | 366 | int buf_len); |
367 | extern int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer, | ||
368 | unsigned int len, unsigned char opcode); | ||
365 | extern int scsi_device_set_state(struct scsi_device *sdev, | 369 | extern int scsi_device_set_state(struct scsi_device *sdev, |
366 | enum scsi_device_state state); | 370 | enum scsi_device_state state); |
367 | extern struct scsi_event *sdev_evt_alloc(enum scsi_device_event evt_type, | 371 | extern struct scsi_event *sdev_evt_alloc(enum scsi_device_event evt_type, |
diff --git a/include/sound/cs4271.h b/include/sound/cs4271.h index 50a059e7d116..6d9e15ed1dcf 100644 --- a/include/sound/cs4271.h +++ b/include/sound/cs4271.h | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | struct cs4271_platform_data { | 20 | struct cs4271_platform_data { |
21 | int gpio_nreset; /* GPIO driving Reset pin, if any */ | 21 | int gpio_nreset; /* GPIO driving Reset pin, if any */ |
22 | int amutec_eq_bmutec:1; /* flag to enable AMUTEC=BMUTEC */ | ||
22 | }; | 23 | }; |
23 | 24 | ||
24 | #endif /* __CS4271_H */ | 25 | #endif /* __CS4271_H */ |
diff --git a/include/sound/sh_fsi.h b/include/sound/sh_fsi.h index 906010344dd7..cc1c919c6436 100644 --- a/include/sound/sh_fsi.h +++ b/include/sound/sh_fsi.h | |||
@@ -26,6 +26,7 @@ | |||
26 | * A: inversion | 26 | * A: inversion |
27 | * B: format mode | 27 | * B: format mode |
28 | * C: chip specific | 28 | * C: chip specific |
29 | * D: clock selecter if master mode | ||
29 | */ | 30 | */ |
30 | 31 | ||
31 | /* A: clock inversion */ | 32 | /* A: clock inversion */ |
@@ -44,6 +45,11 @@ | |||
44 | #define SH_FSI_OPTION_MASK 0x00000F00 | 45 | #define SH_FSI_OPTION_MASK 0x00000F00 |
45 | #define SH_FSI_ENABLE_STREAM_MODE (1 << 8) /* for 16bit data */ | 46 | #define SH_FSI_ENABLE_STREAM_MODE (1 << 8) /* for 16bit data */ |
46 | 47 | ||
48 | /* D: clock selecter if master mode */ | ||
49 | #define SH_FSI_CLK_MASK 0x0000F000 | ||
50 | #define SH_FSI_CLK_EXTERNAL (0 << 12) | ||
51 | #define SH_FSI_CLK_CPG (1 << 12) /* FSIxCK + FSI-DIV */ | ||
52 | |||
47 | /* | 53 | /* |
48 | * set_rate return value | 54 | * set_rate return value |
49 | * | 55 | * |
diff --git a/include/sound/tlv320aic32x4.h b/include/sound/tlv320aic32x4.h index c009f70b4029..24e5d991f148 100644 --- a/include/sound/tlv320aic32x4.h +++ b/include/sound/tlv320aic32x4.h | |||
@@ -26,6 +26,7 @@ struct aic32x4_pdata { | |||
26 | u32 power_cfg; | 26 | u32 power_cfg; |
27 | u32 micpga_routing; | 27 | u32 micpga_routing; |
28 | bool swapdacs; | 28 | bool swapdacs; |
29 | int rstn_gpio; | ||
29 | }; | 30 | }; |
30 | 31 | ||
31 | #endif | 32 | #endif |
diff --git a/lib/mpi/longlong.h b/lib/mpi/longlong.h index 678ce4f1e124..095ab157a521 100644 --- a/lib/mpi/longlong.h +++ b/lib/mpi/longlong.h | |||
@@ -641,7 +641,14 @@ do { \ | |||
641 | ************** MIPS ***************** | 641 | ************** MIPS ***************** |
642 | ***************************************/ | 642 | ***************************************/ |
643 | #if defined(__mips__) && W_TYPE_SIZE == 32 | 643 | #if defined(__mips__) && W_TYPE_SIZE == 32 |
644 | #if __GNUC__ > 2 || __GNUC_MINOR__ >= 7 | 644 | #if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4 |
645 | #define umul_ppmm(w1, w0, u, v) \ | ||
646 | do { \ | ||
647 | UDItype __ll = (UDItype)(u) * (v); \ | ||
648 | w1 = __ll >> 32; \ | ||
649 | w0 = __ll; \ | ||
650 | } while (0) | ||
651 | #elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7 | ||
645 | #define umul_ppmm(w1, w0, u, v) \ | 652 | #define umul_ppmm(w1, w0, u, v) \ |
646 | __asm__ ("multu %2,%3" \ | 653 | __asm__ ("multu %2,%3" \ |
647 | : "=l" ((USItype)(w0)), \ | 654 | : "=l" ((USItype)(w0)), \ |
@@ -666,7 +673,15 @@ do { \ | |||
666 | ************** MIPS/64 ************** | 673 | ************** MIPS/64 ************** |
667 | ***************************************/ | 674 | ***************************************/ |
668 | #if (defined(__mips) && __mips >= 3) && W_TYPE_SIZE == 64 | 675 | #if (defined(__mips) && __mips >= 3) && W_TYPE_SIZE == 64 |
669 | #if __GNUC__ > 2 || __GNUC_MINOR__ >= 7 | 676 | #if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4 |
677 | #define umul_ppmm(w1, w0, u, v) \ | ||
678 | do { \ | ||
679 | typedef unsigned int __ll_UTItype __attribute__((mode(TI))); \ | ||
680 | __ll_UTItype __ll = (__ll_UTItype)(u) * (v); \ | ||
681 | w1 = __ll >> 64; \ | ||
682 | w0 = __ll; \ | ||
683 | } while (0) | ||
684 | #elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7 | ||
670 | #define umul_ppmm(w1, w0, u, v) \ | 685 | #define umul_ppmm(w1, w0, u, v) \ |
671 | __asm__ ("dmultu %2,%3" \ | 686 | __asm__ ("dmultu %2,%3" \ |
672 | : "=l" ((UDItype)(w0)), \ | 687 | : "=l" ((UDItype)(w0)), \ |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 7bb35ac0964a..bcb72c6e2b2d 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -1405,7 +1405,7 @@ int capture_free_page(struct page *page, int alloc_order, int migratetype) | |||
1405 | 1405 | ||
1406 | mt = get_pageblock_migratetype(page); | 1406 | mt = get_pageblock_migratetype(page); |
1407 | if (unlikely(mt != MIGRATE_ISOLATE)) | 1407 | if (unlikely(mt != MIGRATE_ISOLATE)) |
1408 | __mod_zone_freepage_state(zone, -(1UL << order), mt); | 1408 | __mod_zone_freepage_state(zone, -(1UL << alloc_order), mt); |
1409 | 1409 | ||
1410 | if (alloc_order != order) | 1410 | if (alloc_order != order) |
1411 | expand(zone, page, alloc_order, order, | 1411 | expand(zone, page, alloc_order, order, |
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index bcf02f608cbf..017a8bacfb27 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c | |||
@@ -429,6 +429,17 @@ static struct attribute_group netstat_group = { | |||
429 | .name = "statistics", | 429 | .name = "statistics", |
430 | .attrs = netstat_attrs, | 430 | .attrs = netstat_attrs, |
431 | }; | 431 | }; |
432 | |||
433 | #if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211) | ||
434 | static struct attribute *wireless_attrs[] = { | ||
435 | NULL | ||
436 | }; | ||
437 | |||
438 | static struct attribute_group wireless_group = { | ||
439 | .name = "wireless", | ||
440 | .attrs = wireless_attrs, | ||
441 | }; | ||
442 | #endif | ||
432 | #endif /* CONFIG_SYSFS */ | 443 | #endif /* CONFIG_SYSFS */ |
433 | 444 | ||
434 | #ifdef CONFIG_RPS | 445 | #ifdef CONFIG_RPS |
@@ -1409,6 +1420,15 @@ int netdev_register_kobject(struct net_device *net) | |||
1409 | groups++; | 1420 | groups++; |
1410 | 1421 | ||
1411 | *groups++ = &netstat_group; | 1422 | *groups++ = &netstat_group; |
1423 | |||
1424 | #if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211) | ||
1425 | if (net->ieee80211_ptr) | ||
1426 | *groups++ = &wireless_group; | ||
1427 | #if IS_ENABLED(CONFIG_WIRELESS_EXT) | ||
1428 | else if (net->wireless_handlers) | ||
1429 | *groups++ = &wireless_group; | ||
1430 | #endif | ||
1431 | #endif | ||
1412 | #endif /* CONFIG_SYSFS */ | 1432 | #endif /* CONFIG_SYSFS */ |
1413 | 1433 | ||
1414 | error = device_add(dev); | 1434 | error = device_add(dev); |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index a8c651216fa6..df251424d816 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -1785,6 +1785,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res, | |||
1785 | if (dev_out->flags & IFF_LOOPBACK) | 1785 | if (dev_out->flags & IFF_LOOPBACK) |
1786 | flags |= RTCF_LOCAL; | 1786 | flags |= RTCF_LOCAL; |
1787 | 1787 | ||
1788 | do_cache = true; | ||
1788 | if (type == RTN_BROADCAST) { | 1789 | if (type == RTN_BROADCAST) { |
1789 | flags |= RTCF_BROADCAST | RTCF_LOCAL; | 1790 | flags |= RTCF_BROADCAST | RTCF_LOCAL; |
1790 | fi = NULL; | 1791 | fi = NULL; |
@@ -1793,6 +1794,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res, | |||
1793 | if (!ip_check_mc_rcu(in_dev, fl4->daddr, fl4->saddr, | 1794 | if (!ip_check_mc_rcu(in_dev, fl4->daddr, fl4->saddr, |
1794 | fl4->flowi4_proto)) | 1795 | fl4->flowi4_proto)) |
1795 | flags &= ~RTCF_LOCAL; | 1796 | flags &= ~RTCF_LOCAL; |
1797 | else | ||
1798 | do_cache = false; | ||
1796 | /* If multicast route do not exist use | 1799 | /* If multicast route do not exist use |
1797 | * default one, but do not gateway in this case. | 1800 | * default one, but do not gateway in this case. |
1798 | * Yes, it is hack. | 1801 | * Yes, it is hack. |
@@ -1802,8 +1805,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res, | |||
1802 | } | 1805 | } |
1803 | 1806 | ||
1804 | fnhe = NULL; | 1807 | fnhe = NULL; |
1805 | do_cache = fi != NULL; | 1808 | do_cache &= fi != NULL; |
1806 | if (fi) { | 1809 | if (do_cache) { |
1807 | struct rtable __rcu **prth; | 1810 | struct rtable __rcu **prth; |
1808 | struct fib_nh *nh = &FIB_RES_NH(*res); | 1811 | struct fib_nh *nh = &FIB_RES_NH(*res); |
1809 | 1812 | ||
@@ -2597,7 +2600,7 @@ int __init ip_rt_init(void) | |||
2597 | pr_err("Unable to create route proc files\n"); | 2600 | pr_err("Unable to create route proc files\n"); |
2598 | #ifdef CONFIG_XFRM | 2601 | #ifdef CONFIG_XFRM |
2599 | xfrm_init(); | 2602 | xfrm_init(); |
2600 | xfrm4_init(ip_rt_max_size); | 2603 | xfrm4_init(); |
2601 | #endif | 2604 | #endif |
2602 | rtnl_register(PF_INET, RTM_GETROUTE, inet_rtm_getroute, NULL, NULL); | 2605 | rtnl_register(PF_INET, RTM_GETROUTE, inet_rtm_getroute, NULL, NULL); |
2603 | 2606 | ||
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 05c5ab8d983c..3be0ac2c1920 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
@@ -279,19 +279,8 @@ static void __exit xfrm4_policy_fini(void) | |||
279 | xfrm_policy_unregister_afinfo(&xfrm4_policy_afinfo); | 279 | xfrm_policy_unregister_afinfo(&xfrm4_policy_afinfo); |
280 | } | 280 | } |
281 | 281 | ||
282 | void __init xfrm4_init(int rt_max_size) | 282 | void __init xfrm4_init(void) |
283 | { | 283 | { |
284 | /* | ||
285 | * Select a default value for the gc_thresh based on the main route | ||
286 | * table hash size. It seems to me the worst case scenario is when | ||
287 | * we have ipsec operating in transport mode, in which we create a | ||
288 | * dst_entry per socket. The xfrm gc algorithm starts trying to remove | ||
289 | * entries at gc_thresh, and prevents new allocations as 2*gc_thresh | ||
290 | * so lets set an initial xfrm gc_thresh value at the rt_max_size/2. | ||
291 | * That will let us store an ipsec connection per route table entry, | ||
292 | * and start cleaning when were 1/2 full | ||
293 | */ | ||
294 | xfrm4_dst_ops.gc_thresh = rt_max_size/2; | ||
295 | dst_entries_init(&xfrm4_dst_ops); | 284 | dst_entries_init(&xfrm4_dst_ops); |
296 | 285 | ||
297 | xfrm4_state_init(); | 286 | xfrm4_state_init(); |
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index c4f934176cab..30647857a375 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c | |||
@@ -252,6 +252,7 @@ struct dst_entry *inet6_csk_update_pmtu(struct sock *sk, u32 mtu) | |||
252 | return NULL; | 252 | return NULL; |
253 | dst->ops->update_pmtu(dst, sk, NULL, mtu); | 253 | dst->ops->update_pmtu(dst, sk, NULL, mtu); |
254 | 254 | ||
255 | return inet6_csk_route_socket(sk, &fl6); | 255 | dst = inet6_csk_route_socket(sk, &fl6); |
256 | return IS_ERR(dst) ? NULL : dst; | ||
256 | } | 257 | } |
257 | EXPORT_SYMBOL_GPL(inet6_csk_update_pmtu); | 258 | EXPORT_SYMBOL_GPL(inet6_csk_update_pmtu); |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index bf87c70ac6c5..c21e33d1abd0 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -1151,10 +1151,6 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) | |||
1151 | 1151 | ||
1152 | mutex_lock(&sdata->u.ibss.mtx); | 1152 | mutex_lock(&sdata->u.ibss.mtx); |
1153 | 1153 | ||
1154 | sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; | ||
1155 | memset(sdata->u.ibss.bssid, 0, ETH_ALEN); | ||
1156 | sdata->u.ibss.ssid_len = 0; | ||
1157 | |||
1158 | active_ibss = ieee80211_sta_active_ibss(sdata); | 1154 | active_ibss = ieee80211_sta_active_ibss(sdata); |
1159 | 1155 | ||
1160 | if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) { | 1156 | if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) { |
@@ -1175,6 +1171,10 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) | |||
1175 | } | 1171 | } |
1176 | } | 1172 | } |
1177 | 1173 | ||
1174 | ifibss->state = IEEE80211_IBSS_MLME_SEARCH; | ||
1175 | memset(ifibss->bssid, 0, ETH_ALEN); | ||
1176 | ifibss->ssid_len = 0; | ||
1177 | |||
1178 | sta_info_flush(sdata->local, sdata); | 1178 | sta_info_flush(sdata->local, sdata); |
1179 | 1179 | ||
1180 | spin_lock_bh(&ifibss->incomplete_lock); | 1180 | spin_lock_bh(&ifibss->incomplete_lock); |
diff --git a/net/netfilter/ipset/ip_set_hash_ip.c b/net/netfilter/ipset/ip_set_hash_ip.c index ec3dba5dcd62..5c0b78528e55 100644 --- a/net/netfilter/ipset/ip_set_hash_ip.c +++ b/net/netfilter/ipset/ip_set_hash_ip.c | |||
@@ -173,6 +173,7 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
173 | return adtfn(set, &nip, timeout, flags); | 173 | return adtfn(set, &nip, timeout, flags); |
174 | } | 174 | } |
175 | 175 | ||
176 | ip_to = ip; | ||
176 | if (tb[IPSET_ATTR_IP_TO]) { | 177 | if (tb[IPSET_ATTR_IP_TO]) { |
177 | ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); | 178 | ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); |
178 | if (ret) | 179 | if (ret) |
@@ -185,8 +186,7 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
185 | if (!cidr || cidr > 32) | 186 | if (!cidr || cidr > 32) |
186 | return -IPSET_ERR_INVALID_CIDR; | 187 | return -IPSET_ERR_INVALID_CIDR; |
187 | ip_set_mask_from_to(ip, ip_to, cidr); | 188 | ip_set_mask_from_to(ip, ip_to, cidr); |
188 | } else | 189 | } |
189 | ip_to = ip; | ||
190 | 190 | ||
191 | hosts = h->netmask == 32 ? 1 : 2 << (32 - h->netmask - 1); | 191 | hosts = h->netmask == 32 ? 1 : 2 << (32 - h->netmask - 1); |
192 | 192 | ||
diff --git a/net/netfilter/ipset/ip_set_hash_ipport.c b/net/netfilter/ipset/ip_set_hash_ipport.c index 0171f7502fa5..6283351f4eeb 100644 --- a/net/netfilter/ipset/ip_set_hash_ipport.c +++ b/net/netfilter/ipset/ip_set_hash_ipport.c | |||
@@ -162,7 +162,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
162 | const struct ip_set_hash *h = set->data; | 162 | const struct ip_set_hash *h = set->data; |
163 | ipset_adtfn adtfn = set->variant->adt[adt]; | 163 | ipset_adtfn adtfn = set->variant->adt[adt]; |
164 | struct hash_ipport4_elem data = { }; | 164 | struct hash_ipport4_elem data = { }; |
165 | u32 ip, ip_to = 0, p = 0, port, port_to; | 165 | u32 ip, ip_to, p = 0, port, port_to; |
166 | u32 timeout = h->timeout; | 166 | u32 timeout = h->timeout; |
167 | bool with_ports = false; | 167 | bool with_ports = false; |
168 | int ret; | 168 | int ret; |
@@ -210,7 +210,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
210 | return ip_set_eexist(ret, flags) ? 0 : ret; | 210 | return ip_set_eexist(ret, flags) ? 0 : ret; |
211 | } | 211 | } |
212 | 212 | ||
213 | ip = ntohl(data.ip); | 213 | ip_to = ip = ntohl(data.ip); |
214 | if (tb[IPSET_ATTR_IP_TO]) { | 214 | if (tb[IPSET_ATTR_IP_TO]) { |
215 | ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); | 215 | ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); |
216 | if (ret) | 216 | if (ret) |
@@ -223,8 +223,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
223 | if (!cidr || cidr > 32) | 223 | if (!cidr || cidr > 32) |
224 | return -IPSET_ERR_INVALID_CIDR; | 224 | return -IPSET_ERR_INVALID_CIDR; |
225 | ip_set_mask_from_to(ip, ip_to, cidr); | 225 | ip_set_mask_from_to(ip, ip_to, cidr); |
226 | } else | 226 | } |
227 | ip_to = ip; | ||
228 | 227 | ||
229 | port_to = port = ntohs(data.port); | 228 | port_to = port = ntohs(data.port); |
230 | if (with_ports && tb[IPSET_ATTR_PORT_TO]) { | 229 | if (with_ports && tb[IPSET_ATTR_PORT_TO]) { |
diff --git a/net/netfilter/ipset/ip_set_hash_ipportip.c b/net/netfilter/ipset/ip_set_hash_ipportip.c index 6344ef551ec8..6a21271c8d5a 100644 --- a/net/netfilter/ipset/ip_set_hash_ipportip.c +++ b/net/netfilter/ipset/ip_set_hash_ipportip.c | |||
@@ -166,7 +166,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
166 | const struct ip_set_hash *h = set->data; | 166 | const struct ip_set_hash *h = set->data; |
167 | ipset_adtfn adtfn = set->variant->adt[adt]; | 167 | ipset_adtfn adtfn = set->variant->adt[adt]; |
168 | struct hash_ipportip4_elem data = { }; | 168 | struct hash_ipportip4_elem data = { }; |
169 | u32 ip, ip_to = 0, p = 0, port, port_to; | 169 | u32 ip, ip_to, p = 0, port, port_to; |
170 | u32 timeout = h->timeout; | 170 | u32 timeout = h->timeout; |
171 | bool with_ports = false; | 171 | bool with_ports = false; |
172 | int ret; | 172 | int ret; |
@@ -218,7 +218,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
218 | return ip_set_eexist(ret, flags) ? 0 : ret; | 218 | return ip_set_eexist(ret, flags) ? 0 : ret; |
219 | } | 219 | } |
220 | 220 | ||
221 | ip = ntohl(data.ip); | 221 | ip_to = ip = ntohl(data.ip); |
222 | if (tb[IPSET_ATTR_IP_TO]) { | 222 | if (tb[IPSET_ATTR_IP_TO]) { |
223 | ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); | 223 | ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); |
224 | if (ret) | 224 | if (ret) |
@@ -231,8 +231,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
231 | if (!cidr || cidr > 32) | 231 | if (!cidr || cidr > 32) |
232 | return -IPSET_ERR_INVALID_CIDR; | 232 | return -IPSET_ERR_INVALID_CIDR; |
233 | ip_set_mask_from_to(ip, ip_to, cidr); | 233 | ip_set_mask_from_to(ip, ip_to, cidr); |
234 | } else | 234 | } |
235 | ip_to = ip; | ||
236 | 235 | ||
237 | port_to = port = ntohs(data.port); | 236 | port_to = port = ntohs(data.port); |
238 | if (with_ports && tb[IPSET_ATTR_PORT_TO]) { | 237 | if (with_ports && tb[IPSET_ATTR_PORT_TO]) { |
diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c index cb71f9a774e7..2d5cd4ee30eb 100644 --- a/net/netfilter/ipset/ip_set_hash_ipportnet.c +++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c | |||
@@ -215,8 +215,8 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
215 | const struct ip_set_hash *h = set->data; | 215 | const struct ip_set_hash *h = set->data; |
216 | ipset_adtfn adtfn = set->variant->adt[adt]; | 216 | ipset_adtfn adtfn = set->variant->adt[adt]; |
217 | struct hash_ipportnet4_elem data = { .cidr = HOST_MASK - 1 }; | 217 | struct hash_ipportnet4_elem data = { .cidr = HOST_MASK - 1 }; |
218 | u32 ip, ip_to = 0, p = 0, port, port_to; | 218 | u32 ip, ip_to, p = 0, port, port_to; |
219 | u32 ip2_from = 0, ip2_to, ip2_last, ip2; | 219 | u32 ip2_from, ip2_to, ip2_last, ip2; |
220 | u32 timeout = h->timeout; | 220 | u32 timeout = h->timeout; |
221 | bool with_ports = false; | 221 | bool with_ports = false; |
222 | u8 cidr; | 222 | u8 cidr; |
@@ -286,6 +286,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
286 | return ip_set_eexist(ret, flags) ? 0 : ret; | 286 | return ip_set_eexist(ret, flags) ? 0 : ret; |
287 | } | 287 | } |
288 | 288 | ||
289 | ip_to = ip; | ||
289 | if (tb[IPSET_ATTR_IP_TO]) { | 290 | if (tb[IPSET_ATTR_IP_TO]) { |
290 | ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); | 291 | ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); |
291 | if (ret) | 292 | if (ret) |
@@ -306,6 +307,8 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
306 | if (port > port_to) | 307 | if (port > port_to) |
307 | swap(port, port_to); | 308 | swap(port, port_to); |
308 | } | 309 | } |
310 | |||
311 | ip2_to = ip2_from; | ||
309 | if (tb[IPSET_ATTR_IP2_TO]) { | 312 | if (tb[IPSET_ATTR_IP2_TO]) { |
310 | ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP2_TO], &ip2_to); | 313 | ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP2_TO], &ip2_to); |
311 | if (ret) | 314 | if (ret) |
diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c index 8847b4d8be06..701c88a20fea 100644 --- a/net/netfilter/nfnetlink_cttimeout.c +++ b/net/netfilter/nfnetlink_cttimeout.c | |||
@@ -41,7 +41,8 @@ MODULE_DESCRIPTION("cttimeout: Extended Netfilter Connection Tracking timeout tu | |||
41 | static LIST_HEAD(cttimeout_list); | 41 | static LIST_HEAD(cttimeout_list); |
42 | 42 | ||
43 | static const struct nla_policy cttimeout_nla_policy[CTA_TIMEOUT_MAX+1] = { | 43 | static const struct nla_policy cttimeout_nla_policy[CTA_TIMEOUT_MAX+1] = { |
44 | [CTA_TIMEOUT_NAME] = { .type = NLA_NUL_STRING }, | 44 | [CTA_TIMEOUT_NAME] = { .type = NLA_NUL_STRING, |
45 | .len = CTNL_TIMEOUT_NAME_MAX - 1}, | ||
45 | [CTA_TIMEOUT_L3PROTO] = { .type = NLA_U16 }, | 46 | [CTA_TIMEOUT_L3PROTO] = { .type = NLA_U16 }, |
46 | [CTA_TIMEOUT_L4PROTO] = { .type = NLA_U8 }, | 47 | [CTA_TIMEOUT_L4PROTO] = { .type = NLA_U8 }, |
47 | [CTA_TIMEOUT_DATA] = { .type = NLA_NESTED }, | 48 | [CTA_TIMEOUT_DATA] = { .type = NLA_NESTED }, |
diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index cc10d073c338..9e8f4b2801f6 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c | |||
@@ -1210,7 +1210,7 @@ int nfc_llcp_register_device(struct nfc_dev *ndev) | |||
1210 | local->remote_miu = LLCP_DEFAULT_MIU; | 1210 | local->remote_miu = LLCP_DEFAULT_MIU; |
1211 | local->remote_lto = LLCP_DEFAULT_LTO; | 1211 | local->remote_lto = LLCP_DEFAULT_LTO; |
1212 | 1212 | ||
1213 | list_add(&llcp_devices, &local->list); | 1213 | list_add(&local->list, &llcp_devices); |
1214 | 1214 | ||
1215 | return 0; | 1215 | return 0; |
1216 | } | 1216 | } |
diff --git a/scripts/sign-file b/scripts/sign-file index 87ca59d36e7e..974a20b661b7 100755 --- a/scripts/sign-file +++ b/scripts/sign-file | |||
@@ -156,12 +156,12 @@ sub asn1_extract($$@) | |||
156 | 156 | ||
157 | if ($l == 0x1) { | 157 | if ($l == 0x1) { |
158 | $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1)); | 158 | $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1)); |
159 | } elsif ($l = 0x2) { | 159 | } elsif ($l == 0x2) { |
160 | $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0], 2)); | 160 | $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0], 2)); |
161 | } elsif ($l = 0x3) { | 161 | } elsif ($l == 0x3) { |
162 | $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1)) << 16; | 162 | $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1)) << 16; |
163 | $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0] + 1, 2)); | 163 | $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0] + 1, 2)); |
164 | } elsif ($l = 0x4) { | 164 | } elsif ($l == 0x4) { |
165 | $len = unpack("N", substr(${$cursor->[2]}, $cursor->[0], 4)); | 165 | $len = unpack("N", substr(${$cursor->[2]}, $cursor->[0], 4)); |
166 | } else { | 166 | } else { |
167 | die $x509, ": ", $cursor->[0], ": ASN.1 element too long (", $l, ")\n"; | 167 | die $x509, ": ", $cursor->[0], ": ASN.1 element too long (", $l, ")\n"; |
diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c index 28f911cdd7c7..c5454c0477c3 100644 --- a/security/selinux/netnode.c +++ b/security/selinux/netnode.c | |||
@@ -174,7 +174,8 @@ static void sel_netnode_insert(struct sel_netnode *node) | |||
174 | if (sel_netnode_hash[idx].size == SEL_NETNODE_HASH_BKT_LIMIT) { | 174 | if (sel_netnode_hash[idx].size == SEL_NETNODE_HASH_BKT_LIMIT) { |
175 | struct sel_netnode *tail; | 175 | struct sel_netnode *tail; |
176 | tail = list_entry( | 176 | tail = list_entry( |
177 | rcu_dereference(sel_netnode_hash[idx].list.prev), | 177 | rcu_dereference_protected(sel_netnode_hash[idx].list.prev, |
178 | lockdep_is_held(&sel_netnode_lock)), | ||
178 | struct sel_netnode, list); | 179 | struct sel_netnode, list); |
179 | list_del_rcu(&tail->list); | 180 | list_del_rcu(&tail->list); |
180 | kfree_rcu(tail, rcu); | 181 | kfree_rcu(tail, rcu); |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index d05bcbb61077..c5d0472aaba4 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -95,6 +95,7 @@ int snd_hda_delete_codec_preset(struct hda_codec_preset_list *preset) | |||
95 | EXPORT_SYMBOL_HDA(snd_hda_delete_codec_preset); | 95 | EXPORT_SYMBOL_HDA(snd_hda_delete_codec_preset); |
96 | 96 | ||
97 | #ifdef CONFIG_PM | 97 | #ifdef CONFIG_PM |
98 | #define codec_in_pm(codec) ((codec)->in_pm) | ||
98 | static void hda_power_work(struct work_struct *work); | 99 | static void hda_power_work(struct work_struct *work); |
99 | static void hda_keep_power_on(struct hda_codec *codec); | 100 | static void hda_keep_power_on(struct hda_codec *codec); |
100 | #define hda_codec_is_power_on(codec) ((codec)->power_on) | 101 | #define hda_codec_is_power_on(codec) ((codec)->power_on) |
@@ -104,6 +105,7 @@ static inline void hda_call_pm_notify(struct hda_bus *bus, bool power_up) | |||
104 | bus->ops.pm_notify(bus, power_up); | 105 | bus->ops.pm_notify(bus, power_up); |
105 | } | 106 | } |
106 | #else | 107 | #else |
108 | #define codec_in_pm(codec) 0 | ||
107 | static inline void hda_keep_power_on(struct hda_codec *codec) {} | 109 | static inline void hda_keep_power_on(struct hda_codec *codec) {} |
108 | #define hda_codec_is_power_on(codec) 1 | 110 | #define hda_codec_is_power_on(codec) 1 |
109 | #define hda_call_pm_notify(bus, state) {} | 111 | #define hda_call_pm_notify(bus, state) {} |
@@ -228,7 +230,7 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd, | |||
228 | } | 230 | } |
229 | mutex_unlock(&bus->cmd_mutex); | 231 | mutex_unlock(&bus->cmd_mutex); |
230 | snd_hda_power_down(codec); | 232 | snd_hda_power_down(codec); |
231 | if (!codec->in_pm && res && *res == -1 && bus->rirb_error) { | 233 | if (!codec_in_pm(codec) && res && *res == -1 && bus->rirb_error) { |
232 | if (bus->response_reset) { | 234 | if (bus->response_reset) { |
233 | snd_printd("hda_codec: resetting BUS due to " | 235 | snd_printd("hda_codec: resetting BUS due to " |
234 | "fatal communication error\n"); | 236 | "fatal communication error\n"); |
@@ -238,7 +240,7 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd, | |||
238 | goto again; | 240 | goto again; |
239 | } | 241 | } |
240 | /* clear reset-flag when the communication gets recovered */ | 242 | /* clear reset-flag when the communication gets recovered */ |
241 | if (!err || codec->in_pm) | 243 | if (!err || codec_in_pm(codec)) |
242 | bus->response_reset = 0; | 244 | bus->response_reset = 0; |
243 | return err; | 245 | return err; |
244 | } | 246 | } |
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig index 72b09cfd3dc3..d1b691bf8e2d 100644 --- a/sound/soc/atmel/Kconfig +++ b/sound/soc/atmel/Kconfig | |||
@@ -6,6 +6,14 @@ config SND_ATMEL_SOC | |||
6 | the ATMEL SSC interface. You will also need | 6 | the ATMEL SSC interface. You will also need |
7 | to select the audio interfaces to support below. | 7 | to select the audio interfaces to support below. |
8 | 8 | ||
9 | config SND_ATMEL_SOC_PDC | ||
10 | tristate | ||
11 | depends on SND_ATMEL_SOC | ||
12 | |||
13 | config SND_ATMEL_SOC_DMA | ||
14 | tristate | ||
15 | depends on SND_ATMEL_SOC | ||
16 | |||
9 | config SND_ATMEL_SOC_SSC | 17 | config SND_ATMEL_SOC_SSC |
10 | tristate | 18 | tristate |
11 | depends on SND_ATMEL_SOC | 19 | depends on SND_ATMEL_SOC |
@@ -16,8 +24,8 @@ config SND_ATMEL_SOC_SSC | |||
16 | 24 | ||
17 | config SND_AT91_SOC_SAM9G20_WM8731 | 25 | config SND_AT91_SOC_SAM9G20_WM8731 |
18 | tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board" | 26 | tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board" |
19 | depends on ATMEL_SSC && ARCH_AT91SAM9G20 && SND_ATMEL_SOC && \ | 27 | depends on ATMEL_SSC && SND_ATMEL_SOC && AT91_PROGRAMMABLE_CLOCKS |
20 | AT91_PROGRAMMABLE_CLOCKS | 28 | select SND_ATMEL_SOC_PDC |
21 | select SND_ATMEL_SOC_SSC | 29 | select SND_ATMEL_SOC_SSC |
22 | select SND_SOC_WM8731 | 30 | select SND_SOC_WM8731 |
23 | help | 31 | help |
@@ -27,6 +35,7 @@ config SND_AT91_SOC_SAM9G20_WM8731 | |||
27 | config SND_AT91_SOC_AFEB9260 | 35 | config SND_AT91_SOC_AFEB9260 |
28 | tristate "SoC Audio support for AFEB9260 board" | 36 | tristate "SoC Audio support for AFEB9260 board" |
29 | depends on ATMEL_SSC && ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC | 37 | depends on ATMEL_SSC && ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC |
38 | select SND_ATMEL_SOC_PDC | ||
30 | select SND_ATMEL_SOC_SSC | 39 | select SND_ATMEL_SOC_SSC |
31 | select SND_SOC_TLV320AIC23 | 40 | select SND_SOC_TLV320AIC23 |
32 | help | 41 | help |
diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile index a5c0bf19da78..41967ccb6f41 100644 --- a/sound/soc/atmel/Makefile +++ b/sound/soc/atmel/Makefile | |||
@@ -1,8 +1,12 @@ | |||
1 | # AT91 Platform Support | 1 | # AT91 Platform Support |
2 | snd-soc-atmel-pcm-objs := atmel-pcm.o | 2 | snd-soc-atmel-pcm-objs := atmel-pcm.o |
3 | snd-soc-atmel-pcm-pdc-objs := atmel-pcm-pdc.o | ||
4 | snd-soc-atmel-pcm-dma-objs := atmel-pcm-dma.o | ||
3 | snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o | 5 | snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o |
4 | 6 | ||
5 | obj-$(CONFIG_SND_ATMEL_SOC) += snd-soc-atmel-pcm.o | 7 | obj-$(CONFIG_SND_ATMEL_SOC) += snd-soc-atmel-pcm.o |
8 | obj-$(CONFIG_SND_ATMEL_SOC_PDC) += snd-soc-atmel-pcm-pdc.o | ||
9 | obj-$(CONFIG_SND_ATMEL_SOC_DMA) += snd-soc-atmel-pcm-dma.o | ||
6 | obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o | 10 | obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o |
7 | 11 | ||
8 | # AT91 Machine Support | 12 | # AT91 Machine Support |
diff --git a/sound/soc/atmel/atmel-pcm-dma.c b/sound/soc/atmel/atmel-pcm-dma.c new file mode 100644 index 000000000000..30184a4a147a --- /dev/null +++ b/sound/soc/atmel/atmel-pcm-dma.c | |||
@@ -0,0 +1,240 @@ | |||
1 | /* | ||
2 | * atmel-pcm-dma.c -- ALSA PCM DMA support for the Atmel SoC. | ||
3 | * | ||
4 | * Copyright (C) 2012 Atmel | ||
5 | * | ||
6 | * Author: Bo Shen <voice.shen@atmel.com> | ||
7 | * | ||
8 | * Based on atmel-pcm by: | ||
9 | * Sedji Gaouaou <sedji.gaouaou@atmel.com> | ||
10 | * Copyright 2008 Atmel | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2 of the License, or | ||
15 | * (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
25 | */ | ||
26 | |||
27 | #include <linux/module.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/platform_device.h> | ||
30 | #include <linux/slab.h> | ||
31 | #include <linux/dma-mapping.h> | ||
32 | #include <linux/dmaengine.h> | ||
33 | #include <linux/atmel-ssc.h> | ||
34 | #include <linux/platform_data/dma-atmel.h> | ||
35 | |||
36 | #include <sound/core.h> | ||
37 | #include <sound/pcm.h> | ||
38 | #include <sound/pcm_params.h> | ||
39 | #include <sound/soc.h> | ||
40 | #include <sound/dmaengine_pcm.h> | ||
41 | |||
42 | #include "atmel-pcm.h" | ||
43 | |||
44 | /*--------------------------------------------------------------------------*\ | ||
45 | * Hardware definition | ||
46 | \*--------------------------------------------------------------------------*/ | ||
47 | static const struct snd_pcm_hardware atmel_pcm_dma_hardware = { | ||
48 | .info = SNDRV_PCM_INFO_MMAP | | ||
49 | SNDRV_PCM_INFO_MMAP_VALID | | ||
50 | SNDRV_PCM_INFO_INTERLEAVED | | ||
51 | SNDRV_PCM_INFO_RESUME | | ||
52 | SNDRV_PCM_INFO_PAUSE, | ||
53 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
54 | .period_bytes_min = 256, /* lighting DMA overhead */ | ||
55 | .period_bytes_max = 2 * 0xffff, /* if 2 bytes format */ | ||
56 | .periods_min = 8, | ||
57 | .periods_max = 1024, /* no limit */ | ||
58 | .buffer_bytes_max = ATMEL_SSC_DMABUF_SIZE, | ||
59 | }; | ||
60 | |||
61 | /** | ||
62 | * atmel_pcm_dma_irq: SSC interrupt handler for DMAENGINE enabled SSC | ||
63 | * | ||
64 | * We use DMAENGINE to send/receive data to/from SSC so this ISR is only to | ||
65 | * check if any overrun occured. | ||
66 | */ | ||
67 | static void atmel_pcm_dma_irq(u32 ssc_sr, | ||
68 | struct snd_pcm_substream *substream) | ||
69 | { | ||
70 | struct atmel_pcm_dma_params *prtd; | ||
71 | |||
72 | prtd = snd_dmaengine_pcm_get_data(substream); | ||
73 | |||
74 | if (ssc_sr & prtd->mask->ssc_error) { | ||
75 | if (snd_pcm_running(substream)) | ||
76 | pr_warn("atmel-pcm: buffer %s on %s (SSC_SR=%#x)\n", | ||
77 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK | ||
78 | ? "underrun" : "overrun", prtd->name, | ||
79 | ssc_sr); | ||
80 | |||
81 | /* stop RX and capture: will be enabled again at restart */ | ||
82 | ssc_writex(prtd->ssc->regs, SSC_CR, prtd->mask->ssc_disable); | ||
83 | snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); | ||
84 | |||
85 | /* now drain RHR and read status to remove xrun condition */ | ||
86 | ssc_readx(prtd->ssc->regs, SSC_RHR); | ||
87 | ssc_readx(prtd->ssc->regs, SSC_SR); | ||
88 | } | ||
89 | } | ||
90 | |||
91 | /*--------------------------------------------------------------------------*\ | ||
92 | * DMAENGINE operations | ||
93 | \*--------------------------------------------------------------------------*/ | ||
94 | static bool filter(struct dma_chan *chan, void *slave) | ||
95 | { | ||
96 | struct at_dma_slave *sl = slave; | ||
97 | |||
98 | if (sl->dma_dev == chan->device->dev) { | ||
99 | chan->private = sl; | ||
100 | return true; | ||
101 | } else { | ||
102 | return false; | ||
103 | } | ||
104 | } | ||
105 | |||
106 | static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream, | ||
107 | struct snd_pcm_hw_params *params) | ||
108 | { | ||
109 | struct atmel_pcm_dma_params *prtd; | ||
110 | struct ssc_device *ssc; | ||
111 | struct dma_chan *dma_chan; | ||
112 | struct dma_slave_config slave_config; | ||
113 | int ret; | ||
114 | |||
115 | prtd = snd_dmaengine_pcm_get_data(substream); | ||
116 | ssc = prtd->ssc; | ||
117 | |||
118 | ret = snd_hwparams_to_dma_slave_config(substream, params, | ||
119 | &slave_config); | ||
120 | if (ret) { | ||
121 | pr_err("atmel-pcm: hwparams to dma slave configure failed\n"); | ||
122 | return ret; | ||
123 | } | ||
124 | |||
125 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
126 | slave_config.dst_addr = (dma_addr_t)ssc->phybase + SSC_THR; | ||
127 | slave_config.dst_maxburst = 1; | ||
128 | } else { | ||
129 | slave_config.src_addr = (dma_addr_t)ssc->phybase + SSC_RHR; | ||
130 | slave_config.src_maxburst = 1; | ||
131 | } | ||
132 | |||
133 | slave_config.device_fc = false; | ||
134 | |||
135 | dma_chan = snd_dmaengine_pcm_get_chan(substream); | ||
136 | if (dmaengine_slave_config(dma_chan, &slave_config)) { | ||
137 | pr_err("atmel-pcm: failed to configure dma channel\n"); | ||
138 | ret = -EBUSY; | ||
139 | return ret; | ||
140 | } | ||
141 | |||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | static int atmel_pcm_hw_params(struct snd_pcm_substream *substream, | ||
146 | struct snd_pcm_hw_params *params) | ||
147 | { | ||
148 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
149 | struct atmel_pcm_dma_params *prtd; | ||
150 | struct ssc_device *ssc; | ||
151 | struct at_dma_slave *sdata = NULL; | ||
152 | int ret; | ||
153 | |||
154 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | ||
155 | |||
156 | prtd = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | ||
157 | ssc = prtd->ssc; | ||
158 | if (ssc->pdev) | ||
159 | sdata = ssc->pdev->dev.platform_data; | ||
160 | |||
161 | ret = snd_dmaengine_pcm_open(substream, filter, sdata); | ||
162 | if (ret) { | ||
163 | pr_err("atmel-pcm: dmaengine pcm open failed\n"); | ||
164 | return -EINVAL; | ||
165 | } | ||
166 | |||
167 | snd_dmaengine_pcm_set_data(substream, prtd); | ||
168 | |||
169 | ret = atmel_pcm_configure_dma(substream, params); | ||
170 | if (ret) { | ||
171 | pr_err("atmel-pcm: failed to configure dmai\n"); | ||
172 | goto err; | ||
173 | } | ||
174 | |||
175 | prtd->dma_intr_handler = atmel_pcm_dma_irq; | ||
176 | |||
177 | return 0; | ||
178 | err: | ||
179 | snd_dmaengine_pcm_close(substream); | ||
180 | return ret; | ||
181 | } | ||
182 | |||
183 | static int atmel_pcm_dma_prepare(struct snd_pcm_substream *substream) | ||
184 | { | ||
185 | struct atmel_pcm_dma_params *prtd; | ||
186 | |||
187 | prtd = snd_dmaengine_pcm_get_data(substream); | ||
188 | |||
189 | ssc_writex(prtd->ssc->regs, SSC_IER, prtd->mask->ssc_error); | ||
190 | ssc_writex(prtd->ssc->regs, SSC_CR, prtd->mask->ssc_enable); | ||
191 | |||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | static int atmel_pcm_open(struct snd_pcm_substream *substream) | ||
196 | { | ||
197 | snd_soc_set_runtime_hwparams(substream, &atmel_pcm_dma_hardware); | ||
198 | |||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | static int atmel_pcm_close(struct snd_pcm_substream *substream) | ||
203 | { | ||
204 | snd_dmaengine_pcm_close(substream); | ||
205 | |||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | static struct snd_pcm_ops atmel_pcm_ops = { | ||
210 | .open = atmel_pcm_open, | ||
211 | .close = atmel_pcm_close, | ||
212 | .ioctl = snd_pcm_lib_ioctl, | ||
213 | .hw_params = atmel_pcm_hw_params, | ||
214 | .prepare = atmel_pcm_dma_prepare, | ||
215 | .trigger = snd_dmaengine_pcm_trigger, | ||
216 | .pointer = snd_dmaengine_pcm_pointer_no_residue, | ||
217 | .mmap = atmel_pcm_mmap, | ||
218 | }; | ||
219 | |||
220 | static struct snd_soc_platform_driver atmel_soc_platform = { | ||
221 | .ops = &atmel_pcm_ops, | ||
222 | .pcm_new = atmel_pcm_new, | ||
223 | .pcm_free = atmel_pcm_free, | ||
224 | }; | ||
225 | |||
226 | int atmel_pcm_dma_platform_register(struct device *dev) | ||
227 | { | ||
228 | return snd_soc_register_platform(dev, &atmel_soc_platform); | ||
229 | } | ||
230 | EXPORT_SYMBOL(atmel_pcm_dma_platform_register); | ||
231 | |||
232 | void atmel_pcm_dma_platform_unregister(struct device *dev) | ||
233 | { | ||
234 | snd_soc_unregister_platform(dev); | ||
235 | } | ||
236 | EXPORT_SYMBOL(atmel_pcm_dma_platform_unregister); | ||
237 | |||
238 | MODULE_AUTHOR("Bo Shen <voice.shen@atmel.com>"); | ||
239 | MODULE_DESCRIPTION("Atmel DMA based PCM module"); | ||
240 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/atmel/atmel-pcm-pdc.c b/sound/soc/atmel/atmel-pcm-pdc.c new file mode 100644 index 000000000000..6a293c713a38 --- /dev/null +++ b/sound/soc/atmel/atmel-pcm-pdc.c | |||
@@ -0,0 +1,401 @@ | |||
1 | /* | ||
2 | * atmel-pcm.c -- ALSA PCM interface for the Atmel atmel SoC. | ||
3 | * | ||
4 | * Copyright (C) 2005 SAN People | ||
5 | * Copyright (C) 2008 Atmel | ||
6 | * | ||
7 | * Authors: Sedji Gaouaou <sedji.gaouaou@atmel.com> | ||
8 | * | ||
9 | * Based on at91-pcm. by: | ||
10 | * Frank Mandarino <fmandarino@endrelia.com> | ||
11 | * Copyright 2006 Endrelia Technologies Inc. | ||
12 | * | ||
13 | * Based on pxa2xx-pcm.c by: | ||
14 | * | ||
15 | * Author: Nicolas Pitre | ||
16 | * Created: Nov 30, 2004 | ||
17 | * Copyright: (C) 2004 MontaVista Software, Inc. | ||
18 | * | ||
19 | * This program is free software; you can redistribute it and/or modify | ||
20 | * it under the terms of the GNU General Public License as published by | ||
21 | * the Free Software Foundation; either version 2 of the License, or | ||
22 | * (at your option) any later version. | ||
23 | * | ||
24 | * This program is distributed in the hope that it will be useful, | ||
25 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
26 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
27 | * GNU General Public License for more details. | ||
28 | * | ||
29 | * You should have received a copy of the GNU General Public License | ||
30 | * along with this program; if not, write to the Free Software | ||
31 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
32 | */ | ||
33 | |||
34 | #include <linux/module.h> | ||
35 | #include <linux/init.h> | ||
36 | #include <linux/platform_device.h> | ||
37 | #include <linux/slab.h> | ||
38 | #include <linux/dma-mapping.h> | ||
39 | #include <linux/atmel_pdc.h> | ||
40 | #include <linux/atmel-ssc.h> | ||
41 | |||
42 | #include <sound/core.h> | ||
43 | #include <sound/pcm.h> | ||
44 | #include <sound/pcm_params.h> | ||
45 | #include <sound/soc.h> | ||
46 | |||
47 | #include "atmel-pcm.h" | ||
48 | |||
49 | |||
50 | /*--------------------------------------------------------------------------*\ | ||
51 | * Hardware definition | ||
52 | \*--------------------------------------------------------------------------*/ | ||
53 | /* TODO: These values were taken from the AT91 platform driver, check | ||
54 | * them against real values for AT32 | ||
55 | */ | ||
56 | static const struct snd_pcm_hardware atmel_pcm_hardware = { | ||
57 | .info = SNDRV_PCM_INFO_MMAP | | ||
58 | SNDRV_PCM_INFO_MMAP_VALID | | ||
59 | SNDRV_PCM_INFO_INTERLEAVED | | ||
60 | SNDRV_PCM_INFO_PAUSE, | ||
61 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
62 | .period_bytes_min = 32, | ||
63 | .period_bytes_max = 8192, | ||
64 | .periods_min = 2, | ||
65 | .periods_max = 1024, | ||
66 | .buffer_bytes_max = ATMEL_SSC_DMABUF_SIZE, | ||
67 | }; | ||
68 | |||
69 | |||
70 | /*--------------------------------------------------------------------------*\ | ||
71 | * Data types | ||
72 | \*--------------------------------------------------------------------------*/ | ||
73 | struct atmel_runtime_data { | ||
74 | struct atmel_pcm_dma_params *params; | ||
75 | dma_addr_t dma_buffer; /* physical address of dma buffer */ | ||
76 | dma_addr_t dma_buffer_end; /* first address beyond DMA buffer */ | ||
77 | size_t period_size; | ||
78 | |||
79 | dma_addr_t period_ptr; /* physical address of next period */ | ||
80 | |||
81 | /* PDC register save */ | ||
82 | u32 pdc_xpr_save; | ||
83 | u32 pdc_xcr_save; | ||
84 | u32 pdc_xnpr_save; | ||
85 | u32 pdc_xncr_save; | ||
86 | }; | ||
87 | |||
88 | /*--------------------------------------------------------------------------*\ | ||
89 | * ISR | ||
90 | \*--------------------------------------------------------------------------*/ | ||
91 | static void atmel_pcm_dma_irq(u32 ssc_sr, | ||
92 | struct snd_pcm_substream *substream) | ||
93 | { | ||
94 | struct atmel_runtime_data *prtd = substream->runtime->private_data; | ||
95 | struct atmel_pcm_dma_params *params = prtd->params; | ||
96 | static int count; | ||
97 | |||
98 | count++; | ||
99 | |||
100 | if (ssc_sr & params->mask->ssc_endbuf) { | ||
101 | pr_warn("atmel-pcm: buffer %s on %s (SSC_SR=%#x, count=%d)\n", | ||
102 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK | ||
103 | ? "underrun" : "overrun", | ||
104 | params->name, ssc_sr, count); | ||
105 | |||
106 | /* re-start the PDC */ | ||
107 | ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, | ||
108 | params->mask->pdc_disable); | ||
109 | prtd->period_ptr += prtd->period_size; | ||
110 | if (prtd->period_ptr >= prtd->dma_buffer_end) | ||
111 | prtd->period_ptr = prtd->dma_buffer; | ||
112 | |||
113 | ssc_writex(params->ssc->regs, params->pdc->xpr, | ||
114 | prtd->period_ptr); | ||
115 | ssc_writex(params->ssc->regs, params->pdc->xcr, | ||
116 | prtd->period_size / params->pdc_xfer_size); | ||
117 | ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, | ||
118 | params->mask->pdc_enable); | ||
119 | } | ||
120 | |||
121 | if (ssc_sr & params->mask->ssc_endx) { | ||
122 | /* Load the PDC next pointer and counter registers */ | ||
123 | prtd->period_ptr += prtd->period_size; | ||
124 | if (prtd->period_ptr >= prtd->dma_buffer_end) | ||
125 | prtd->period_ptr = prtd->dma_buffer; | ||
126 | |||
127 | ssc_writex(params->ssc->regs, params->pdc->xnpr, | ||
128 | prtd->period_ptr); | ||
129 | ssc_writex(params->ssc->regs, params->pdc->xncr, | ||
130 | prtd->period_size / params->pdc_xfer_size); | ||
131 | } | ||
132 | |||
133 | snd_pcm_period_elapsed(substream); | ||
134 | } | ||
135 | |||
136 | |||
137 | /*--------------------------------------------------------------------------*\ | ||
138 | * PCM operations | ||
139 | \*--------------------------------------------------------------------------*/ | ||
140 | static int atmel_pcm_hw_params(struct snd_pcm_substream *substream, | ||
141 | struct snd_pcm_hw_params *params) | ||
142 | { | ||
143 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
144 | struct atmel_runtime_data *prtd = runtime->private_data; | ||
145 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
146 | |||
147 | /* this may get called several times by oss emulation | ||
148 | * with different params */ | ||
149 | |||
150 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | ||
151 | runtime->dma_bytes = params_buffer_bytes(params); | ||
152 | |||
153 | prtd->params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | ||
154 | prtd->params->dma_intr_handler = atmel_pcm_dma_irq; | ||
155 | |||
156 | prtd->dma_buffer = runtime->dma_addr; | ||
157 | prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes; | ||
158 | prtd->period_size = params_period_bytes(params); | ||
159 | |||
160 | pr_debug("atmel-pcm: " | ||
161 | "hw_params: DMA for %s initialized " | ||
162 | "(dma_bytes=%u, period_size=%u)\n", | ||
163 | prtd->params->name, | ||
164 | runtime->dma_bytes, | ||
165 | prtd->period_size); | ||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | static int atmel_pcm_hw_free(struct snd_pcm_substream *substream) | ||
170 | { | ||
171 | struct atmel_runtime_data *prtd = substream->runtime->private_data; | ||
172 | struct atmel_pcm_dma_params *params = prtd->params; | ||
173 | |||
174 | if (params != NULL) { | ||
175 | ssc_writex(params->ssc->regs, SSC_PDC_PTCR, | ||
176 | params->mask->pdc_disable); | ||
177 | prtd->params->dma_intr_handler = NULL; | ||
178 | } | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | static int atmel_pcm_prepare(struct snd_pcm_substream *substream) | ||
184 | { | ||
185 | struct atmel_runtime_data *prtd = substream->runtime->private_data; | ||
186 | struct atmel_pcm_dma_params *params = prtd->params; | ||
187 | |||
188 | ssc_writex(params->ssc->regs, SSC_IDR, | ||
189 | params->mask->ssc_endx | params->mask->ssc_endbuf); | ||
190 | ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, | ||
191 | params->mask->pdc_disable); | ||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | static int atmel_pcm_trigger(struct snd_pcm_substream *substream, | ||
196 | int cmd) | ||
197 | { | ||
198 | struct snd_pcm_runtime *rtd = substream->runtime; | ||
199 | struct atmel_runtime_data *prtd = rtd->private_data; | ||
200 | struct atmel_pcm_dma_params *params = prtd->params; | ||
201 | int ret = 0; | ||
202 | |||
203 | pr_debug("atmel-pcm:buffer_size = %ld," | ||
204 | "dma_area = %p, dma_bytes = %u\n", | ||
205 | rtd->buffer_size, rtd->dma_area, rtd->dma_bytes); | ||
206 | |||
207 | switch (cmd) { | ||
208 | case SNDRV_PCM_TRIGGER_START: | ||
209 | prtd->period_ptr = prtd->dma_buffer; | ||
210 | |||
211 | ssc_writex(params->ssc->regs, params->pdc->xpr, | ||
212 | prtd->period_ptr); | ||
213 | ssc_writex(params->ssc->regs, params->pdc->xcr, | ||
214 | prtd->period_size / params->pdc_xfer_size); | ||
215 | |||
216 | prtd->period_ptr += prtd->period_size; | ||
217 | ssc_writex(params->ssc->regs, params->pdc->xnpr, | ||
218 | prtd->period_ptr); | ||
219 | ssc_writex(params->ssc->regs, params->pdc->xncr, | ||
220 | prtd->period_size / params->pdc_xfer_size); | ||
221 | |||
222 | pr_debug("atmel-pcm: trigger: " | ||
223 | "period_ptr=%lx, xpr=%u, " | ||
224 | "xcr=%u, xnpr=%u, xncr=%u\n", | ||
225 | (unsigned long)prtd->period_ptr, | ||
226 | ssc_readx(params->ssc->regs, params->pdc->xpr), | ||
227 | ssc_readx(params->ssc->regs, params->pdc->xcr), | ||
228 | ssc_readx(params->ssc->regs, params->pdc->xnpr), | ||
229 | ssc_readx(params->ssc->regs, params->pdc->xncr)); | ||
230 | |||
231 | ssc_writex(params->ssc->regs, SSC_IER, | ||
232 | params->mask->ssc_endx | params->mask->ssc_endbuf); | ||
233 | ssc_writex(params->ssc->regs, SSC_PDC_PTCR, | ||
234 | params->mask->pdc_enable); | ||
235 | |||
236 | pr_debug("sr=%u imr=%u\n", | ||
237 | ssc_readx(params->ssc->regs, SSC_SR), | ||
238 | ssc_readx(params->ssc->regs, SSC_IER)); | ||
239 | break; /* SNDRV_PCM_TRIGGER_START */ | ||
240 | |||
241 | case SNDRV_PCM_TRIGGER_STOP: | ||
242 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
243 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
244 | ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, | ||
245 | params->mask->pdc_disable); | ||
246 | break; | ||
247 | |||
248 | case SNDRV_PCM_TRIGGER_RESUME: | ||
249 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
250 | ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, | ||
251 | params->mask->pdc_enable); | ||
252 | break; | ||
253 | |||
254 | default: | ||
255 | ret = -EINVAL; | ||
256 | } | ||
257 | |||
258 | return ret; | ||
259 | } | ||
260 | |||
261 | static snd_pcm_uframes_t atmel_pcm_pointer( | ||
262 | struct snd_pcm_substream *substream) | ||
263 | { | ||
264 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
265 | struct atmel_runtime_data *prtd = runtime->private_data; | ||
266 | struct atmel_pcm_dma_params *params = prtd->params; | ||
267 | dma_addr_t ptr; | ||
268 | snd_pcm_uframes_t x; | ||
269 | |||
270 | ptr = (dma_addr_t) ssc_readx(params->ssc->regs, params->pdc->xpr); | ||
271 | x = bytes_to_frames(runtime, ptr - prtd->dma_buffer); | ||
272 | |||
273 | if (x == runtime->buffer_size) | ||
274 | x = 0; | ||
275 | |||
276 | return x; | ||
277 | } | ||
278 | |||
279 | static int atmel_pcm_open(struct snd_pcm_substream *substream) | ||
280 | { | ||
281 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
282 | struct atmel_runtime_data *prtd; | ||
283 | int ret = 0; | ||
284 | |||
285 | snd_soc_set_runtime_hwparams(substream, &atmel_pcm_hardware); | ||
286 | |||
287 | /* ensure that buffer size is a multiple of period size */ | ||
288 | ret = snd_pcm_hw_constraint_integer(runtime, | ||
289 | SNDRV_PCM_HW_PARAM_PERIODS); | ||
290 | if (ret < 0) | ||
291 | goto out; | ||
292 | |||
293 | prtd = kzalloc(sizeof(struct atmel_runtime_data), GFP_KERNEL); | ||
294 | if (prtd == NULL) { | ||
295 | ret = -ENOMEM; | ||
296 | goto out; | ||
297 | } | ||
298 | runtime->private_data = prtd; | ||
299 | |||
300 | out: | ||
301 | return ret; | ||
302 | } | ||
303 | |||
304 | static int atmel_pcm_close(struct snd_pcm_substream *substream) | ||
305 | { | ||
306 | struct atmel_runtime_data *prtd = substream->runtime->private_data; | ||
307 | |||
308 | kfree(prtd); | ||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | static struct snd_pcm_ops atmel_pcm_ops = { | ||
313 | .open = atmel_pcm_open, | ||
314 | .close = atmel_pcm_close, | ||
315 | .ioctl = snd_pcm_lib_ioctl, | ||
316 | .hw_params = atmel_pcm_hw_params, | ||
317 | .hw_free = atmel_pcm_hw_free, | ||
318 | .prepare = atmel_pcm_prepare, | ||
319 | .trigger = atmel_pcm_trigger, | ||
320 | .pointer = atmel_pcm_pointer, | ||
321 | .mmap = atmel_pcm_mmap, | ||
322 | }; | ||
323 | |||
324 | |||
325 | /*--------------------------------------------------------------------------*\ | ||
326 | * ASoC platform driver | ||
327 | \*--------------------------------------------------------------------------*/ | ||
328 | #ifdef CONFIG_PM | ||
329 | static int atmel_pcm_suspend(struct snd_soc_dai *dai) | ||
330 | { | ||
331 | struct snd_pcm_runtime *runtime = dai->runtime; | ||
332 | struct atmel_runtime_data *prtd; | ||
333 | struct atmel_pcm_dma_params *params; | ||
334 | |||
335 | if (!runtime) | ||
336 | return 0; | ||
337 | |||
338 | prtd = runtime->private_data; | ||
339 | params = prtd->params; | ||
340 | |||
341 | /* disable the PDC and save the PDC registers */ | ||
342 | |||
343 | ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_disable); | ||
344 | |||
345 | prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr); | ||
346 | prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr); | ||
347 | prtd->pdc_xnpr_save = ssc_readx(params->ssc->regs, params->pdc->xnpr); | ||
348 | prtd->pdc_xncr_save = ssc_readx(params->ssc->regs, params->pdc->xncr); | ||
349 | |||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | static int atmel_pcm_resume(struct snd_soc_dai *dai) | ||
354 | { | ||
355 | struct snd_pcm_runtime *runtime = dai->runtime; | ||
356 | struct atmel_runtime_data *prtd; | ||
357 | struct atmel_pcm_dma_params *params; | ||
358 | |||
359 | if (!runtime) | ||
360 | return 0; | ||
361 | |||
362 | prtd = runtime->private_data; | ||
363 | params = prtd->params; | ||
364 | |||
365 | /* restore the PDC registers and enable the PDC */ | ||
366 | ssc_writex(params->ssc->regs, params->pdc->xpr, prtd->pdc_xpr_save); | ||
367 | ssc_writex(params->ssc->regs, params->pdc->xcr, prtd->pdc_xcr_save); | ||
368 | ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save); | ||
369 | ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save); | ||
370 | |||
371 | ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_enable); | ||
372 | return 0; | ||
373 | } | ||
374 | #else | ||
375 | #define atmel_pcm_suspend NULL | ||
376 | #define atmel_pcm_resume NULL | ||
377 | #endif | ||
378 | |||
379 | static struct snd_soc_platform_driver atmel_soc_platform = { | ||
380 | .ops = &atmel_pcm_ops, | ||
381 | .pcm_new = atmel_pcm_new, | ||
382 | .pcm_free = atmel_pcm_free, | ||
383 | .suspend = atmel_pcm_suspend, | ||
384 | .resume = atmel_pcm_resume, | ||
385 | }; | ||
386 | |||
387 | int atmel_pcm_pdc_platform_register(struct device *dev) | ||
388 | { | ||
389 | return snd_soc_register_platform(dev, &atmel_soc_platform); | ||
390 | } | ||
391 | EXPORT_SYMBOL(atmel_pcm_pdc_platform_register); | ||
392 | |||
393 | void atmel_pcm_pdc_platform_unregister(struct device *dev) | ||
394 | { | ||
395 | snd_soc_unregister_platform(dev); | ||
396 | } | ||
397 | EXPORT_SYMBOL(atmel_pcm_pdc_platform_unregister); | ||
398 | |||
399 | MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>"); | ||
400 | MODULE_DESCRIPTION("Atmel PCM module"); | ||
401 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c index 9b84f985770e..e99f1811300a 100644 --- a/sound/soc/atmel/atmel-pcm.c +++ b/sound/soc/atmel/atmel-pcm.c | |||
@@ -32,80 +32,25 @@ | |||
32 | */ | 32 | */ |
33 | 33 | ||
34 | #include <linux/module.h> | 34 | #include <linux/module.h> |
35 | #include <linux/init.h> | ||
36 | #include <linux/platform_device.h> | ||
37 | #include <linux/slab.h> | ||
38 | #include <linux/dma-mapping.h> | 35 | #include <linux/dma-mapping.h> |
39 | #include <linux/atmel_pdc.h> | ||
40 | #include <linux/atmel-ssc.h> | ||
41 | |||
42 | #include <sound/core.h> | ||
43 | #include <sound/pcm.h> | 36 | #include <sound/pcm.h> |
44 | #include <sound/pcm_params.h> | ||
45 | #include <sound/soc.h> | 37 | #include <sound/soc.h> |
46 | |||
47 | #include "atmel-pcm.h" | 38 | #include "atmel-pcm.h" |
48 | 39 | ||
49 | |||
50 | /*--------------------------------------------------------------------------*\ | ||
51 | * Hardware definition | ||
52 | \*--------------------------------------------------------------------------*/ | ||
53 | /* TODO: These values were taken from the AT91 platform driver, check | ||
54 | * them against real values for AT32 | ||
55 | */ | ||
56 | static const struct snd_pcm_hardware atmel_pcm_hardware = { | ||
57 | .info = SNDRV_PCM_INFO_MMAP | | ||
58 | SNDRV_PCM_INFO_MMAP_VALID | | ||
59 | SNDRV_PCM_INFO_INTERLEAVED | | ||
60 | SNDRV_PCM_INFO_PAUSE, | ||
61 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
62 | .period_bytes_min = 32, | ||
63 | .period_bytes_max = 8192, | ||
64 | .periods_min = 2, | ||
65 | .periods_max = 1024, | ||
66 | .buffer_bytes_max = 32 * 1024, | ||
67 | }; | ||
68 | |||
69 | |||
70 | /*--------------------------------------------------------------------------*\ | ||
71 | * Data types | ||
72 | \*--------------------------------------------------------------------------*/ | ||
73 | struct atmel_runtime_data { | ||
74 | struct atmel_pcm_dma_params *params; | ||
75 | dma_addr_t dma_buffer; /* physical address of dma buffer */ | ||
76 | dma_addr_t dma_buffer_end; /* first address beyond DMA buffer */ | ||
77 | size_t period_size; | ||
78 | |||
79 | dma_addr_t period_ptr; /* physical address of next period */ | ||
80 | |||
81 | /* PDC register save */ | ||
82 | u32 pdc_xpr_save; | ||
83 | u32 pdc_xcr_save; | ||
84 | u32 pdc_xnpr_save; | ||
85 | u32 pdc_xncr_save; | ||
86 | }; | ||
87 | |||
88 | |||
89 | /*--------------------------------------------------------------------------*\ | ||
90 | * Helper functions | ||
91 | \*--------------------------------------------------------------------------*/ | ||
92 | static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, | 40 | static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, |
93 | int stream) | 41 | int stream) |
94 | { | 42 | { |
95 | struct snd_pcm_substream *substream = pcm->streams[stream].substream; | 43 | struct snd_pcm_substream *substream = pcm->streams[stream].substream; |
96 | struct snd_dma_buffer *buf = &substream->dma_buffer; | 44 | struct snd_dma_buffer *buf = &substream->dma_buffer; |
97 | size_t size = atmel_pcm_hardware.buffer_bytes_max; | 45 | size_t size = ATMEL_SSC_DMABUF_SIZE; |
98 | 46 | ||
99 | buf->dev.type = SNDRV_DMA_TYPE_DEV; | 47 | buf->dev.type = SNDRV_DMA_TYPE_DEV; |
100 | buf->dev.dev = pcm->card->dev; | 48 | buf->dev.dev = pcm->card->dev; |
101 | buf->private_data = NULL; | 49 | buf->private_data = NULL; |
102 | buf->area = dma_alloc_coherent(pcm->card->dev, size, | 50 | buf->area = dma_alloc_coherent(pcm->card->dev, size, |
103 | &buf->addr, GFP_KERNEL); | 51 | &buf->addr, GFP_KERNEL); |
104 | pr_debug("atmel-pcm:" | 52 | pr_debug("atmel-pcm: alloc dma buffer: area=%p, addr=%p, size=%d\n", |
105 | "preallocate_dma_buffer: area=%p, addr=%p, size=%d\n", | 53 | (void *)buf->area, (void *)buf->addr, size); |
106 | (void *) buf->area, | ||
107 | (void *) buf->addr, | ||
108 | size); | ||
109 | 54 | ||
110 | if (!buf->area) | 55 | if (!buf->area) |
111 | return -ENOMEM; | 56 | return -ENOMEM; |
@@ -113,258 +58,19 @@ static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, | |||
113 | buf->bytes = size; | 58 | buf->bytes = size; |
114 | return 0; | 59 | return 0; |
115 | } | 60 | } |
116 | /*--------------------------------------------------------------------------*\ | ||
117 | * ISR | ||
118 | \*--------------------------------------------------------------------------*/ | ||
119 | static void atmel_pcm_dma_irq(u32 ssc_sr, | ||
120 | struct snd_pcm_substream *substream) | ||
121 | { | ||
122 | struct atmel_runtime_data *prtd = substream->runtime->private_data; | ||
123 | struct atmel_pcm_dma_params *params = prtd->params; | ||
124 | static int count; | ||
125 | |||
126 | count++; | ||
127 | |||
128 | if (ssc_sr & params->mask->ssc_endbuf) { | ||
129 | pr_warning("atmel-pcm: buffer %s on %s" | ||
130 | " (SSC_SR=%#x, count=%d)\n", | ||
131 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK | ||
132 | ? "underrun" : "overrun", | ||
133 | params->name, ssc_sr, count); | ||
134 | |||
135 | /* re-start the PDC */ | ||
136 | ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, | ||
137 | params->mask->pdc_disable); | ||
138 | prtd->period_ptr += prtd->period_size; | ||
139 | if (prtd->period_ptr >= prtd->dma_buffer_end) | ||
140 | prtd->period_ptr = prtd->dma_buffer; | ||
141 | |||
142 | ssc_writex(params->ssc->regs, params->pdc->xpr, | ||
143 | prtd->period_ptr); | ||
144 | ssc_writex(params->ssc->regs, params->pdc->xcr, | ||
145 | prtd->period_size / params->pdc_xfer_size); | ||
146 | ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, | ||
147 | params->mask->pdc_enable); | ||
148 | } | ||
149 | |||
150 | if (ssc_sr & params->mask->ssc_endx) { | ||
151 | /* Load the PDC next pointer and counter registers */ | ||
152 | prtd->period_ptr += prtd->period_size; | ||
153 | if (prtd->period_ptr >= prtd->dma_buffer_end) | ||
154 | prtd->period_ptr = prtd->dma_buffer; | ||
155 | |||
156 | ssc_writex(params->ssc->regs, params->pdc->xnpr, | ||
157 | prtd->period_ptr); | ||
158 | ssc_writex(params->ssc->regs, params->pdc->xncr, | ||
159 | prtd->period_size / params->pdc_xfer_size); | ||
160 | } | ||
161 | |||
162 | snd_pcm_period_elapsed(substream); | ||
163 | } | ||
164 | |||
165 | |||
166 | /*--------------------------------------------------------------------------*\ | ||
167 | * PCM operations | ||
168 | \*--------------------------------------------------------------------------*/ | ||
169 | static int atmel_pcm_hw_params(struct snd_pcm_substream *substream, | ||
170 | struct snd_pcm_hw_params *params) | ||
171 | { | ||
172 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
173 | struct atmel_runtime_data *prtd = runtime->private_data; | ||
174 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
175 | |||
176 | /* this may get called several times by oss emulation | ||
177 | * with different params */ | ||
178 | |||
179 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | ||
180 | runtime->dma_bytes = params_buffer_bytes(params); | ||
181 | |||
182 | prtd->params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | ||
183 | prtd->params->dma_intr_handler = atmel_pcm_dma_irq; | ||
184 | |||
185 | prtd->dma_buffer = runtime->dma_addr; | ||
186 | prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes; | ||
187 | prtd->period_size = params_period_bytes(params); | ||
188 | |||
189 | pr_debug("atmel-pcm: " | ||
190 | "hw_params: DMA for %s initialized " | ||
191 | "(dma_bytes=%u, period_size=%u)\n", | ||
192 | prtd->params->name, | ||
193 | runtime->dma_bytes, | ||
194 | prtd->period_size); | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static int atmel_pcm_hw_free(struct snd_pcm_substream *substream) | ||
199 | { | ||
200 | struct atmel_runtime_data *prtd = substream->runtime->private_data; | ||
201 | struct atmel_pcm_dma_params *params = prtd->params; | ||
202 | |||
203 | if (params != NULL) { | ||
204 | ssc_writex(params->ssc->regs, SSC_PDC_PTCR, | ||
205 | params->mask->pdc_disable); | ||
206 | prtd->params->dma_intr_handler = NULL; | ||
207 | } | ||
208 | |||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | static int atmel_pcm_prepare(struct snd_pcm_substream *substream) | ||
213 | { | ||
214 | struct atmel_runtime_data *prtd = substream->runtime->private_data; | ||
215 | struct atmel_pcm_dma_params *params = prtd->params; | ||
216 | |||
217 | ssc_writex(params->ssc->regs, SSC_IDR, | ||
218 | params->mask->ssc_endx | params->mask->ssc_endbuf); | ||
219 | ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, | ||
220 | params->mask->pdc_disable); | ||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | static int atmel_pcm_trigger(struct snd_pcm_substream *substream, | ||
225 | int cmd) | ||
226 | { | ||
227 | struct snd_pcm_runtime *rtd = substream->runtime; | ||
228 | struct atmel_runtime_data *prtd = rtd->private_data; | ||
229 | struct atmel_pcm_dma_params *params = prtd->params; | ||
230 | int ret = 0; | ||
231 | |||
232 | pr_debug("atmel-pcm:buffer_size = %ld," | ||
233 | "dma_area = %p, dma_bytes = %u\n", | ||
234 | rtd->buffer_size, rtd->dma_area, rtd->dma_bytes); | ||
235 | |||
236 | switch (cmd) { | ||
237 | case SNDRV_PCM_TRIGGER_START: | ||
238 | prtd->period_ptr = prtd->dma_buffer; | ||
239 | |||
240 | ssc_writex(params->ssc->regs, params->pdc->xpr, | ||
241 | prtd->period_ptr); | ||
242 | ssc_writex(params->ssc->regs, params->pdc->xcr, | ||
243 | prtd->period_size / params->pdc_xfer_size); | ||
244 | |||
245 | prtd->period_ptr += prtd->period_size; | ||
246 | ssc_writex(params->ssc->regs, params->pdc->xnpr, | ||
247 | prtd->period_ptr); | ||
248 | ssc_writex(params->ssc->regs, params->pdc->xncr, | ||
249 | prtd->period_size / params->pdc_xfer_size); | ||
250 | |||
251 | pr_debug("atmel-pcm: trigger: " | ||
252 | "period_ptr=%lx, xpr=%u, " | ||
253 | "xcr=%u, xnpr=%u, xncr=%u\n", | ||
254 | (unsigned long)prtd->period_ptr, | ||
255 | ssc_readx(params->ssc->regs, params->pdc->xpr), | ||
256 | ssc_readx(params->ssc->regs, params->pdc->xcr), | ||
257 | ssc_readx(params->ssc->regs, params->pdc->xnpr), | ||
258 | ssc_readx(params->ssc->regs, params->pdc->xncr)); | ||
259 | |||
260 | ssc_writex(params->ssc->regs, SSC_IER, | ||
261 | params->mask->ssc_endx | params->mask->ssc_endbuf); | ||
262 | ssc_writex(params->ssc->regs, SSC_PDC_PTCR, | ||
263 | params->mask->pdc_enable); | ||
264 | |||
265 | pr_debug("sr=%u imr=%u\n", | ||
266 | ssc_readx(params->ssc->regs, SSC_SR), | ||
267 | ssc_readx(params->ssc->regs, SSC_IER)); | ||
268 | break; /* SNDRV_PCM_TRIGGER_START */ | ||
269 | |||
270 | case SNDRV_PCM_TRIGGER_STOP: | ||
271 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
272 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
273 | ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, | ||
274 | params->mask->pdc_disable); | ||
275 | break; | ||
276 | |||
277 | case SNDRV_PCM_TRIGGER_RESUME: | ||
278 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
279 | ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, | ||
280 | params->mask->pdc_enable); | ||
281 | break; | ||
282 | |||
283 | default: | ||
284 | ret = -EINVAL; | ||
285 | } | ||
286 | 61 | ||
287 | return ret; | 62 | int atmel_pcm_mmap(struct snd_pcm_substream *substream, |
288 | } | ||
289 | |||
290 | static snd_pcm_uframes_t atmel_pcm_pointer( | ||
291 | struct snd_pcm_substream *substream) | ||
292 | { | ||
293 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
294 | struct atmel_runtime_data *prtd = runtime->private_data; | ||
295 | struct atmel_pcm_dma_params *params = prtd->params; | ||
296 | dma_addr_t ptr; | ||
297 | snd_pcm_uframes_t x; | ||
298 | |||
299 | ptr = (dma_addr_t) ssc_readx(params->ssc->regs, params->pdc->xpr); | ||
300 | x = bytes_to_frames(runtime, ptr - prtd->dma_buffer); | ||
301 | |||
302 | if (x == runtime->buffer_size) | ||
303 | x = 0; | ||
304 | |||
305 | return x; | ||
306 | } | ||
307 | |||
308 | static int atmel_pcm_open(struct snd_pcm_substream *substream) | ||
309 | { | ||
310 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
311 | struct atmel_runtime_data *prtd; | ||
312 | int ret = 0; | ||
313 | |||
314 | snd_soc_set_runtime_hwparams(substream, &atmel_pcm_hardware); | ||
315 | |||
316 | /* ensure that buffer size is a multiple of period size */ | ||
317 | ret = snd_pcm_hw_constraint_integer(runtime, | ||
318 | SNDRV_PCM_HW_PARAM_PERIODS); | ||
319 | if (ret < 0) | ||
320 | goto out; | ||
321 | |||
322 | prtd = kzalloc(sizeof(struct atmel_runtime_data), GFP_KERNEL); | ||
323 | if (prtd == NULL) { | ||
324 | ret = -ENOMEM; | ||
325 | goto out; | ||
326 | } | ||
327 | runtime->private_data = prtd; | ||
328 | |||
329 | out: | ||
330 | return ret; | ||
331 | } | ||
332 | |||
333 | static int atmel_pcm_close(struct snd_pcm_substream *substream) | ||
334 | { | ||
335 | struct atmel_runtime_data *prtd = substream->runtime->private_data; | ||
336 | |||
337 | kfree(prtd); | ||
338 | return 0; | ||
339 | } | ||
340 | |||
341 | static int atmel_pcm_mmap(struct snd_pcm_substream *substream, | ||
342 | struct vm_area_struct *vma) | 63 | struct vm_area_struct *vma) |
343 | { | 64 | { |
344 | return remap_pfn_range(vma, vma->vm_start, | 65 | return remap_pfn_range(vma, vma->vm_start, |
345 | substream->dma_buffer.addr >> PAGE_SHIFT, | 66 | substream->dma_buffer.addr >> PAGE_SHIFT, |
346 | vma->vm_end - vma->vm_start, vma->vm_page_prot); | 67 | vma->vm_end - vma->vm_start, vma->vm_page_prot); |
347 | } | 68 | } |
69 | EXPORT_SYMBOL_GPL(atmel_pcm_mmap); | ||
348 | 70 | ||
349 | static struct snd_pcm_ops atmel_pcm_ops = { | ||
350 | .open = atmel_pcm_open, | ||
351 | .close = atmel_pcm_close, | ||
352 | .ioctl = snd_pcm_lib_ioctl, | ||
353 | .hw_params = atmel_pcm_hw_params, | ||
354 | .hw_free = atmel_pcm_hw_free, | ||
355 | .prepare = atmel_pcm_prepare, | ||
356 | .trigger = atmel_pcm_trigger, | ||
357 | .pointer = atmel_pcm_pointer, | ||
358 | .mmap = atmel_pcm_mmap, | ||
359 | }; | ||
360 | |||
361 | |||
362 | /*--------------------------------------------------------------------------*\ | ||
363 | * ASoC platform driver | ||
364 | \*--------------------------------------------------------------------------*/ | ||
365 | static u64 atmel_pcm_dmamask = DMA_BIT_MASK(32); | 71 | static u64 atmel_pcm_dmamask = DMA_BIT_MASK(32); |
366 | 72 | ||
367 | static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd) | 73 | int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd) |
368 | { | 74 | { |
369 | struct snd_card *card = rtd->card->snd_card; | 75 | struct snd_card *card = rtd->card->snd_card; |
370 | struct snd_pcm *pcm = rtd->pcm; | 76 | struct snd_pcm *pcm = rtd->pcm; |
@@ -376,6 +82,7 @@ static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
376 | card->dev->coherent_dma_mask = DMA_BIT_MASK(32); | 82 | card->dev->coherent_dma_mask = DMA_BIT_MASK(32); |
377 | 83 | ||
378 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { | 84 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { |
85 | pr_debug("atmel-pcm: allocating PCM playback DMA buffer\n"); | ||
379 | ret = atmel_pcm_preallocate_dma_buffer(pcm, | 86 | ret = atmel_pcm_preallocate_dma_buffer(pcm, |
380 | SNDRV_PCM_STREAM_PLAYBACK); | 87 | SNDRV_PCM_STREAM_PLAYBACK); |
381 | if (ret) | 88 | if (ret) |
@@ -383,8 +90,7 @@ static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
383 | } | 90 | } |
384 | 91 | ||
385 | if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { | 92 | if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { |
386 | pr_debug("atmel-pcm:" | 93 | pr_debug("atmel-pcm: allocating PCM capture DMA buffer\n"); |
387 | "Allocating PCM capture DMA buffer\n"); | ||
388 | ret = atmel_pcm_preallocate_dma_buffer(pcm, | 94 | ret = atmel_pcm_preallocate_dma_buffer(pcm, |
389 | SNDRV_PCM_STREAM_CAPTURE); | 95 | SNDRV_PCM_STREAM_CAPTURE); |
390 | if (ret) | 96 | if (ret) |
@@ -393,8 +99,9 @@ static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
393 | out: | 99 | out: |
394 | return ret; | 100 | return ret; |
395 | } | 101 | } |
102 | EXPORT_SYMBOL_GPL(atmel_pcm_new); | ||
396 | 103 | ||
397 | static void atmel_pcm_free_dma_buffers(struct snd_pcm *pcm) | 104 | void atmel_pcm_free(struct snd_pcm *pcm) |
398 | { | 105 | { |
399 | struct snd_pcm_substream *substream; | 106 | struct snd_pcm_substream *substream; |
400 | struct snd_dma_buffer *buf; | 107 | struct snd_dma_buffer *buf; |
@@ -413,89 +120,5 @@ static void atmel_pcm_free_dma_buffers(struct snd_pcm *pcm) | |||
413 | buf->area = NULL; | 120 | buf->area = NULL; |
414 | } | 121 | } |
415 | } | 122 | } |
123 | EXPORT_SYMBOL_GPL(atmel_pcm_free); | ||
416 | 124 | ||
417 | #ifdef CONFIG_PM | ||
418 | static int atmel_pcm_suspend(struct snd_soc_dai *dai) | ||
419 | { | ||
420 | struct snd_pcm_runtime *runtime = dai->runtime; | ||
421 | struct atmel_runtime_data *prtd; | ||
422 | struct atmel_pcm_dma_params *params; | ||
423 | |||
424 | if (!runtime) | ||
425 | return 0; | ||
426 | |||
427 | prtd = runtime->private_data; | ||
428 | params = prtd->params; | ||
429 | |||
430 | /* disable the PDC and save the PDC registers */ | ||
431 | |||
432 | ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_disable); | ||
433 | |||
434 | prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr); | ||
435 | prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr); | ||
436 | prtd->pdc_xnpr_save = ssc_readx(params->ssc->regs, params->pdc->xnpr); | ||
437 | prtd->pdc_xncr_save = ssc_readx(params->ssc->regs, params->pdc->xncr); | ||
438 | |||
439 | return 0; | ||
440 | } | ||
441 | |||
442 | static int atmel_pcm_resume(struct snd_soc_dai *dai) | ||
443 | { | ||
444 | struct snd_pcm_runtime *runtime = dai->runtime; | ||
445 | struct atmel_runtime_data *prtd; | ||
446 | struct atmel_pcm_dma_params *params; | ||
447 | |||
448 | if (!runtime) | ||
449 | return 0; | ||
450 | |||
451 | prtd = runtime->private_data; | ||
452 | params = prtd->params; | ||
453 | |||
454 | /* restore the PDC registers and enable the PDC */ | ||
455 | ssc_writex(params->ssc->regs, params->pdc->xpr, prtd->pdc_xpr_save); | ||
456 | ssc_writex(params->ssc->regs, params->pdc->xcr, prtd->pdc_xcr_save); | ||
457 | ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save); | ||
458 | ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save); | ||
459 | |||
460 | ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_enable); | ||
461 | return 0; | ||
462 | } | ||
463 | #else | ||
464 | #define atmel_pcm_suspend NULL | ||
465 | #define atmel_pcm_resume NULL | ||
466 | #endif | ||
467 | |||
468 | static struct snd_soc_platform_driver atmel_soc_platform = { | ||
469 | .ops = &atmel_pcm_ops, | ||
470 | .pcm_new = atmel_pcm_new, | ||
471 | .pcm_free = atmel_pcm_free_dma_buffers, | ||
472 | .suspend = atmel_pcm_suspend, | ||
473 | .resume = atmel_pcm_resume, | ||
474 | }; | ||
475 | |||
476 | static int __devinit atmel_soc_platform_probe(struct platform_device *pdev) | ||
477 | { | ||
478 | return snd_soc_register_platform(&pdev->dev, &atmel_soc_platform); | ||
479 | } | ||
480 | |||
481 | static int __devexit atmel_soc_platform_remove(struct platform_device *pdev) | ||
482 | { | ||
483 | snd_soc_unregister_platform(&pdev->dev); | ||
484 | return 0; | ||
485 | } | ||
486 | |||
487 | static struct platform_driver atmel_pcm_driver = { | ||
488 | .driver = { | ||
489 | .name = "atmel-pcm-audio", | ||
490 | .owner = THIS_MODULE, | ||
491 | }, | ||
492 | |||
493 | .probe = atmel_soc_platform_probe, | ||
494 | .remove = __devexit_p(atmel_soc_platform_remove), | ||
495 | }; | ||
496 | |||
497 | module_platform_driver(atmel_pcm_driver); | ||
498 | |||
499 | MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>"); | ||
500 | MODULE_DESCRIPTION("Atmel PCM module"); | ||
501 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/atmel/atmel-pcm.h b/sound/soc/atmel/atmel-pcm.h index 5e0a95e64329..bb45d20e7250 100644 --- a/sound/soc/atmel/atmel-pcm.h +++ b/sound/soc/atmel/atmel-pcm.h | |||
@@ -36,6 +36,8 @@ | |||
36 | 36 | ||
37 | #include <linux/atmel-ssc.h> | 37 | #include <linux/atmel-ssc.h> |
38 | 38 | ||
39 | #define ATMEL_SSC_DMABUF_SIZE (64 * 1024) | ||
40 | |||
39 | /* | 41 | /* |
40 | * Registers and status bits that are required by the PCM driver. | 42 | * Registers and status bits that are required by the PCM driver. |
41 | */ | 43 | */ |
@@ -50,6 +52,7 @@ struct atmel_pdc_regs { | |||
50 | struct atmel_ssc_mask { | 52 | struct atmel_ssc_mask { |
51 | u32 ssc_enable; /* SSC recv/trans enable */ | 53 | u32 ssc_enable; /* SSC recv/trans enable */ |
52 | u32 ssc_disable; /* SSC recv/trans disable */ | 54 | u32 ssc_disable; /* SSC recv/trans disable */ |
55 | u32 ssc_error; /* SSC error conditions */ | ||
53 | u32 ssc_endx; /* SSC ENDTX or ENDRX */ | 56 | u32 ssc_endx; /* SSC ENDTX or ENDRX */ |
54 | u32 ssc_endbuf; /* SSC TXBUFE or RXBUFF */ | 57 | u32 ssc_endbuf; /* SSC TXBUFE or RXBUFF */ |
55 | u32 pdc_enable; /* PDC recv/trans enable */ | 58 | u32 pdc_enable; /* PDC recv/trans enable */ |
@@ -80,4 +83,35 @@ struct atmel_pcm_dma_params { | |||
80 | #define ssc_readx(base, reg) (__raw_readl((base) + (reg))) | 83 | #define ssc_readx(base, reg) (__raw_readl((base) + (reg))) |
81 | #define ssc_writex(base, reg, value) __raw_writel((value), (base) + (reg)) | 84 | #define ssc_writex(base, reg, value) __raw_writel((value), (base) + (reg)) |
82 | 85 | ||
86 | int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd); | ||
87 | void atmel_pcm_free(struct snd_pcm *pcm); | ||
88 | int atmel_pcm_mmap(struct snd_pcm_substream *substream, | ||
89 | struct vm_area_struct *vma); | ||
90 | |||
91 | #ifdef CONFIG_SND_ATMEL_SOC_PDC | ||
92 | int atmel_pcm_pdc_platform_register(struct device *dev); | ||
93 | void atmel_pcm_pdc_platform_unregister(struct device *dev); | ||
94 | #else | ||
95 | static inline int atmel_pcm_pdc_platform_register(struct device *dev) | ||
96 | { | ||
97 | return 0; | ||
98 | } | ||
99 | static inline void atmel_pcm_pdc_platform_unregister(struct device *dev) | ||
100 | { | ||
101 | } | ||
102 | #endif | ||
103 | |||
104 | #ifdef CONFIG_SND_ATMEL_SOC_DMA | ||
105 | int atmel_pcm_dma_platform_register(struct device *dev); | ||
106 | void atmel_pcm_dma_platform_unregister(struct device *dev); | ||
107 | #else | ||
108 | static inline int atmel_pcm_dma_platform_register(struct device *dev) | ||
109 | { | ||
110 | return 0; | ||
111 | } | ||
112 | static inline void atmel_pcm_dma_platform_unregister(struct device *dev) | ||
113 | { | ||
114 | } | ||
115 | #endif | ||
116 | |||
83 | #endif /* _ATMEL_PCM_H */ | 117 | #endif /* _ATMEL_PCM_H */ |
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c index 354341ec0f42..1c7663422054 100644 --- a/sound/soc/atmel/atmel_ssc_dai.c +++ b/sound/soc/atmel/atmel_ssc_dai.c | |||
@@ -48,11 +48,7 @@ | |||
48 | #include "atmel_ssc_dai.h" | 48 | #include "atmel_ssc_dai.h" |
49 | 49 | ||
50 | 50 | ||
51 | #if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20) | ||
52 | #define NUM_SSC_DEVICES 1 | ||
53 | #else | ||
54 | #define NUM_SSC_DEVICES 3 | 51 | #define NUM_SSC_DEVICES 3 |
55 | #endif | ||
56 | 52 | ||
57 | /* | 53 | /* |
58 | * SSC PDC registers required by the PCM DMA engine. | 54 | * SSC PDC registers required by the PCM DMA engine. |
@@ -107,7 +103,6 @@ static struct atmel_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = { | |||
107 | .pdc = &pdc_rx_reg, | 103 | .pdc = &pdc_rx_reg, |
108 | .mask = &ssc_rx_mask, | 104 | .mask = &ssc_rx_mask, |
109 | } }, | 105 | } }, |
110 | #if NUM_SSC_DEVICES == 3 | ||
111 | {{ | 106 | {{ |
112 | .name = "SSC1 PCM out", | 107 | .name = "SSC1 PCM out", |
113 | .pdc = &pdc_tx_reg, | 108 | .pdc = &pdc_tx_reg, |
@@ -128,7 +123,6 @@ static struct atmel_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = { | |||
128 | .pdc = &pdc_rx_reg, | 123 | .pdc = &pdc_rx_reg, |
129 | .mask = &ssc_rx_mask, | 124 | .mask = &ssc_rx_mask, |
130 | } }, | 125 | } }, |
131 | #endif | ||
132 | }; | 126 | }; |
133 | 127 | ||
134 | 128 | ||
@@ -139,7 +133,6 @@ static struct atmel_ssc_info ssc_info[NUM_SSC_DEVICES] = { | |||
139 | .dir_mask = SSC_DIR_MASK_UNUSED, | 133 | .dir_mask = SSC_DIR_MASK_UNUSED, |
140 | .initialized = 0, | 134 | .initialized = 0, |
141 | }, | 135 | }, |
142 | #if NUM_SSC_DEVICES == 3 | ||
143 | { | 136 | { |
144 | .name = "ssc1", | 137 | .name = "ssc1", |
145 | .lock = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock), | 138 | .lock = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock), |
@@ -152,7 +145,6 @@ static struct atmel_ssc_info ssc_info[NUM_SSC_DEVICES] = { | |||
152 | .dir_mask = SSC_DIR_MASK_UNUSED, | 145 | .dir_mask = SSC_DIR_MASK_UNUSED, |
153 | .initialized = 0, | 146 | .initialized = 0, |
154 | }, | 147 | }, |
155 | #endif | ||
156 | }; | 148 | }; |
157 | 149 | ||
158 | 150 | ||
@@ -690,27 +682,9 @@ static int atmel_ssc_resume(struct snd_soc_dai *cpu_dai) | |||
690 | static int atmel_ssc_probe(struct snd_soc_dai *dai) | 682 | static int atmel_ssc_probe(struct snd_soc_dai *dai) |
691 | { | 683 | { |
692 | struct atmel_ssc_info *ssc_p = &ssc_info[dai->id]; | 684 | struct atmel_ssc_info *ssc_p = &ssc_info[dai->id]; |
693 | int ret = 0; | ||
694 | 685 | ||
695 | snd_soc_dai_set_drvdata(dai, ssc_p); | 686 | snd_soc_dai_set_drvdata(dai, ssc_p); |
696 | 687 | ||
697 | /* | ||
698 | * Request SSC device | ||
699 | */ | ||
700 | ssc_p->ssc = ssc_request(dai->id); | ||
701 | if (IS_ERR(ssc_p->ssc)) { | ||
702 | printk(KERN_ERR "ASoC: Failed to request SSC %d\n", dai->id); | ||
703 | ret = PTR_ERR(ssc_p->ssc); | ||
704 | } | ||
705 | |||
706 | return ret; | ||
707 | } | ||
708 | |||
709 | static int atmel_ssc_remove(struct snd_soc_dai *dai) | ||
710 | { | ||
711 | struct atmel_ssc_info *ssc_p = snd_soc_dai_get_drvdata(dai); | ||
712 | |||
713 | ssc_free(ssc_p->ssc); | ||
714 | return 0; | 688 | return 0; |
715 | } | 689 | } |
716 | 690 | ||
@@ -728,30 +702,8 @@ static const struct snd_soc_dai_ops atmel_ssc_dai_ops = { | |||
728 | .set_clkdiv = atmel_ssc_set_dai_clkdiv, | 702 | .set_clkdiv = atmel_ssc_set_dai_clkdiv, |
729 | }; | 703 | }; |
730 | 704 | ||
731 | static struct snd_soc_dai_driver atmel_ssc_dai[NUM_SSC_DEVICES] = { | 705 | static struct snd_soc_dai_driver atmel_ssc_dai = { |
732 | { | ||
733 | .name = "atmel-ssc-dai.0", | ||
734 | .probe = atmel_ssc_probe, | ||
735 | .remove = atmel_ssc_remove, | ||
736 | .suspend = atmel_ssc_suspend, | ||
737 | .resume = atmel_ssc_resume, | ||
738 | .playback = { | ||
739 | .channels_min = 1, | ||
740 | .channels_max = 2, | ||
741 | .rates = ATMEL_SSC_RATES, | ||
742 | .formats = ATMEL_SSC_FORMATS,}, | ||
743 | .capture = { | ||
744 | .channels_min = 1, | ||
745 | .channels_max = 2, | ||
746 | .rates = ATMEL_SSC_RATES, | ||
747 | .formats = ATMEL_SSC_FORMATS,}, | ||
748 | .ops = &atmel_ssc_dai_ops, | ||
749 | }, | ||
750 | #if NUM_SSC_DEVICES == 3 | ||
751 | { | ||
752 | .name = "atmel-ssc-dai.1", | ||
753 | .probe = atmel_ssc_probe, | 706 | .probe = atmel_ssc_probe, |
754 | .remove = atmel_ssc_remove, | ||
755 | .suspend = atmel_ssc_suspend, | 707 | .suspend = atmel_ssc_suspend, |
756 | .resume = atmel_ssc_resume, | 708 | .resume = atmel_ssc_resume, |
757 | .playback = { | 709 | .playback = { |
@@ -765,50 +717,50 @@ static struct snd_soc_dai_driver atmel_ssc_dai[NUM_SSC_DEVICES] = { | |||
765 | .rates = ATMEL_SSC_RATES, | 717 | .rates = ATMEL_SSC_RATES, |
766 | .formats = ATMEL_SSC_FORMATS,}, | 718 | .formats = ATMEL_SSC_FORMATS,}, |
767 | .ops = &atmel_ssc_dai_ops, | 719 | .ops = &atmel_ssc_dai_ops, |
768 | }, | ||
769 | { | ||
770 | .name = "atmel-ssc-dai.2", | ||
771 | .probe = atmel_ssc_probe, | ||
772 | .remove = atmel_ssc_remove, | ||
773 | .suspend = atmel_ssc_suspend, | ||
774 | .resume = atmel_ssc_resume, | ||
775 | .playback = { | ||
776 | .channels_min = 1, | ||
777 | .channels_max = 2, | ||
778 | .rates = ATMEL_SSC_RATES, | ||
779 | .formats = ATMEL_SSC_FORMATS,}, | ||
780 | .capture = { | ||
781 | .channels_min = 1, | ||
782 | .channels_max = 2, | ||
783 | .rates = ATMEL_SSC_RATES, | ||
784 | .formats = ATMEL_SSC_FORMATS,}, | ||
785 | .ops = &atmel_ssc_dai_ops, | ||
786 | }, | ||
787 | #endif | ||
788 | }; | 720 | }; |
789 | 721 | ||
790 | static __devinit int asoc_ssc_probe(struct platform_device *pdev) | 722 | static int asoc_ssc_init(struct device *dev) |
791 | { | 723 | { |
792 | BUG_ON(pdev->id < 0); | 724 | struct platform_device *pdev = to_platform_device(dev); |
793 | BUG_ON(pdev->id >= ARRAY_SIZE(atmel_ssc_dai)); | 725 | struct ssc_device *ssc = platform_get_drvdata(pdev); |
794 | return snd_soc_register_dai(&pdev->dev, &atmel_ssc_dai[pdev->id]); | 726 | int ret; |
795 | } | 727 | |
728 | ret = snd_soc_register_dai(dev, &atmel_ssc_dai); | ||
729 | if (ret) { | ||
730 | dev_err(dev, "Could not register DAI: %d\n", ret); | ||
731 | goto err; | ||
732 | } | ||
733 | |||
734 | if (ssc->pdata->use_dma) | ||
735 | ret = atmel_pcm_dma_platform_register(dev); | ||
736 | else | ||
737 | ret = atmel_pcm_pdc_platform_register(dev); | ||
738 | |||
739 | if (ret) { | ||
740 | dev_err(dev, "Could not register PCM: %d\n", ret); | ||
741 | goto err_unregister_dai; | ||
742 | }; | ||
796 | 743 | ||
797 | static int __devexit asoc_ssc_remove(struct platform_device *pdev) | ||
798 | { | ||
799 | snd_soc_unregister_dai(&pdev->dev); | ||
800 | return 0; | 744 | return 0; |
745 | |||
746 | err_unregister_dai: | ||
747 | snd_soc_unregister_dai(dev); | ||
748 | err: | ||
749 | return ret; | ||
801 | } | 750 | } |
802 | 751 | ||
803 | static struct platform_driver asoc_ssc_driver = { | 752 | static void asoc_ssc_exit(struct device *dev) |
804 | .driver = { | 753 | { |
805 | .name = "atmel-ssc-dai", | 754 | struct platform_device *pdev = to_platform_device(dev); |
806 | .owner = THIS_MODULE, | 755 | struct ssc_device *ssc = platform_get_drvdata(pdev); |
807 | }, | ||
808 | 756 | ||
809 | .probe = asoc_ssc_probe, | 757 | if (ssc->pdata->use_dma) |
810 | .remove = __devexit_p(asoc_ssc_remove), | 758 | atmel_pcm_dma_platform_unregister(dev); |
811 | }; | 759 | else |
760 | atmel_pcm_pdc_platform_unregister(dev); | ||
761 | |||
762 | snd_soc_unregister_dai(dev); | ||
763 | } | ||
812 | 764 | ||
813 | /** | 765 | /** |
814 | * atmel_ssc_set_audio - Allocate the specified SSC for audio use. | 766 | * atmel_ssc_set_audio - Allocate the specified SSC for audio use. |
@@ -816,50 +768,32 @@ static struct platform_driver asoc_ssc_driver = { | |||
816 | int atmel_ssc_set_audio(int ssc_id) | 768 | int atmel_ssc_set_audio(int ssc_id) |
817 | { | 769 | { |
818 | struct ssc_device *ssc; | 770 | struct ssc_device *ssc; |
819 | static struct platform_device *dma_pdev; | ||
820 | struct platform_device *ssc_pdev; | ||
821 | int ret; | 771 | int ret; |
822 | 772 | ||
823 | if (ssc_id < 0 || ssc_id >= ARRAY_SIZE(atmel_ssc_dai)) | ||
824 | return -EINVAL; | ||
825 | |||
826 | /* Allocate a dummy device for DMA if we don't have one already */ | ||
827 | if (!dma_pdev) { | ||
828 | dma_pdev = platform_device_alloc("atmel-pcm-audio", -1); | ||
829 | if (!dma_pdev) | ||
830 | return -ENOMEM; | ||
831 | |||
832 | ret = platform_device_add(dma_pdev); | ||
833 | if (ret < 0) { | ||
834 | platform_device_put(dma_pdev); | ||
835 | dma_pdev = NULL; | ||
836 | return ret; | ||
837 | } | ||
838 | } | ||
839 | |||
840 | ssc_pdev = platform_device_alloc("atmel-ssc-dai", ssc_id); | ||
841 | if (!ssc_pdev) | ||
842 | return -ENOMEM; | ||
843 | |||
844 | /* If we can grab the SSC briefly to parent the DAI device off it */ | 773 | /* If we can grab the SSC briefly to parent the DAI device off it */ |
845 | ssc = ssc_request(ssc_id); | 774 | ssc = ssc_request(ssc_id); |
846 | if (IS_ERR(ssc)) | 775 | if (IS_ERR(ssc)) { |
847 | pr_warn("Unable to parent ASoC SSC DAI on SSC: %ld\n", | 776 | pr_err("Unable to parent ASoC SSC DAI on SSC: %ld\n", |
848 | PTR_ERR(ssc)); | 777 | PTR_ERR(ssc)); |
849 | else { | 778 | return PTR_ERR(ssc); |
850 | ssc_pdev->dev.parent = &(ssc->pdev->dev); | 779 | } else { |
851 | ssc_free(ssc); | 780 | ssc_info[ssc_id].ssc = ssc; |
852 | } | 781 | } |
853 | 782 | ||
854 | ret = platform_device_add(ssc_pdev); | 783 | ret = asoc_ssc_init(&ssc->pdev->dev); |
855 | if (ret < 0) | ||
856 | platform_device_put(ssc_pdev); | ||
857 | 784 | ||
858 | return ret; | 785 | return ret; |
859 | } | 786 | } |
860 | EXPORT_SYMBOL_GPL(atmel_ssc_set_audio); | 787 | EXPORT_SYMBOL_GPL(atmel_ssc_set_audio); |
861 | 788 | ||
862 | module_platform_driver(asoc_ssc_driver); | 789 | void atmel_ssc_put_audio(int ssc_id) |
790 | { | ||
791 | struct ssc_device *ssc = ssc_info[ssc_id].ssc; | ||
792 | |||
793 | ssc_free(ssc); | ||
794 | asoc_ssc_exit(&ssc->pdev->dev); | ||
795 | } | ||
796 | EXPORT_SYMBOL_GPL(atmel_ssc_put_audio); | ||
863 | 797 | ||
864 | /* Module information */ | 798 | /* Module information */ |
865 | MODULE_AUTHOR("Sedji Gaouaou, sedji.gaouaou@atmel.com, www.atmel.com"); | 799 | MODULE_AUTHOR("Sedji Gaouaou, sedji.gaouaou@atmel.com, www.atmel.com"); |
diff --git a/sound/soc/atmel/atmel_ssc_dai.h b/sound/soc/atmel/atmel_ssc_dai.h index 5d4f0f9b4d9a..b1f08d511495 100644 --- a/sound/soc/atmel/atmel_ssc_dai.h +++ b/sound/soc/atmel/atmel_ssc_dai.h | |||
@@ -117,6 +117,7 @@ struct atmel_ssc_info { | |||
117 | struct atmel_ssc_state ssc_state; | 117 | struct atmel_ssc_state ssc_state; |
118 | }; | 118 | }; |
119 | 119 | ||
120 | int atmel_ssc_set_audio(int ssc); | 120 | int atmel_ssc_set_audio(int ssc_id); |
121 | void atmel_ssc_put_audio(int ssc_id); | ||
121 | 122 | ||
122 | #endif /* _AT91_SSC_DAI_H */ | 123 | #endif /* _AT91_SSC_DAI_H */ |
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c index c88351488f45..0744610e53dd 100644 --- a/sound/soc/atmel/sam9g20_wm8731.c +++ b/sound/soc/atmel/sam9g20_wm8731.c | |||
@@ -38,6 +38,8 @@ | |||
38 | #include <linux/platform_device.h> | 38 | #include <linux/platform_device.h> |
39 | #include <linux/i2c.h> | 39 | #include <linux/i2c.h> |
40 | 40 | ||
41 | #include <linux/pinctrl/consumer.h> | ||
42 | |||
41 | #include <linux/atmel-ssc.h> | 43 | #include <linux/atmel-ssc.h> |
42 | 44 | ||
43 | #include <sound/core.h> | 45 | #include <sound/core.h> |
@@ -179,10 +181,10 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd) | |||
179 | static struct snd_soc_dai_link at91sam9g20ek_dai = { | 181 | static struct snd_soc_dai_link at91sam9g20ek_dai = { |
180 | .name = "WM8731", | 182 | .name = "WM8731", |
181 | .stream_name = "WM8731 PCM", | 183 | .stream_name = "WM8731 PCM", |
182 | .cpu_dai_name = "atmel-ssc-dai.0", | 184 | .cpu_dai_name = "at91rm9200_ssc.0", |
183 | .codec_dai_name = "wm8731-hifi", | 185 | .codec_dai_name = "wm8731-hifi", |
184 | .init = at91sam9g20ek_wm8731_init, | 186 | .init = at91sam9g20ek_wm8731_init, |
185 | .platform_name = "atmel-pcm-audio", | 187 | .platform_name = "at91rm9200_ssc.0", |
186 | .codec_name = "wm8731.0-001b", | 188 | .codec_name = "wm8731.0-001b", |
187 | .ops = &at91sam9g20ek_ops, | 189 | .ops = &at91sam9g20ek_ops, |
188 | }; | 190 | }; |
@@ -195,20 +197,31 @@ static struct snd_soc_card snd_soc_at91sam9g20ek = { | |||
195 | .set_bias_level = at91sam9g20ek_set_bias_level, | 197 | .set_bias_level = at91sam9g20ek_set_bias_level, |
196 | }; | 198 | }; |
197 | 199 | ||
198 | static struct platform_device *at91sam9g20ek_snd_device; | 200 | static int __devinit at91sam9g20ek_audio_probe(struct platform_device *pdev) |
199 | |||
200 | static int __init at91sam9g20ek_init(void) | ||
201 | { | 201 | { |
202 | struct device_node *np = pdev->dev.of_node; | ||
203 | struct device_node *codec_np, *cpu_np; | ||
202 | struct clk *pllb; | 204 | struct clk *pllb; |
205 | struct snd_soc_card *card = &snd_soc_at91sam9g20ek; | ||
206 | struct pinctrl *pinctrl; | ||
203 | int ret; | 207 | int ret; |
204 | 208 | ||
205 | if (!(machine_is_at91sam9g20ek() || machine_is_at91sam9g20ek_2mmc())) | 209 | pinctrl = devm_pinctrl_get_select_default(&pdev->dev); |
206 | return -ENODEV; | 210 | if (IS_ERR(pinctrl)) { |
211 | dev_err(&pdev->dev, "Failed to request pinctrl for mck\n"); | ||
212 | return PTR_ERR(pinctrl); | ||
213 | } | ||
214 | |||
215 | if (!np) { | ||
216 | if (!(machine_is_at91sam9g20ek() || | ||
217 | machine_is_at91sam9g20ek_2mmc())) | ||
218 | return -ENODEV; | ||
219 | } | ||
207 | 220 | ||
208 | ret = atmel_ssc_set_audio(0); | 221 | ret = atmel_ssc_set_audio(0); |
209 | if (ret != 0) { | 222 | if (ret) { |
210 | pr_err("Failed to set SSC 0 for audio: %d\n", ret); | 223 | dev_err(&pdev->dev, "ssc channel is not valid\n"); |
211 | return ret; | 224 | return -EINVAL; |
212 | } | 225 | } |
213 | 226 | ||
214 | /* | 227 | /* |
@@ -236,45 +249,92 @@ static int __init at91sam9g20ek_init(void) | |||
236 | 249 | ||
237 | clk_set_rate(mclk, MCLK_RATE); | 250 | clk_set_rate(mclk, MCLK_RATE); |
238 | 251 | ||
239 | at91sam9g20ek_snd_device = platform_device_alloc("soc-audio", -1); | 252 | card->dev = &pdev->dev; |
240 | if (!at91sam9g20ek_snd_device) { | 253 | |
241 | printk(KERN_ERR "ASoC: Platform device allocation failed\n"); | 254 | /* Parse device node info */ |
242 | ret = -ENOMEM; | 255 | if (np) { |
243 | goto err_mclk; | 256 | ret = snd_soc_of_parse_card_name(card, "atmel,model"); |
257 | if (ret) | ||
258 | goto err; | ||
259 | |||
260 | ret = snd_soc_of_parse_audio_routing(card, | ||
261 | "atmel,audio-routing"); | ||
262 | if (ret) | ||
263 | goto err; | ||
264 | |||
265 | /* Parse codec info */ | ||
266 | at91sam9g20ek_dai.codec_name = NULL; | ||
267 | codec_np = of_parse_phandle(np, "atmel,audio-codec", 0); | ||
268 | if (!codec_np) { | ||
269 | dev_err(&pdev->dev, "codec info missing\n"); | ||
270 | return -EINVAL; | ||
271 | } | ||
272 | at91sam9g20ek_dai.codec_of_node = codec_np; | ||
273 | |||
274 | /* Parse dai and platform info */ | ||
275 | at91sam9g20ek_dai.cpu_dai_name = NULL; | ||
276 | at91sam9g20ek_dai.platform_name = NULL; | ||
277 | cpu_np = of_parse_phandle(np, "atmel,ssc-controller", 0); | ||
278 | if (!cpu_np) { | ||
279 | dev_err(&pdev->dev, "dai and pcm info missing\n"); | ||
280 | return -EINVAL; | ||
281 | } | ||
282 | at91sam9g20ek_dai.cpu_of_node = cpu_np; | ||
283 | at91sam9g20ek_dai.platform_of_node = cpu_np; | ||
284 | |||
285 | of_node_put(codec_np); | ||
286 | of_node_put(cpu_np); | ||
244 | } | 287 | } |
245 | 288 | ||
246 | platform_set_drvdata(at91sam9g20ek_snd_device, | 289 | ret = snd_soc_register_card(card); |
247 | &snd_soc_at91sam9g20ek); | ||
248 | |||
249 | ret = platform_device_add(at91sam9g20ek_snd_device); | ||
250 | if (ret) { | 290 | if (ret) { |
251 | printk(KERN_ERR "ASoC: Platform device allocation failed\n"); | 291 | printk(KERN_ERR "ASoC: snd_soc_register_card() failed\n"); |
252 | goto err_device_add; | ||
253 | } | 292 | } |
254 | 293 | ||
255 | return ret; | 294 | return ret; |
256 | 295 | ||
257 | err_device_add: | ||
258 | platform_device_put(at91sam9g20ek_snd_device); | ||
259 | err_mclk: | 296 | err_mclk: |
260 | clk_put(mclk); | 297 | clk_put(mclk); |
261 | mclk = NULL; | 298 | mclk = NULL; |
262 | err: | 299 | err: |
300 | atmel_ssc_put_audio(0); | ||
263 | return ret; | 301 | return ret; |
264 | } | 302 | } |
265 | 303 | ||
266 | static void __exit at91sam9g20ek_exit(void) | 304 | static int __devexit at91sam9g20ek_audio_remove(struct platform_device *pdev) |
267 | { | 305 | { |
268 | platform_device_unregister(at91sam9g20ek_snd_device); | 306 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
269 | at91sam9g20ek_snd_device = NULL; | 307 | |
308 | atmel_ssc_put_audio(0); | ||
309 | snd_soc_unregister_card(card); | ||
270 | clk_put(mclk); | 310 | clk_put(mclk); |
271 | mclk = NULL; | 311 | mclk = NULL; |
312 | |||
313 | return 0; | ||
272 | } | 314 | } |
273 | 315 | ||
274 | module_init(at91sam9g20ek_init); | 316 | #ifdef CONFIG_OF |
275 | module_exit(at91sam9g20ek_exit); | 317 | static const struct of_device_id at91sam9g20ek_wm8731_dt_ids[] = { |
318 | { .compatible = "atmel,at91sam9g20ek-wm8731-audio", }, | ||
319 | { } | ||
320 | }; | ||
321 | MODULE_DEVICE_TABLE(of, at91sam9g20ek_wm8731_dt_ids); | ||
322 | #endif | ||
323 | |||
324 | static struct platform_driver at91sam9g20ek_audio_driver = { | ||
325 | .driver = { | ||
326 | .name = "at91sam9g20ek-audio", | ||
327 | .owner = THIS_MODULE, | ||
328 | .of_match_table = of_match_ptr(at91sam9g20ek_wm8731_dt_ids), | ||
329 | }, | ||
330 | .probe = at91sam9g20ek_audio_probe, | ||
331 | .remove = __devexit_p(at91sam9g20ek_audio_remove), | ||
332 | }; | ||
333 | |||
334 | module_platform_driver(at91sam9g20ek_audio_driver); | ||
276 | 335 | ||
277 | /* Module information */ | 336 | /* Module information */ |
278 | MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>"); | 337 | MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>"); |
279 | MODULE_DESCRIPTION("ALSA SoC AT91SAM9G20EK_WM8731"); | 338 | MODULE_DESCRIPTION("ALSA SoC AT91SAM9G20EK_WM8731"); |
339 | MODULE_ALIAS("platform:at91sam9g20ek-audio"); | ||
280 | MODULE_LICENSE("GPL"); | 340 | MODULE_LICENSE("GPL"); |
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index b92759a39361..3a847828932a 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -44,6 +44,7 @@ config SND_SOC_ALL_CODECS | |||
44 | select SND_SOC_LM4857 if I2C | 44 | select SND_SOC_LM4857 if I2C |
45 | select SND_SOC_LM49453 if I2C | 45 | select SND_SOC_LM49453 if I2C |
46 | select SND_SOC_MAX98088 if I2C | 46 | select SND_SOC_MAX98088 if I2C |
47 | select SND_SOC_MAX98090 if I2C | ||
47 | select SND_SOC_MAX98095 if I2C | 48 | select SND_SOC_MAX98095 if I2C |
48 | select SND_SOC_MAX9850 if I2C | 49 | select SND_SOC_MAX9850 if I2C |
49 | select SND_SOC_MAX9768 if I2C | 50 | select SND_SOC_MAX9768 if I2C |
@@ -54,6 +55,7 @@ config SND_SOC_ALL_CODECS | |||
54 | select SND_SOC_PCM3008 | 55 | select SND_SOC_PCM3008 |
55 | select SND_SOC_RT5631 if I2C | 56 | select SND_SOC_RT5631 if I2C |
56 | select SND_SOC_SGTL5000 if I2C | 57 | select SND_SOC_SGTL5000 if I2C |
58 | select SND_SOC_SI476X if MFD_SI476X_CORE | ||
57 | select SND_SOC_SN95031 if INTEL_SCU_IPC | 59 | select SND_SOC_SN95031 if INTEL_SCU_IPC |
58 | select SND_SOC_SPDIF | 60 | select SND_SOC_SPDIF |
59 | select SND_SOC_SSM2602 if SND_SOC_I2C_AND_SPI | 61 | select SND_SOC_SSM2602 if SND_SOC_I2C_AND_SPI |
@@ -146,6 +148,13 @@ config SND_SOC_WM_HUBS | |||
146 | default y if SND_SOC_WM8993=y || SND_SOC_WM8994=y | 148 | default y if SND_SOC_WM8993=y || SND_SOC_WM8994=y |
147 | default m if SND_SOC_WM8993=m || SND_SOC_WM8994=m | 149 | default m if SND_SOC_WM8993=m || SND_SOC_WM8994=m |
148 | 150 | ||
151 | config SND_SOC_WM_ADSP | ||
152 | tristate | ||
153 | default y if SND_SOC_WM5102=y | ||
154 | default y if SND_SOC_WM2200=y | ||
155 | default m if SND_SOC_WM5102=m | ||
156 | default m if SND_SOC_WM2200=m | ||
157 | |||
149 | config SND_SOC_AB8500_CODEC | 158 | config SND_SOC_AB8500_CODEC |
150 | tristate | 159 | tristate |
151 | 160 | ||
@@ -229,6 +238,7 @@ config SND_SOC_CX20442 | |||
229 | tristate | 238 | tristate |
230 | 239 | ||
231 | config SND_SOC_JZ4740_CODEC | 240 | config SND_SOC_JZ4740_CODEC |
241 | select REGMAP_MMIO | ||
232 | tristate | 242 | tristate |
233 | 243 | ||
234 | config SND_SOC_L3 | 244 | config SND_SOC_L3 |
@@ -258,6 +268,9 @@ config SND_SOC_LM49453 | |||
258 | config SND_SOC_MAX98088 | 268 | config SND_SOC_MAX98088 |
259 | tristate | 269 | tristate |
260 | 270 | ||
271 | config SND_SOC_MAX98090 | ||
272 | tristate | ||
273 | |||
261 | config SND_SOC_MAX98095 | 274 | config SND_SOC_MAX98095 |
262 | tristate | 275 | tristate |
263 | 276 | ||
@@ -277,6 +290,9 @@ config SND_SOC_RT5631 | |||
277 | config SND_SOC_SGTL5000 | 290 | config SND_SOC_SGTL5000 |
278 | tristate | 291 | tristate |
279 | 292 | ||
293 | config SND_SOC_SI476X | ||
294 | tristate | ||
295 | |||
280 | config SND_SOC_SIGMADSP | 296 | config SND_SOC_SIGMADSP |
281 | tristate | 297 | tristate |
282 | select CRC32 | 298 | select CRC32 |
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 9bd4d95aab4f..f6e8e36cceb7 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile | |||
@@ -34,6 +34,7 @@ snd-soc-lm4857-objs := lm4857.o | |||
34 | snd-soc-lm49453-objs := lm49453.o | 34 | snd-soc-lm49453-objs := lm49453.o |
35 | snd-soc-max9768-objs := max9768.o | 35 | snd-soc-max9768-objs := max9768.o |
36 | snd-soc-max98088-objs := max98088.o | 36 | snd-soc-max98088-objs := max98088.o |
37 | snd-soc-max98090-objs := max98090.o | ||
37 | snd-soc-max98095-objs := max98095.o | 38 | snd-soc-max98095-objs := max98095.o |
38 | snd-soc-max9850-objs := max9850.o | 39 | snd-soc-max9850-objs := max9850.o |
39 | snd-soc-mc13783-objs := mc13783.o | 40 | snd-soc-mc13783-objs := mc13783.o |
@@ -45,6 +46,7 @@ snd-soc-sgtl5000-objs := sgtl5000.o | |||
45 | snd-soc-alc5623-objs := alc5623.o | 46 | snd-soc-alc5623-objs := alc5623.o |
46 | snd-soc-alc5632-objs := alc5632.o | 47 | snd-soc-alc5632-objs := alc5632.o |
47 | snd-soc-sigmadsp-objs := sigmadsp.o | 48 | snd-soc-sigmadsp-objs := sigmadsp.o |
49 | snd-soc-si476x-objs := si476x.o | ||
48 | snd-soc-sn95031-objs := sn95031.o | 50 | snd-soc-sn95031-objs := sn95031.o |
49 | snd-soc-spdif-tx-objs := spdif_transciever.o | 51 | snd-soc-spdif-tx-objs := spdif_transciever.o |
50 | snd-soc-spdif-rx-objs := spdif_receiver.o | 52 | snd-soc-spdif-rx-objs := spdif_receiver.o |
@@ -62,6 +64,7 @@ snd-soc-twl6040-objs := twl6040.o | |||
62 | snd-soc-uda134x-objs := uda134x.o | 64 | snd-soc-uda134x-objs := uda134x.o |
63 | snd-soc-uda1380-objs := uda1380.o | 65 | snd-soc-uda1380-objs := uda1380.o |
64 | snd-soc-wl1273-objs := wl1273.o | 66 | snd-soc-wl1273-objs := wl1273.o |
67 | snd-soc-wm-adsp-objs := wm_adsp.o | ||
65 | snd-soc-wm0010-objs := wm0010.o | 68 | snd-soc-wm0010-objs := wm0010.o |
66 | snd-soc-wm1250-ev1-objs := wm1250-ev1.o | 69 | snd-soc-wm1250-ev1-objs := wm1250-ev1.o |
67 | snd-soc-wm2000-objs := wm2000.o | 70 | snd-soc-wm2000-objs := wm2000.o |
@@ -155,6 +158,7 @@ obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o | |||
155 | obj-$(CONFIG_SND_SOC_LM49453) += snd-soc-lm49453.o | 158 | obj-$(CONFIG_SND_SOC_LM49453) += snd-soc-lm49453.o |
156 | obj-$(CONFIG_SND_SOC_MAX9768) += snd-soc-max9768.o | 159 | obj-$(CONFIG_SND_SOC_MAX9768) += snd-soc-max9768.o |
157 | obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o | 160 | obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o |
161 | obj-$(CONFIG_SND_SOC_MAX98090) += snd-soc-max98090.o | ||
158 | obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o | 162 | obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o |
159 | obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o | 163 | obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o |
160 | obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o | 164 | obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o |
@@ -164,6 +168,7 @@ obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o | |||
164 | obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o | 168 | obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o |
165 | obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o | 169 | obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o |
166 | obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o | 170 | obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o |
171 | obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o | ||
167 | obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o | 172 | obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o |
168 | obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o | 173 | obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o |
169 | obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o | 174 | obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o |
@@ -229,6 +234,7 @@ obj-$(CONFIG_SND_SOC_WM9090) += snd-soc-wm9090.o | |||
229 | obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o | 234 | obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o |
230 | obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o | 235 | obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o |
231 | obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o | 236 | obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o |
237 | obj-$(CONFIG_SND_SOC_WM_ADSP) += snd-soc-wm-adsp.o | ||
232 | obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o | 238 | obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o |
233 | 239 | ||
234 | # Amp | 240 | # Amp |
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index af547490b4f7..4d96090db662 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c | |||
@@ -2356,7 +2356,7 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai, | |||
2356 | return 0; | 2356 | return 0; |
2357 | } | 2357 | } |
2358 | 2358 | ||
2359 | struct snd_soc_dai_driver ab8500_codec_dai[] = { | 2359 | static struct snd_soc_dai_driver ab8500_codec_dai[] = { |
2360 | { | 2360 | { |
2361 | .name = "ab8500-codec-dai.0", | 2361 | .name = "ab8500-codec-dai.0", |
2362 | .id = 0, | 2362 | .id = 0, |
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c index 31d4483245d0..4b11b82b2273 100644 --- a/sound/soc/codecs/ak4104.c +++ b/sound/soc/codecs/ak4104.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <sound/soc.h> | 15 | #include <sound/soc.h> |
16 | #include <sound/initval.h> | 16 | #include <sound/initval.h> |
17 | #include <linux/spi/spi.h> | 17 | #include <linux/spi/spi.h> |
18 | #include <linux/of_device.h> | ||
19 | #include <linux/of_gpio.h> | ||
18 | #include <sound/asoundef.h> | 20 | #include <sound/asoundef.h> |
19 | 21 | ||
20 | /* AK4104 registers addresses */ | 22 | /* AK4104 registers addresses */ |
@@ -98,14 +100,32 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream, | |||
98 | val = 0; | 100 | val = 0; |
99 | 101 | ||
100 | switch (params_rate(params)) { | 102 | switch (params_rate(params)) { |
103 | case 22050: | ||
104 | val |= IEC958_AES3_CON_FS_22050; | ||
105 | break; | ||
106 | case 24000: | ||
107 | val |= IEC958_AES3_CON_FS_24000; | ||
108 | break; | ||
109 | case 32000: | ||
110 | val |= IEC958_AES3_CON_FS_32000; | ||
111 | break; | ||
101 | case 44100: | 112 | case 44100: |
102 | val |= IEC958_AES3_CON_FS_44100; | 113 | val |= IEC958_AES3_CON_FS_44100; |
103 | break; | 114 | break; |
104 | case 48000: | 115 | case 48000: |
105 | val |= IEC958_AES3_CON_FS_48000; | 116 | val |= IEC958_AES3_CON_FS_48000; |
106 | break; | 117 | break; |
107 | case 32000: | 118 | case 88200: |
108 | val |= IEC958_AES3_CON_FS_32000; | 119 | val |= IEC958_AES3_CON_FS_88200; |
120 | break; | ||
121 | case 96000: | ||
122 | val |= IEC958_AES3_CON_FS_96000; | ||
123 | break; | ||
124 | case 176400: | ||
125 | val |= IEC958_AES3_CON_FS_176400; | ||
126 | break; | ||
127 | case 192000: | ||
128 | val |= IEC958_AES3_CON_FS_192000; | ||
109 | break; | 129 | break; |
110 | default: | 130 | default: |
111 | dev_err(codec->dev, "unsupported sampling rate\n"); | 131 | dev_err(codec->dev, "unsupported sampling rate\n"); |
@@ -186,6 +206,7 @@ static const struct regmap_config ak4104_regmap = { | |||
186 | 206 | ||
187 | static int ak4104_spi_probe(struct spi_device *spi) | 207 | static int ak4104_spi_probe(struct spi_device *spi) |
188 | { | 208 | { |
209 | struct device_node *np = spi->dev.of_node; | ||
189 | struct ak4104_private *ak4104; | 210 | struct ak4104_private *ak4104; |
190 | unsigned int val; | 211 | unsigned int val; |
191 | int ret; | 212 | int ret; |
@@ -201,49 +222,59 @@ static int ak4104_spi_probe(struct spi_device *spi) | |||
201 | if (ak4104 == NULL) | 222 | if (ak4104 == NULL) |
202 | return -ENOMEM; | 223 | return -ENOMEM; |
203 | 224 | ||
204 | ak4104->regmap = regmap_init_spi(spi, &ak4104_regmap); | 225 | ak4104->regmap = devm_regmap_init_spi(spi, &ak4104_regmap); |
205 | if (IS_ERR(ak4104->regmap)) { | 226 | if (IS_ERR(ak4104->regmap)) { |
206 | ret = PTR_ERR(ak4104->regmap); | 227 | ret = PTR_ERR(ak4104->regmap); |
207 | return ret; | 228 | return ret; |
208 | } | 229 | } |
209 | 230 | ||
231 | if (np) { | ||
232 | enum of_gpio_flags flags; | ||
233 | int gpio = of_get_named_gpio_flags(np, "reset-gpio", 0, &flags); | ||
234 | |||
235 | if (gpio_is_valid(gpio)) { | ||
236 | ret = devm_gpio_request_one(&spi->dev, gpio, | ||
237 | flags & OF_GPIO_ACTIVE_LOW ? | ||
238 | GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH, | ||
239 | "ak4104 reset"); | ||
240 | if (ret < 0) | ||
241 | return ret; | ||
242 | } | ||
243 | } | ||
244 | |||
210 | /* read the 'reserved' register - according to the datasheet, it | 245 | /* read the 'reserved' register - according to the datasheet, it |
211 | * should contain 0x5b. Not a good way to verify the presence of | 246 | * should contain 0x5b. Not a good way to verify the presence of |
212 | * the device, but there is no hardware ID register. */ | 247 | * the device, but there is no hardware ID register. */ |
213 | ret = regmap_read(ak4104->regmap, AK4104_REG_RESERVED, &val); | 248 | ret = regmap_read(ak4104->regmap, AK4104_REG_RESERVED, &val); |
214 | if (ret != 0) | 249 | if (ret != 0) |
215 | goto err; | 250 | return ret; |
216 | if (val != AK4104_RESERVED_VAL) { | 251 | if (val != AK4104_RESERVED_VAL) |
217 | ret = -ENODEV; | 252 | return -ENODEV; |
218 | goto err; | ||
219 | } | ||
220 | 253 | ||
221 | spi_set_drvdata(spi, ak4104); | 254 | spi_set_drvdata(spi, ak4104); |
222 | 255 | ||
223 | ret = snd_soc_register_codec(&spi->dev, | 256 | ret = snd_soc_register_codec(&spi->dev, |
224 | &soc_codec_device_ak4104, &ak4104_dai, 1); | 257 | &soc_codec_device_ak4104, &ak4104_dai, 1); |
225 | if (ret != 0) | ||
226 | goto err; | ||
227 | |||
228 | return 0; | ||
229 | |||
230 | err: | ||
231 | regmap_exit(ak4104->regmap); | ||
232 | return ret; | 258 | return ret; |
233 | } | 259 | } |
234 | 260 | ||
235 | static int __devexit ak4104_spi_remove(struct spi_device *spi) | 261 | static int __devexit ak4104_spi_remove(struct spi_device *spi) |
236 | { | 262 | { |
237 | struct ak4104_private *ak4101 = spi_get_drvdata(spi); | ||
238 | regmap_exit(ak4101->regmap); | ||
239 | snd_soc_unregister_codec(&spi->dev); | 263 | snd_soc_unregister_codec(&spi->dev); |
240 | return 0; | 264 | return 0; |
241 | } | 265 | } |
242 | 266 | ||
267 | static const struct of_device_id ak4104_of_match[] = { | ||
268 | { .compatible = "asahi-kasei,ak4104", }, | ||
269 | { } | ||
270 | }; | ||
271 | MODULE_DEVICE_TABLE(of, ak4104_of_match); | ||
272 | |||
243 | static struct spi_driver ak4104_spi_driver = { | 273 | static struct spi_driver ak4104_spi_driver = { |
244 | .driver = { | 274 | .driver = { |
245 | .name = DRV_NAME, | 275 | .name = DRV_NAME, |
246 | .owner = THIS_MODULE, | 276 | .owner = THIS_MODULE, |
277 | .of_match_table = ak4104_of_match, | ||
247 | }, | 278 | }, |
248 | .probe = ak4104_spi_probe, | 279 | .probe = ak4104_spi_probe, |
249 | .remove = __devexit_p(ak4104_spi_remove), | 280 | .remove = __devexit_p(ak4104_spi_remove), |
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index 618fdc30f73e..fc5581063b2d 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c | |||
@@ -447,7 +447,7 @@ static __devinit int ak4535_i2c_probe(struct i2c_client *i2c, | |||
447 | if (ak4535 == NULL) | 447 | if (ak4535 == NULL) |
448 | return -ENOMEM; | 448 | return -ENOMEM; |
449 | 449 | ||
450 | ak4535->regmap = regmap_init_i2c(i2c, &ak4535_regmap); | 450 | ak4535->regmap = devm_regmap_init_i2c(i2c, &ak4535_regmap); |
451 | if (IS_ERR(ak4535->regmap)) { | 451 | if (IS_ERR(ak4535->regmap)) { |
452 | ret = PTR_ERR(ak4535->regmap); | 452 | ret = PTR_ERR(ak4535->regmap); |
453 | dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret); | 453 | dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret); |
@@ -458,18 +458,13 @@ static __devinit int ak4535_i2c_probe(struct i2c_client *i2c, | |||
458 | 458 | ||
459 | ret = snd_soc_register_codec(&i2c->dev, | 459 | ret = snd_soc_register_codec(&i2c->dev, |
460 | &soc_codec_dev_ak4535, &ak4535_dai, 1); | 460 | &soc_codec_dev_ak4535, &ak4535_dai, 1); |
461 | if (ret != 0) | ||
462 | regmap_exit(ak4535->regmap); | ||
463 | 461 | ||
464 | return ret; | 462 | return ret; |
465 | } | 463 | } |
466 | 464 | ||
467 | static __devexit int ak4535_i2c_remove(struct i2c_client *client) | 465 | static __devexit int ak4535_i2c_remove(struct i2c_client *client) |
468 | { | 466 | { |
469 | struct ak4535_priv *ak4535 = i2c_get_clientdata(client); | ||
470 | |||
471 | snd_soc_unregister_codec(&client->dev); | 467 | snd_soc_unregister_codec(&client->dev); |
472 | regmap_exit(ak4535->regmap); | ||
473 | return 0; | 468 | return 0; |
474 | } | 469 | } |
475 | 470 | ||
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index b3e24f289421..546466abb77f 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c | |||
@@ -194,12 +194,6 @@ static const struct snd_soc_dapm_route ak4642_intercon[] = { | |||
194 | {"LINEOUT Mixer", "DACL", "DAC"}, | 194 | {"LINEOUT Mixer", "DACL", "DAC"}, |
195 | }; | 195 | }; |
196 | 196 | ||
197 | /* codec private data */ | ||
198 | struct ak4642_priv { | ||
199 | unsigned int sysclk; | ||
200 | enum snd_soc_control_type control_type; | ||
201 | }; | ||
202 | |||
203 | /* | 197 | /* |
204 | * ak4642 register cache | 198 | * ak4642 register cache |
205 | */ | 199 | */ |
@@ -468,10 +462,9 @@ static int ak4642_resume(struct snd_soc_codec *codec) | |||
468 | 462 | ||
469 | static int ak4642_probe(struct snd_soc_codec *codec) | 463 | static int ak4642_probe(struct snd_soc_codec *codec) |
470 | { | 464 | { |
471 | struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec); | ||
472 | int ret; | 465 | int ret; |
473 | 466 | ||
474 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4642->control_type); | 467 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); |
475 | if (ret < 0) { | 468 | if (ret < 0) { |
476 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 469 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
477 | return ret; | 470 | return ret; |
@@ -523,21 +516,9 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4648 = { | |||
523 | static __devinit int ak4642_i2c_probe(struct i2c_client *i2c, | 516 | static __devinit int ak4642_i2c_probe(struct i2c_client *i2c, |
524 | const struct i2c_device_id *id) | 517 | const struct i2c_device_id *id) |
525 | { | 518 | { |
526 | struct ak4642_priv *ak4642; | 519 | return snd_soc_register_codec(&i2c->dev, |
527 | int ret; | ||
528 | |||
529 | ak4642 = devm_kzalloc(&i2c->dev, sizeof(struct ak4642_priv), | ||
530 | GFP_KERNEL); | ||
531 | if (!ak4642) | ||
532 | return -ENOMEM; | ||
533 | |||
534 | i2c_set_clientdata(i2c, ak4642); | ||
535 | ak4642->control_type = SND_SOC_I2C; | ||
536 | |||
537 | ret = snd_soc_register_codec(&i2c->dev, | ||
538 | (struct snd_soc_codec_driver *)id->driver_data, | 520 | (struct snd_soc_codec_driver *)id->driver_data, |
539 | &ak4642_dai, 1); | 521 | &ak4642_dai, 1); |
540 | return ret; | ||
541 | } | 522 | } |
542 | 523 | ||
543 | static __devexit int ak4642_i2c_remove(struct i2c_client *client) | 524 | static __devexit int ak4642_i2c_remove(struct i2c_client *client) |
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 054967d8bac2..87cfaa3a6f0e 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c | |||
@@ -380,6 +380,18 @@ int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, | |||
380 | case 49152000: | 380 | case 49152000: |
381 | val |= 3 << ARIZONA_SYSCLK_FREQ_SHIFT; | 381 | val |= 3 << ARIZONA_SYSCLK_FREQ_SHIFT; |
382 | break; | 382 | break; |
383 | case 67737600: | ||
384 | case 73728000: | ||
385 | val |= 4 << ARIZONA_SYSCLK_FREQ_SHIFT; | ||
386 | break; | ||
387 | case 90316800: | ||
388 | case 98304000: | ||
389 | val |= 5 << ARIZONA_SYSCLK_FREQ_SHIFT; | ||
390 | break; | ||
391 | case 135475200: | ||
392 | case 147456000: | ||
393 | val |= 6 << ARIZONA_SYSCLK_FREQ_SHIFT; | ||
394 | break; | ||
383 | default: | 395 | default: |
384 | return -EINVAL; | 396 | return -EINVAL; |
385 | } | 397 | } |
@@ -925,6 +937,9 @@ int arizona_set_fll(struct arizona_fll *fll, int source, | |||
925 | bool ena; | 937 | bool ena; |
926 | int ret; | 938 | int ret; |
927 | 939 | ||
940 | if (fll->fref == Fref && fll->fout == Fout) | ||
941 | return 0; | ||
942 | |||
928 | ret = regmap_read(arizona->regmap, fll->base + 1, ®); | 943 | ret = regmap_read(arizona->regmap, fll->base + 1, ®); |
929 | if (ret != 0) { | 944 | if (ret != 0) { |
930 | arizona_fll_err(fll, "Failed to read current state: %d\n", | 945 | arizona_fll_err(fll, "Failed to read current state: %d\n", |
@@ -970,6 +985,9 @@ int arizona_set_fll(struct arizona_fll *fll, int source, | |||
970 | if (ena) | 985 | if (ena) |
971 | pm_runtime_put_autosuspend(arizona->dev); | 986 | pm_runtime_put_autosuspend(arizona->dev); |
972 | 987 | ||
988 | fll->fref = Fref; | ||
989 | fll->fout = Fout; | ||
990 | |||
973 | return 0; | 991 | return 0; |
974 | } | 992 | } |
975 | 993 | ||
@@ -1002,6 +1020,9 @@ int arizona_set_fll(struct arizona_fll *fll, int source, | |||
1002 | if (ret == 0) | 1020 | if (ret == 0) |
1003 | arizona_fll_warn(fll, "Timed out waiting for lock\n"); | 1021 | arizona_fll_warn(fll, "Timed out waiting for lock\n"); |
1004 | 1022 | ||
1023 | fll->fref = Fref; | ||
1024 | fll->fout = Fout; | ||
1025 | |||
1005 | return 0; | 1026 | return 0; |
1006 | } | 1027 | } |
1007 | EXPORT_SYMBOL_GPL(arizona_set_fll); | 1028 | EXPORT_SYMBOL_GPL(arizona_set_fll); |
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 36ec64946120..84c415d335bd 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h | |||
@@ -17,6 +17,8 @@ | |||
17 | 17 | ||
18 | #include <sound/soc.h> | 18 | #include <sound/soc.h> |
19 | 19 | ||
20 | #include "wm_adsp.h" | ||
21 | |||
20 | #define ARIZONA_CLK_SYSCLK 1 | 22 | #define ARIZONA_CLK_SYSCLK 1 |
21 | #define ARIZONA_CLK_ASYNCCLK 2 | 23 | #define ARIZONA_CLK_ASYNCCLK 2 |
22 | #define ARIZONA_CLK_OPCLK 3 | 24 | #define ARIZONA_CLK_OPCLK 3 |
@@ -46,15 +48,18 @@ | |||
46 | #define ARIZONA_MIXER_VOL_SHIFT 1 | 48 | #define ARIZONA_MIXER_VOL_SHIFT 1 |
47 | #define ARIZONA_MIXER_VOL_WIDTH 7 | 49 | #define ARIZONA_MIXER_VOL_WIDTH 7 |
48 | 50 | ||
49 | #define ARIZONA_MAX_DAI 3 | 51 | #define ARIZONA_MAX_DAI 4 |
52 | #define ARIZONA_MAX_ADSP 4 | ||
50 | 53 | ||
51 | struct arizona; | 54 | struct arizona; |
55 | struct wm_adsp; | ||
52 | 56 | ||
53 | struct arizona_dai_priv { | 57 | struct arizona_dai_priv { |
54 | int clk; | 58 | int clk; |
55 | }; | 59 | }; |
56 | 60 | ||
57 | struct arizona_priv { | 61 | struct arizona_priv { |
62 | struct wm_adsp adsp[ARIZONA_MAX_ADSP]; | ||
58 | struct arizona *arizona; | 63 | struct arizona *arizona; |
59 | int sysclk; | 64 | int sysclk; |
60 | int asyncclk; | 65 | int asyncclk; |
@@ -89,19 +94,30 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; | |||
89 | const struct snd_kcontrol_new name##_mux = \ | 94 | const struct snd_kcontrol_new name##_mux = \ |
90 | SOC_DAPM_VALUE_ENUM("Route", name##_enum) | 95 | SOC_DAPM_VALUE_ENUM("Route", name##_enum) |
91 | 96 | ||
97 | #define ARIZONA_MUX_ENUMS(name, base_reg) \ | ||
98 | static ARIZONA_MUX_ENUM_DECL(name##_enum, base_reg); \ | ||
99 | static ARIZONA_MUX_CTL_DECL(name) | ||
100 | |||
92 | #define ARIZONA_MIXER_ENUMS(name, base_reg) \ | 101 | #define ARIZONA_MIXER_ENUMS(name, base_reg) \ |
93 | static ARIZONA_MUX_ENUM_DECL(name##_in1_enum, base_reg); \ | 102 | ARIZONA_MUX_ENUMS(name##_in1, base_reg); \ |
94 | static ARIZONA_MUX_ENUM_DECL(name##_in2_enum, base_reg + 2); \ | 103 | ARIZONA_MUX_ENUMS(name##_in2, base_reg + 2); \ |
95 | static ARIZONA_MUX_ENUM_DECL(name##_in3_enum, base_reg + 4); \ | 104 | ARIZONA_MUX_ENUMS(name##_in3, base_reg + 4); \ |
96 | static ARIZONA_MUX_ENUM_DECL(name##_in4_enum, base_reg + 6); \ | 105 | ARIZONA_MUX_ENUMS(name##_in4, base_reg + 6) |
97 | static ARIZONA_MUX_CTL_DECL(name##_in1); \ | 106 | |
98 | static ARIZONA_MUX_CTL_DECL(name##_in2); \ | 107 | #define ARIZONA_DSP_AUX_ENUMS(name, base_reg) \ |
99 | static ARIZONA_MUX_CTL_DECL(name##_in3); \ | 108 | ARIZONA_MUX_ENUMS(name##_aux1, base_reg); \ |
100 | static ARIZONA_MUX_CTL_DECL(name##_in4) | 109 | ARIZONA_MUX_ENUMS(name##_aux2, base_reg + 8); \ |
110 | ARIZONA_MUX_ENUMS(name##_aux3, base_reg + 16); \ | ||
111 | ARIZONA_MUX_ENUMS(name##_aux4, base_reg + 24); \ | ||
112 | ARIZONA_MUX_ENUMS(name##_aux5, base_reg + 32); \ | ||
113 | ARIZONA_MUX_ENUMS(name##_aux6, base_reg + 40) | ||
101 | 114 | ||
102 | #define ARIZONA_MUX(name, ctrl) \ | 115 | #define ARIZONA_MUX(name, ctrl) \ |
103 | SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) | 116 | SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) |
104 | 117 | ||
118 | #define ARIZONA_MUX_WIDGETS(name, name_str) \ | ||
119 | ARIZONA_MUX(name_str " Input", &name##_mux) | ||
120 | |||
105 | #define ARIZONA_MIXER_WIDGETS(name, name_str) \ | 121 | #define ARIZONA_MIXER_WIDGETS(name, name_str) \ |
106 | ARIZONA_MUX(name_str " Input 1", &name##_in1_mux), \ | 122 | ARIZONA_MUX(name_str " Input 1", &name##_in1_mux), \ |
107 | ARIZONA_MUX(name_str " Input 2", &name##_in2_mux), \ | 123 | ARIZONA_MUX(name_str " Input 2", &name##_in2_mux), \ |
@@ -109,6 +125,19 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; | |||
109 | ARIZONA_MUX(name_str " Input 4", &name##_in4_mux), \ | 125 | ARIZONA_MUX(name_str " Input 4", &name##_in4_mux), \ |
110 | SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0) | 126 | SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0) |
111 | 127 | ||
128 | #define ARIZONA_DSP_WIDGETS(name, name_str) \ | ||
129 | ARIZONA_MIXER_WIDGETS(name##L, name_str "L"), \ | ||
130 | ARIZONA_MIXER_WIDGETS(name##R, name_str "R"), \ | ||
131 | ARIZONA_MUX(name_str " Aux 1", &name##_aux1_mux), \ | ||
132 | ARIZONA_MUX(name_str " Aux 2", &name##_aux2_mux), \ | ||
133 | ARIZONA_MUX(name_str " Aux 3", &name##_aux3_mux), \ | ||
134 | ARIZONA_MUX(name_str " Aux 4", &name##_aux4_mux), \ | ||
135 | ARIZONA_MUX(name_str " Aux 5", &name##_aux5_mux), \ | ||
136 | ARIZONA_MUX(name_str " Aux 6", &name##_aux6_mux) | ||
137 | |||
138 | #define ARIZONA_MUX_ROUTES(name) \ | ||
139 | ARIZONA_MIXER_INPUT_ROUTES(name " Input") | ||
140 | |||
112 | #define ARIZONA_MIXER_ROUTES(widget, name) \ | 141 | #define ARIZONA_MIXER_ROUTES(widget, name) \ |
113 | { widget, NULL, name " Mixer" }, \ | 142 | { widget, NULL, name " Mixer" }, \ |
114 | { name " Mixer", NULL, name " Input 1" }, \ | 143 | { name " Mixer", NULL, name " Input 1" }, \ |
@@ -120,6 +149,22 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; | |||
120 | ARIZONA_MIXER_INPUT_ROUTES(name " Input 3"), \ | 149 | ARIZONA_MIXER_INPUT_ROUTES(name " Input 3"), \ |
121 | ARIZONA_MIXER_INPUT_ROUTES(name " Input 4") | 150 | ARIZONA_MIXER_INPUT_ROUTES(name " Input 4") |
122 | 151 | ||
152 | #define ARIZONA_DSP_ROUTES(name) \ | ||
153 | { name, NULL, name " Aux 1" }, \ | ||
154 | { name, NULL, name " Aux 2" }, \ | ||
155 | { name, NULL, name " Aux 3" }, \ | ||
156 | { name, NULL, name " Aux 4" }, \ | ||
157 | { name, NULL, name " Aux 5" }, \ | ||
158 | { name, NULL, name " Aux 6" }, \ | ||
159 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 1"), \ | ||
160 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 2"), \ | ||
161 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 3"), \ | ||
162 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 4"), \ | ||
163 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 5"), \ | ||
164 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 6"), \ | ||
165 | ARIZONA_MIXER_ROUTES(name, name "L"), \ | ||
166 | ARIZONA_MIXER_ROUTES(name, name "R") | ||
167 | |||
123 | extern const struct soc_enum arizona_lhpf1_mode; | 168 | extern const struct soc_enum arizona_lhpf1_mode; |
124 | extern const struct soc_enum arizona_lhpf2_mode; | 169 | extern const struct soc_enum arizona_lhpf2_mode; |
125 | extern const struct soc_enum arizona_lhpf3_mode; | 170 | extern const struct soc_enum arizona_lhpf3_mode; |
@@ -146,6 +191,8 @@ struct arizona_fll { | |||
146 | unsigned int vco_mult; | 191 | unsigned int vco_mult; |
147 | struct completion lock; | 192 | struct completion lock; |
148 | struct completion ok; | 193 | struct completion ok; |
194 | unsigned int fref; | ||
195 | unsigned int fout; | ||
149 | 196 | ||
150 | char lock_name[ARIZONA_FLL_NAME_LEN]; | 197 | char lock_name[ARIZONA_FLL_NAME_LEN]; |
151 | char clock_ok_name[ARIZONA_FLL_NAME_LEN]; | 198 | char clock_ok_name[ARIZONA_FLL_NAME_LEN]; |
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index e3f0a7f3131e..6ad3878db8fc 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c | |||
@@ -474,15 +474,25 @@ static int cs4271_probe(struct snd_soc_codec *codec) | |||
474 | struct cs4271_platform_data *cs4271plat = codec->dev->platform_data; | 474 | struct cs4271_platform_data *cs4271plat = codec->dev->platform_data; |
475 | int ret; | 475 | int ret; |
476 | int gpio_nreset = -EINVAL; | 476 | int gpio_nreset = -EINVAL; |
477 | int amutec_eq_bmutec = 0; | ||
477 | 478 | ||
478 | #ifdef CONFIG_OF | 479 | #ifdef CONFIG_OF |
479 | if (of_match_device(cs4271_dt_ids, codec->dev)) | 480 | if (of_match_device(cs4271_dt_ids, codec->dev)) { |
480 | gpio_nreset = of_get_named_gpio(codec->dev->of_node, | 481 | gpio_nreset = of_get_named_gpio(codec->dev->of_node, |
481 | "reset-gpio", 0); | 482 | "reset-gpio", 0); |
483 | |||
484 | if (!of_get_property(codec->dev->of_node, | ||
485 | "cirrus,amutec-eq-bmutec", NULL)) | ||
486 | amutec_eq_bmutec = 1; | ||
487 | } | ||
482 | #endif | 488 | #endif |
483 | 489 | ||
484 | if (cs4271plat && gpio_is_valid(cs4271plat->gpio_nreset)) | 490 | if (cs4271plat) { |
485 | gpio_nreset = cs4271plat->gpio_nreset; | 491 | if (gpio_is_valid(cs4271plat->gpio_nreset)) |
492 | gpio_nreset = cs4271plat->gpio_nreset; | ||
493 | |||
494 | amutec_eq_bmutec = cs4271plat->amutec_eq_bmutec; | ||
495 | } | ||
486 | 496 | ||
487 | if (gpio_nreset >= 0) | 497 | if (gpio_nreset >= 0) |
488 | if (devm_gpio_request(codec->dev, gpio_nreset, "CS4271 Reset")) | 498 | if (devm_gpio_request(codec->dev, gpio_nreset, "CS4271 Reset")) |
@@ -528,6 +538,11 @@ static int cs4271_probe(struct snd_soc_codec *codec) | |||
528 | /* Power-up sequence requires 85 uS */ | 538 | /* Power-up sequence requires 85 uS */ |
529 | udelay(85); | 539 | udelay(85); |
530 | 540 | ||
541 | if (amutec_eq_bmutec) | ||
542 | snd_soc_update_bits(codec, CS4271_MODE2, | ||
543 | CS4271_MODE2_MUTECAEQUB, | ||
544 | CS4271_MODE2_MUTECAEQUB); | ||
545 | |||
531 | return snd_soc_add_codec_controls(codec, cs4271_snd_controls, | 546 | return snd_soc_add_codec_controls(codec, cs4271_snd_controls, |
532 | ARRAY_SIZE(cs4271_snd_controls)); | 547 | ARRAY_SIZE(cs4271_snd_controls)); |
533 | } | 548 | } |
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index af5db7080519..ab1ee5b734db 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c | |||
@@ -1231,7 +1231,7 @@ static int __devinit da7210_i2c_probe(struct i2c_client *i2c, | |||
1231 | 1231 | ||
1232 | i2c_set_clientdata(i2c, da7210); | 1232 | i2c_set_clientdata(i2c, da7210); |
1233 | 1233 | ||
1234 | da7210->regmap = regmap_init_i2c(i2c, &da7210_regmap_config_i2c); | 1234 | da7210->regmap = devm_regmap_init_i2c(i2c, &da7210_regmap_config_i2c); |
1235 | if (IS_ERR(da7210->regmap)) { | 1235 | if (IS_ERR(da7210->regmap)) { |
1236 | ret = PTR_ERR(da7210->regmap); | 1236 | ret = PTR_ERR(da7210->regmap); |
1237 | dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); | 1237 | dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); |
@@ -1245,24 +1245,15 @@ static int __devinit da7210_i2c_probe(struct i2c_client *i2c, | |||
1245 | 1245 | ||
1246 | ret = snd_soc_register_codec(&i2c->dev, | 1246 | ret = snd_soc_register_codec(&i2c->dev, |
1247 | &soc_codec_dev_da7210, &da7210_dai, 1); | 1247 | &soc_codec_dev_da7210, &da7210_dai, 1); |
1248 | if (ret < 0) { | 1248 | if (ret < 0) |
1249 | dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); | 1249 | dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); |
1250 | goto err_regmap; | ||
1251 | } | ||
1252 | return ret; | ||
1253 | |||
1254 | err_regmap: | ||
1255 | regmap_exit(da7210->regmap); | ||
1256 | 1250 | ||
1257 | return ret; | 1251 | return ret; |
1258 | } | 1252 | } |
1259 | 1253 | ||
1260 | static int __devexit da7210_i2c_remove(struct i2c_client *client) | 1254 | static int __devexit da7210_i2c_remove(struct i2c_client *client) |
1261 | { | 1255 | { |
1262 | struct da7210_priv *da7210 = i2c_get_clientdata(client); | ||
1263 | |||
1264 | snd_soc_unregister_codec(&client->dev); | 1256 | snd_soc_unregister_codec(&client->dev); |
1265 | regmap_exit(da7210->regmap); | ||
1266 | return 0; | 1257 | return 0; |
1267 | } | 1258 | } |
1268 | 1259 | ||
diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c index f379b085c392..d3a6de2e757b 100644 --- a/sound/soc/codecs/da9055.c +++ b/sound/soc/codecs/da9055.c | |||
@@ -173,6 +173,7 @@ | |||
173 | #define DA9055_AIF_FORMAT_I2S_MODE (0 << 0) | 173 | #define DA9055_AIF_FORMAT_I2S_MODE (0 << 0) |
174 | #define DA9055_AIF_FORMAT_LEFT_J (1 << 0) | 174 | #define DA9055_AIF_FORMAT_LEFT_J (1 << 0) |
175 | #define DA9055_AIF_FORMAT_RIGHT_J (2 << 0) | 175 | #define DA9055_AIF_FORMAT_RIGHT_J (2 << 0) |
176 | #define DA9055_AIF_FORMAT_DSP (3 << 0) | ||
176 | #define DA9055_AIF_WORD_S16_LE (0 << 2) | 177 | #define DA9055_AIF_WORD_S16_LE (0 << 2) |
177 | #define DA9055_AIF_WORD_S20_3LE (1 << 2) | 178 | #define DA9055_AIF_WORD_S20_3LE (1 << 2) |
178 | #define DA9055_AIF_WORD_S24_LE (2 << 2) | 179 | #define DA9055_AIF_WORD_S24_LE (2 << 2) |
@@ -752,6 +753,17 @@ static const struct snd_kcontrol_new da9055_dapm_mixoutr_controls[] = { | |||
752 | 6, 1, 0), | 753 | 6, 1, 0), |
753 | }; | 754 | }; |
754 | 755 | ||
756 | /* Headphone Output Enable */ | ||
757 | static const struct snd_kcontrol_new da9055_dapm_hp_l_control = | ||
758 | SOC_DAPM_SINGLE("Switch", DA9055_HP_L_CTRL, 3, 1, 0); | ||
759 | |||
760 | static const struct snd_kcontrol_new da9055_dapm_hp_r_control = | ||
761 | SOC_DAPM_SINGLE("Switch", DA9055_HP_R_CTRL, 3, 1, 0); | ||
762 | |||
763 | /* Lineout Output Enable */ | ||
764 | static const struct snd_kcontrol_new da9055_dapm_lineout_control = | ||
765 | SOC_DAPM_SINGLE("Switch", DA9055_LINE_CTRL, 3, 1, 0); | ||
766 | |||
755 | /* DAPM widgets */ | 767 | /* DAPM widgets */ |
756 | static const struct snd_soc_dapm_widget da9055_dapm_widgets[] = { | 768 | static const struct snd_soc_dapm_widget da9055_dapm_widgets[] = { |
757 | /* Input Side */ | 769 | /* Input Side */ |
@@ -816,6 +828,14 @@ static const struct snd_soc_dapm_widget da9055_dapm_widgets[] = { | |||
816 | &da9055_dapm_mixoutr_controls[0], | 828 | &da9055_dapm_mixoutr_controls[0], |
817 | ARRAY_SIZE(da9055_dapm_mixoutr_controls)), | 829 | ARRAY_SIZE(da9055_dapm_mixoutr_controls)), |
818 | 830 | ||
831 | /* Output Enable Switches */ | ||
832 | SND_SOC_DAPM_SWITCH("Headphone Left Enable", SND_SOC_NOPM, 0, 0, | ||
833 | &da9055_dapm_hp_l_control), | ||
834 | SND_SOC_DAPM_SWITCH("Headphone Right Enable", SND_SOC_NOPM, 0, 0, | ||
835 | &da9055_dapm_hp_r_control), | ||
836 | SND_SOC_DAPM_SWITCH("Lineout Enable", SND_SOC_NOPM, 0, 0, | ||
837 | &da9055_dapm_lineout_control), | ||
838 | |||
819 | /* Output PGAs */ | 839 | /* Output PGAs */ |
820 | SND_SOC_DAPM_PGA("MIXOUT Left", DA9055_MIXOUT_L_CTRL, 7, 0, NULL, 0), | 840 | SND_SOC_DAPM_PGA("MIXOUT Left", DA9055_MIXOUT_L_CTRL, 7, 0, NULL, 0), |
821 | SND_SOC_DAPM_PGA("MIXOUT Right", DA9055_MIXOUT_R_CTRL, 7, 0, NULL, 0), | 841 | SND_SOC_DAPM_PGA("MIXOUT Right", DA9055_MIXOUT_R_CTRL, 7, 0, NULL, 0), |
@@ -901,17 +921,20 @@ static const struct snd_soc_dapm_route da9055_audio_map[] = { | |||
901 | {"Out Mixer Right", "DAC Right Switch", "DAC Right"}, | 921 | {"Out Mixer Right", "DAC Right Switch", "DAC Right"}, |
902 | 922 | ||
903 | {"MIXOUT Left", NULL, "Out Mixer Left"}, | 923 | {"MIXOUT Left", NULL, "Out Mixer Left"}, |
904 | {"Headphone Left", NULL, "MIXOUT Left"}, | 924 | {"Headphone Left Enable", "Switch", "MIXOUT Left"}, |
925 | {"Headphone Left", NULL, "Headphone Left Enable"}, | ||
905 | {"Headphone Left", NULL, "Charge Pump"}, | 926 | {"Headphone Left", NULL, "Charge Pump"}, |
906 | {"HPL", NULL, "Headphone Left"}, | 927 | {"HPL", NULL, "Headphone Left"}, |
907 | 928 | ||
908 | {"MIXOUT Right", NULL, "Out Mixer Right"}, | 929 | {"MIXOUT Right", NULL, "Out Mixer Right"}, |
909 | {"Headphone Right", NULL, "MIXOUT Right"}, | 930 | {"Headphone Right Enable", "Switch", "MIXOUT Right"}, |
931 | {"Headphone Right", NULL, "Headphone Right Enable"}, | ||
910 | {"Headphone Right", NULL, "Charge Pump"}, | 932 | {"Headphone Right", NULL, "Charge Pump"}, |
911 | {"HPR", NULL, "Headphone Right"}, | 933 | {"HPR", NULL, "Headphone Right"}, |
912 | 934 | ||
913 | {"MIXOUT Right", NULL, "Out Mixer Right"}, | 935 | {"MIXOUT Right", NULL, "Out Mixer Right"}, |
914 | {"Lineout", NULL, "MIXOUT Right"}, | 936 | {"Lineout Enable", "Switch", "MIXOUT Right"}, |
937 | {"Lineout", NULL, "Lineout Enable"}, | ||
915 | {"LINE", NULL, "Lineout"}, | 938 | {"LINE", NULL, "Lineout"}, |
916 | }; | 939 | }; |
917 | 940 | ||
@@ -1175,6 +1198,9 @@ static int da9055_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) | |||
1175 | case SND_SOC_DAIFMT_RIGHT_J: | 1198 | case SND_SOC_DAIFMT_RIGHT_J: |
1176 | aif_ctrl = DA9055_AIF_FORMAT_RIGHT_J; | 1199 | aif_ctrl = DA9055_AIF_FORMAT_RIGHT_J; |
1177 | break; | 1200 | break; |
1201 | case SND_SOC_DAIFMT_DSP_A: | ||
1202 | aif_ctrl = DA9055_AIF_FORMAT_DSP; | ||
1203 | break; | ||
1178 | default: | 1204 | default: |
1179 | return -EINVAL; | 1205 | return -EINVAL; |
1180 | } | 1206 | } |
@@ -1390,8 +1416,7 @@ static int da9055_probe(struct snd_soc_codec *codec) | |||
1390 | DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN); | 1416 | DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN); |
1391 | 1417 | ||
1392 | /* | 1418 | /* |
1393 | * There are two separate control bits for input and output mixers as | 1419 | * There are two separate control bits for input and output mixers. |
1394 | * well as headphone and line outs. | ||
1395 | * One to enable corresponding amplifier and other to enable its | 1420 | * One to enable corresponding amplifier and other to enable its |
1396 | * output. As amplifier bits are related to power control, they are | 1421 | * output. As amplifier bits are related to power control, they are |
1397 | * being managed by DAPM while other (non power related) bits are | 1422 | * being managed by DAPM while other (non power related) bits are |
@@ -1407,14 +1432,6 @@ static int da9055_probe(struct snd_soc_codec *codec) | |||
1407 | snd_soc_update_bits(codec, DA9055_MIXOUT_R_CTRL, | 1432 | snd_soc_update_bits(codec, DA9055_MIXOUT_R_CTRL, |
1408 | DA9055_MIXOUT_R_MIX_EN, DA9055_MIXOUT_R_MIX_EN); | 1433 | DA9055_MIXOUT_R_MIX_EN, DA9055_MIXOUT_R_MIX_EN); |
1409 | 1434 | ||
1410 | snd_soc_update_bits(codec, DA9055_HP_L_CTRL, | ||
1411 | DA9055_HP_L_AMP_OE, DA9055_HP_L_AMP_OE); | ||
1412 | snd_soc_update_bits(codec, DA9055_HP_R_CTRL, | ||
1413 | DA9055_HP_R_AMP_OE, DA9055_HP_R_AMP_OE); | ||
1414 | |||
1415 | snd_soc_update_bits(codec, DA9055_LINE_CTRL, | ||
1416 | DA9055_LINE_AMP_OE, DA9055_LINE_AMP_OE); | ||
1417 | |||
1418 | /* Set this as per your system configuration */ | 1435 | /* Set this as per your system configuration */ |
1419 | snd_soc_write(codec, DA9055_PLL_CTRL, DA9055_PLL_INDIV_10_20_MHZ); | 1436 | snd_soc_write(codec, DA9055_PLL_CTRL, DA9055_PLL_INDIV_10_20_MHZ); |
1420 | 1437 | ||
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c index 85d9cabe6d55..9ad1da36887e 100644 --- a/sound/soc/codecs/jz4740.c +++ b/sound/soc/codecs/jz4740.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
19 | #include <linux/regmap.h> | ||
19 | 20 | ||
20 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
21 | 22 | ||
@@ -24,9 +25,10 @@ | |||
24 | #include <sound/pcm_params.h> | 25 | #include <sound/pcm_params.h> |
25 | #include <sound/initval.h> | 26 | #include <sound/initval.h> |
26 | #include <sound/soc.h> | 27 | #include <sound/soc.h> |
28 | #include <sound/tlv.h> | ||
27 | 29 | ||
28 | #define JZ4740_REG_CODEC_1 0x0 | 30 | #define JZ4740_REG_CODEC_1 0x0 |
29 | #define JZ4740_REG_CODEC_2 0x1 | 31 | #define JZ4740_REG_CODEC_2 0x4 |
30 | 32 | ||
31 | #define JZ4740_CODEC_1_LINE_ENABLE BIT(29) | 33 | #define JZ4740_CODEC_1_LINE_ENABLE BIT(29) |
32 | #define JZ4740_CODEC_1_MIC_ENABLE BIT(28) | 34 | #define JZ4740_CODEC_1_MIC_ENABLE BIT(28) |
@@ -67,43 +69,36 @@ | |||
67 | #define JZ4740_CODEC_2_MIC_BOOST_GAIN_OFFSET 4 | 69 | #define JZ4740_CODEC_2_MIC_BOOST_GAIN_OFFSET 4 |
68 | #define JZ4740_CODEC_2_HEADPHONE_VOLUME_OFFSET 0 | 70 | #define JZ4740_CODEC_2_HEADPHONE_VOLUME_OFFSET 0 |
69 | 71 | ||
70 | static const uint32_t jz4740_codec_regs[] = { | 72 | static const struct reg_default jz4740_codec_reg_defaults[] = { |
71 | 0x021b2302, 0x00170803, | 73 | { JZ4740_REG_CODEC_1, 0x021b2302 }, |
74 | { JZ4740_REG_CODEC_2, 0x00170803 }, | ||
72 | }; | 75 | }; |
73 | 76 | ||
74 | struct jz4740_codec { | 77 | struct jz4740_codec { |
75 | void __iomem *base; | 78 | struct regmap *regmap; |
76 | struct resource *mem; | ||
77 | }; | 79 | }; |
78 | 80 | ||
79 | static unsigned int jz4740_codec_read(struct snd_soc_codec *codec, | 81 | static const unsigned int jz4740_mic_tlv[] = { |
80 | unsigned int reg) | 82 | TLV_DB_RANGE_HEAD(2), |
81 | { | 83 | 0, 2, TLV_DB_SCALE_ITEM(0, 600, 0), |
82 | struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec); | 84 | 3, 3, TLV_DB_SCALE_ITEM(2000, 0, 0), |
83 | return readl(jz4740_codec->base + (reg << 2)); | 85 | }; |
84 | } | ||
85 | |||
86 | static int jz4740_codec_write(struct snd_soc_codec *codec, unsigned int reg, | ||
87 | unsigned int val) | ||
88 | { | ||
89 | struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec); | ||
90 | u32 *cache = codec->reg_cache; | ||
91 | |||
92 | cache[reg] = val; | ||
93 | writel(val, jz4740_codec->base + (reg << 2)); | ||
94 | 86 | ||
95 | return 0; | 87 | static const DECLARE_TLV_DB_SCALE(jz4740_out_tlv, 0, 200, 0); |
96 | } | 88 | static const DECLARE_TLV_DB_SCALE(jz4740_in_tlv, -3450, 150, 0); |
97 | 89 | ||
98 | static const struct snd_kcontrol_new jz4740_codec_controls[] = { | 90 | static const struct snd_kcontrol_new jz4740_codec_controls[] = { |
99 | SOC_SINGLE("Master Playback Volume", JZ4740_REG_CODEC_2, | 91 | SOC_SINGLE_TLV("Master Playback Volume", JZ4740_REG_CODEC_2, |
100 | JZ4740_CODEC_2_HEADPHONE_VOLUME_OFFSET, 3, 0), | 92 | JZ4740_CODEC_2_HEADPHONE_VOLUME_OFFSET, 3, 0, |
101 | SOC_SINGLE("Master Capture Volume", JZ4740_REG_CODEC_2, | 93 | jz4740_out_tlv), |
102 | JZ4740_CODEC_2_INPUT_VOLUME_OFFSET, 31, 0), | 94 | SOC_SINGLE_TLV("Master Capture Volume", JZ4740_REG_CODEC_2, |
95 | JZ4740_CODEC_2_INPUT_VOLUME_OFFSET, 31, 0, | ||
96 | jz4740_in_tlv), | ||
103 | SOC_SINGLE("Master Playback Switch", JZ4740_REG_CODEC_1, | 97 | SOC_SINGLE("Master Playback Switch", JZ4740_REG_CODEC_1, |
104 | JZ4740_CODEC_1_HEADPHONE_DISABLE_OFFSET, 1, 1), | 98 | JZ4740_CODEC_1_HEADPHONE_DISABLE_OFFSET, 1, 1), |
105 | SOC_SINGLE("Mic Capture Volume", JZ4740_REG_CODEC_2, | 99 | SOC_SINGLE_TLV("Mic Capture Volume", JZ4740_REG_CODEC_2, |
106 | JZ4740_CODEC_2_MIC_BOOST_GAIN_OFFSET, 3, 0), | 100 | JZ4740_CODEC_2_MIC_BOOST_GAIN_OFFSET, 3, 0, |
101 | jz4740_mic_tlv), | ||
107 | }; | 102 | }; |
108 | 103 | ||
109 | static const struct snd_kcontrol_new jz4740_codec_output_controls[] = { | 104 | static const struct snd_kcontrol_new jz4740_codec_output_controls[] = { |
@@ -163,8 +158,8 @@ static const struct snd_soc_dapm_route jz4740_codec_dapm_routes[] = { | |||
163 | static int jz4740_codec_hw_params(struct snd_pcm_substream *substream, | 158 | static int jz4740_codec_hw_params(struct snd_pcm_substream *substream, |
164 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | 159 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) |
165 | { | 160 | { |
161 | struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(dai->codec); | ||
166 | uint32_t val; | 162 | uint32_t val; |
167 | struct snd_soc_codec *codec = dai->codec; | ||
168 | 163 | ||
169 | switch (params_rate(params)) { | 164 | switch (params_rate(params)) { |
170 | case 8000: | 165 | case 8000: |
@@ -200,7 +195,7 @@ static int jz4740_codec_hw_params(struct snd_pcm_substream *substream, | |||
200 | 195 | ||
201 | val <<= JZ4740_CODEC_2_SAMPLE_RATE_OFFSET; | 196 | val <<= JZ4740_CODEC_2_SAMPLE_RATE_OFFSET; |
202 | 197 | ||
203 | snd_soc_update_bits(codec, JZ4740_REG_CODEC_2, | 198 | regmap_update_bits(jz4740_codec->regmap, JZ4740_REG_CODEC_2, |
204 | JZ4740_CODEC_2_SAMPLE_RATE_MASK, val); | 199 | JZ4740_CODEC_2_SAMPLE_RATE_MASK, val); |
205 | 200 | ||
206 | return 0; | 201 | return 0; |
@@ -230,25 +225,23 @@ static struct snd_soc_dai_driver jz4740_codec_dai = { | |||
230 | .symmetric_rates = 1, | 225 | .symmetric_rates = 1, |
231 | }; | 226 | }; |
232 | 227 | ||
233 | static void jz4740_codec_wakeup(struct snd_soc_codec *codec) | 228 | static void jz4740_codec_wakeup(struct regmap *regmap) |
234 | { | 229 | { |
235 | int i; | 230 | regmap_update_bits(regmap, JZ4740_REG_CODEC_1, |
236 | uint32_t *cache = codec->reg_cache; | ||
237 | |||
238 | snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, | ||
239 | JZ4740_CODEC_1_RESET, JZ4740_CODEC_1_RESET); | 231 | JZ4740_CODEC_1_RESET, JZ4740_CODEC_1_RESET); |
240 | udelay(2); | 232 | udelay(2); |
241 | 233 | ||
242 | snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, | 234 | regmap_update_bits(regmap, JZ4740_REG_CODEC_1, |
243 | JZ4740_CODEC_1_SUSPEND | JZ4740_CODEC_1_RESET, 0); | 235 | JZ4740_CODEC_1_SUSPEND | JZ4740_CODEC_1_RESET, 0); |
244 | 236 | ||
245 | for (i = 0; i < ARRAY_SIZE(jz4740_codec_regs); ++i) | 237 | regcache_sync(regmap); |
246 | jz4740_codec_write(codec, i, cache[i]); | ||
247 | } | 238 | } |
248 | 239 | ||
249 | static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec, | 240 | static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec, |
250 | enum snd_soc_bias_level level) | 241 | enum snd_soc_bias_level level) |
251 | { | 242 | { |
243 | struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec); | ||
244 | struct regmap *regmap = jz4740_codec->regmap; | ||
252 | unsigned int mask; | 245 | unsigned int mask; |
253 | unsigned int value; | 246 | unsigned int value; |
254 | 247 | ||
@@ -261,12 +254,12 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec, | |||
261 | JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M; | 254 | JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M; |
262 | value = 0; | 255 | value = 0; |
263 | 256 | ||
264 | snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, mask, value); | 257 | regmap_update_bits(regmap, JZ4740_REG_CODEC_1, mask, value); |
265 | break; | 258 | break; |
266 | case SND_SOC_BIAS_STANDBY: | 259 | case SND_SOC_BIAS_STANDBY: |
267 | /* The only way to clear the suspend flag is to reset the codec */ | 260 | /* The only way to clear the suspend flag is to reset the codec */ |
268 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) | 261 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) |
269 | jz4740_codec_wakeup(codec); | 262 | jz4740_codec_wakeup(regmap); |
270 | 263 | ||
271 | mask = JZ4740_CODEC_1_VREF_DISABLE | | 264 | mask = JZ4740_CODEC_1_VREF_DISABLE | |
272 | JZ4740_CODEC_1_VREF_AMP_DISABLE | | 265 | JZ4740_CODEC_1_VREF_AMP_DISABLE | |
@@ -275,13 +268,14 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec, | |||
275 | JZ4740_CODEC_1_VREF_AMP_DISABLE | | 268 | JZ4740_CODEC_1_VREF_AMP_DISABLE | |
276 | JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M; | 269 | JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M; |
277 | 270 | ||
278 | snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, mask, value); | 271 | regmap_update_bits(regmap, JZ4740_REG_CODEC_1, mask, value); |
279 | break; | 272 | break; |
280 | case SND_SOC_BIAS_OFF: | 273 | case SND_SOC_BIAS_OFF: |
281 | mask = JZ4740_CODEC_1_SUSPEND; | 274 | mask = JZ4740_CODEC_1_SUSPEND; |
282 | value = JZ4740_CODEC_1_SUSPEND; | 275 | value = JZ4740_CODEC_1_SUSPEND; |
283 | 276 | ||
284 | snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, mask, value); | 277 | regmap_update_bits(regmap, JZ4740_REG_CODEC_1, mask, value); |
278 | regcache_mark_dirty(regmap); | ||
285 | break; | 279 | break; |
286 | default: | 280 | default: |
287 | break; | 281 | break; |
@@ -294,7 +288,9 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec, | |||
294 | 288 | ||
295 | static int jz4740_codec_dev_probe(struct snd_soc_codec *codec) | 289 | static int jz4740_codec_dev_probe(struct snd_soc_codec *codec) |
296 | { | 290 | { |
297 | snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, | 291 | struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec); |
292 | |||
293 | regmap_update_bits(jz4740_codec->regmap, JZ4740_REG_CODEC_1, | ||
298 | JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE); | 294 | JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE); |
299 | 295 | ||
300 | jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 296 | jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
@@ -331,12 +327,7 @@ static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = { | |||
331 | .remove = jz4740_codec_dev_remove, | 327 | .remove = jz4740_codec_dev_remove, |
332 | .suspend = jz4740_codec_suspend, | 328 | .suspend = jz4740_codec_suspend, |
333 | .resume = jz4740_codec_resume, | 329 | .resume = jz4740_codec_resume, |
334 | .read = jz4740_codec_read, | ||
335 | .write = jz4740_codec_write, | ||
336 | .set_bias_level = jz4740_codec_set_bias_level, | 330 | .set_bias_level = jz4740_codec_set_bias_level, |
337 | .reg_cache_default = jz4740_codec_regs, | ||
338 | .reg_word_size = sizeof(u32), | ||
339 | .reg_cache_size = 2, | ||
340 | 331 | ||
341 | .controls = jz4740_codec_controls, | 332 | .controls = jz4740_codec_controls, |
342 | .num_controls = ARRAY_SIZE(jz4740_codec_controls), | 333 | .num_controls = ARRAY_SIZE(jz4740_codec_controls), |
@@ -346,11 +337,23 @@ static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = { | |||
346 | .num_dapm_routes = ARRAY_SIZE(jz4740_codec_dapm_routes), | 337 | .num_dapm_routes = ARRAY_SIZE(jz4740_codec_dapm_routes), |
347 | }; | 338 | }; |
348 | 339 | ||
340 | static const struct regmap_config jz4740_codec_regmap_config = { | ||
341 | .reg_bits = 32, | ||
342 | .reg_stride = 4, | ||
343 | .val_bits = 32, | ||
344 | .max_register = JZ4740_REG_CODEC_2, | ||
345 | |||
346 | .reg_defaults = jz4740_codec_reg_defaults, | ||
347 | .num_reg_defaults = ARRAY_SIZE(jz4740_codec_reg_defaults), | ||
348 | .cache_type = REGCACHE_RBTREE, | ||
349 | }; | ||
350 | |||
349 | static int __devinit jz4740_codec_probe(struct platform_device *pdev) | 351 | static int __devinit jz4740_codec_probe(struct platform_device *pdev) |
350 | { | 352 | { |
351 | int ret; | 353 | int ret; |
352 | struct jz4740_codec *jz4740_codec; | 354 | struct jz4740_codec *jz4740_codec; |
353 | struct resource *mem; | 355 | struct resource *mem; |
356 | void __iomem *base; | ||
354 | 357 | ||
355 | jz4740_codec = devm_kzalloc(&pdev->dev, sizeof(*jz4740_codec), | 358 | jz4740_codec = devm_kzalloc(&pdev->dev, sizeof(*jz4740_codec), |
356 | GFP_KERNEL); | 359 | GFP_KERNEL); |
@@ -358,56 +361,29 @@ static int __devinit jz4740_codec_probe(struct platform_device *pdev) | |||
358 | return -ENOMEM; | 361 | return -ENOMEM; |
359 | 362 | ||
360 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 363 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
361 | if (!mem) { | 364 | base = devm_request_and_ioremap(&pdev->dev, mem); |
362 | dev_err(&pdev->dev, "Failed to get mmio memory resource\n"); | 365 | if (!base) |
363 | ret = -ENOENT; | 366 | return -EBUSY; |
364 | goto err_out; | ||
365 | } | ||
366 | |||
367 | mem = request_mem_region(mem->start, resource_size(mem), pdev->name); | ||
368 | if (!mem) { | ||
369 | dev_err(&pdev->dev, "Failed to request mmio memory region\n"); | ||
370 | ret = -EBUSY; | ||
371 | goto err_out; | ||
372 | } | ||
373 | 367 | ||
374 | jz4740_codec->base = ioremap(mem->start, resource_size(mem)); | 368 | jz4740_codec->regmap = devm_regmap_init_mmio(&pdev->dev, base, |
375 | if (!jz4740_codec->base) { | 369 | &jz4740_codec_regmap_config); |
376 | dev_err(&pdev->dev, "Failed to ioremap mmio memory\n"); | 370 | if (IS_ERR(jz4740_codec->regmap)) |
377 | ret = -EBUSY; | 371 | return PTR_ERR(jz4740_codec->regmap); |
378 | goto err_release_mem_region; | ||
379 | } | ||
380 | jz4740_codec->mem = mem; | ||
381 | 372 | ||
382 | platform_set_drvdata(pdev, jz4740_codec); | 373 | platform_set_drvdata(pdev, jz4740_codec); |
383 | 374 | ||
384 | ret = snd_soc_register_codec(&pdev->dev, | 375 | ret = snd_soc_register_codec(&pdev->dev, |
385 | &soc_codec_dev_jz4740_codec, &jz4740_codec_dai, 1); | 376 | &soc_codec_dev_jz4740_codec, &jz4740_codec_dai, 1); |
386 | if (ret) { | 377 | if (ret) |
387 | dev_err(&pdev->dev, "Failed to register codec\n"); | 378 | dev_err(&pdev->dev, "Failed to register codec\n"); |
388 | goto err_iounmap; | ||
389 | } | ||
390 | 379 | ||
391 | return 0; | ||
392 | |||
393 | err_iounmap: | ||
394 | iounmap(jz4740_codec->base); | ||
395 | err_release_mem_region: | ||
396 | release_mem_region(mem->start, resource_size(mem)); | ||
397 | err_out: | ||
398 | return ret; | 380 | return ret; |
399 | } | 381 | } |
400 | 382 | ||
401 | static int __devexit jz4740_codec_remove(struct platform_device *pdev) | 383 | static int __devexit jz4740_codec_remove(struct platform_device *pdev) |
402 | { | 384 | { |
403 | struct jz4740_codec *jz4740_codec = platform_get_drvdata(pdev); | ||
404 | struct resource *mem = jz4740_codec->mem; | ||
405 | |||
406 | snd_soc_unregister_codec(&pdev->dev); | 385 | snd_soc_unregister_codec(&pdev->dev); |
407 | 386 | ||
408 | iounmap(jz4740_codec->base); | ||
409 | release_mem_region(mem->start, resource_size(mem)); | ||
410 | |||
411 | platform_set_drvdata(pdev, NULL); | 387 | platform_set_drvdata(pdev, NULL); |
412 | 388 | ||
413 | return 0; | 389 | return 0; |
diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c index 99b0a9dcff34..096b6aa87f0f 100644 --- a/sound/soc/codecs/lm49453.c +++ b/sound/soc/codecs/lm49453.c | |||
@@ -1497,7 +1497,7 @@ static __devinit int lm49453_i2c_probe(struct i2c_client *i2c, | |||
1497 | 1497 | ||
1498 | i2c_set_clientdata(i2c, lm49453); | 1498 | i2c_set_clientdata(i2c, lm49453); |
1499 | 1499 | ||
1500 | lm49453->regmap = regmap_init_i2c(i2c, &lm49453_regmap_config); | 1500 | lm49453->regmap = devm_regmap_init_i2c(i2c, &lm49453_regmap_config); |
1501 | if (IS_ERR(lm49453->regmap)) { | 1501 | if (IS_ERR(lm49453->regmap)) { |
1502 | ret = PTR_ERR(lm49453->regmap); | 1502 | ret = PTR_ERR(lm49453->regmap); |
1503 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | 1503 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", |
@@ -1508,21 +1508,15 @@ static __devinit int lm49453_i2c_probe(struct i2c_client *i2c, | |||
1508 | ret = snd_soc_register_codec(&i2c->dev, | 1508 | ret = snd_soc_register_codec(&i2c->dev, |
1509 | &soc_codec_dev_lm49453, | 1509 | &soc_codec_dev_lm49453, |
1510 | lm49453_dai, ARRAY_SIZE(lm49453_dai)); | 1510 | lm49453_dai, ARRAY_SIZE(lm49453_dai)); |
1511 | if (ret < 0) { | 1511 | if (ret < 0) |
1512 | dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); | 1512 | dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); |
1513 | regmap_exit(lm49453->regmap); | ||
1514 | return ret; | ||
1515 | } | ||
1516 | 1513 | ||
1517 | return ret; | 1514 | return ret; |
1518 | } | 1515 | } |
1519 | 1516 | ||
1520 | static int __devexit lm49453_i2c_remove(struct i2c_client *client) | 1517 | static int __devexit lm49453_i2c_remove(struct i2c_client *client) |
1521 | { | 1518 | { |
1522 | struct lm49453_priv *lm49453 = i2c_get_clientdata(client); | ||
1523 | |||
1524 | snd_soc_unregister_codec(&client->dev); | 1519 | snd_soc_unregister_codec(&client->dev); |
1525 | regmap_exit(lm49453->regmap); | ||
1526 | return 0; | 1520 | return 0; |
1527 | } | 1521 | } |
1528 | 1522 | ||
diff --git a/sound/soc/codecs/max9768.c b/sound/soc/codecs/max9768.c index 17b3ec2d05cb..a777de6a1b23 100644 --- a/sound/soc/codecs/max9768.c +++ b/sound/soc/codecs/max9768.c | |||
@@ -187,7 +187,7 @@ static int __devinit max9768_i2c_probe(struct i2c_client *client, | |||
187 | 187 | ||
188 | i2c_set_clientdata(client, max9768); | 188 | i2c_set_clientdata(client, max9768); |
189 | 189 | ||
190 | max9768->regmap = regmap_init_i2c(client, &max9768_i2c_regmap_config); | 190 | max9768->regmap = devm_regmap_init_i2c(client, &max9768_i2c_regmap_config); |
191 | if (IS_ERR(max9768->regmap)) { | 191 | if (IS_ERR(max9768->regmap)) { |
192 | err = PTR_ERR(max9768->regmap); | 192 | err = PTR_ERR(max9768->regmap); |
193 | goto err_gpio_free; | 193 | goto err_gpio_free; |
@@ -195,12 +195,10 @@ static int __devinit max9768_i2c_probe(struct i2c_client *client, | |||
195 | 195 | ||
196 | err = snd_soc_register_codec(&client->dev, &max9768_codec_driver, NULL, 0); | 196 | err = snd_soc_register_codec(&client->dev, &max9768_codec_driver, NULL, 0); |
197 | if (err) | 197 | if (err) |
198 | goto err_regmap_free; | 198 | goto err_gpio_free; |
199 | 199 | ||
200 | return 0; | 200 | return 0; |
201 | 201 | ||
202 | err_regmap_free: | ||
203 | regmap_exit(max9768->regmap); | ||
204 | err_gpio_free: | 202 | err_gpio_free: |
205 | if (gpio_is_valid(max9768->shdn_gpio)) | 203 | if (gpio_is_valid(max9768->shdn_gpio)) |
206 | gpio_free(max9768->shdn_gpio); | 204 | gpio_free(max9768->shdn_gpio); |
@@ -215,7 +213,6 @@ static int __devexit max9768_i2c_remove(struct i2c_client *client) | |||
215 | struct max9768 *max9768 = i2c_get_clientdata(client); | 213 | struct max9768 *max9768 = i2c_get_clientdata(client); |
216 | 214 | ||
217 | snd_soc_unregister_codec(&client->dev); | 215 | snd_soc_unregister_codec(&client->dev); |
218 | regmap_exit(max9768->regmap); | ||
219 | 216 | ||
220 | if (gpio_is_valid(max9768->shdn_gpio)) | 217 | if (gpio_is_valid(max9768->shdn_gpio)) |
221 | gpio_free(max9768->shdn_gpio); | 218 | gpio_free(max9768->shdn_gpio); |
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index 3264a5169306..b858264235c4 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c | |||
@@ -2098,13 +2098,13 @@ static const struct i2c_device_id max98088_i2c_id[] = { | |||
2098 | MODULE_DEVICE_TABLE(i2c, max98088_i2c_id); | 2098 | MODULE_DEVICE_TABLE(i2c, max98088_i2c_id); |
2099 | 2099 | ||
2100 | static struct i2c_driver max98088_i2c_driver = { | 2100 | static struct i2c_driver max98088_i2c_driver = { |
2101 | .driver = { | 2101 | .driver = { |
2102 | .name = "max98088", | 2102 | .name = "max98088", |
2103 | .owner = THIS_MODULE, | 2103 | .owner = THIS_MODULE, |
2104 | }, | 2104 | }, |
2105 | .probe = max98088_i2c_probe, | 2105 | .probe = max98088_i2c_probe, |
2106 | .remove = __devexit_p(max98088_i2c_remove), | 2106 | .remove = max98088_i2c_remove, |
2107 | .id_table = max98088_i2c_id, | 2107 | .id_table = max98088_i2c_id, |
2108 | }; | 2108 | }; |
2109 | 2109 | ||
2110 | module_i2c_driver(max98088_i2c_driver); | 2110 | module_i2c_driver(max98088_i2c_driver); |
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c new file mode 100644 index 000000000000..c9772ca3da4f --- /dev/null +++ b/sound/soc/codecs/max98090.c | |||
@@ -0,0 +1,577 @@ | |||
1 | /* | ||
2 | * max98090.c -- MAX98090 ALSA SoC Audio driver | ||
3 | * based on Rev0p8 datasheet | ||
4 | * | ||
5 | * Copyright (C) 2012 Renesas Solutions Corp. | ||
6 | * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | ||
7 | * | ||
8 | * Based on | ||
9 | * | ||
10 | * max98095.c | ||
11 | * Copyright 2011 Maxim Integrated Products | ||
12 | * | ||
13 | * https://github.com/hardkernel/linux/commit/\ | ||
14 | * 3417d7166b17113b3b33b0a337c74d1c7cc313df#sound/soc/codecs/max98090.c | ||
15 | * Copyright 2011 Maxim Integrated Products | ||
16 | * | ||
17 | * This program is free software; you can redistribute it and/or modify | ||
18 | * it under the terms of the GNU General Public License version 2 as | ||
19 | * published by the Free Software Foundation. | ||
20 | */ | ||
21 | |||
22 | #include <linux/i2c.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/regmap.h> | ||
25 | #include <sound/soc.h> | ||
26 | #include <sound/tlv.h> | ||
27 | |||
28 | /* | ||
29 | * | ||
30 | * MAX98090 Registers Definition | ||
31 | * | ||
32 | */ | ||
33 | |||
34 | /* RESET / STATUS / INTERRUPT REGISTERS */ | ||
35 | #define MAX98090_0x00_SW_RESET 0x00 | ||
36 | #define MAX98090_0x01_INT_STS 0x01 | ||
37 | #define MAX98090_0x02_JACK_STS 0x02 | ||
38 | #define MAX98090_0x03_INT_MASK 0x03 | ||
39 | |||
40 | /* QUICK SETUP REGISTERS */ | ||
41 | #define MAX98090_0x04_SYS_CLK 0x04 | ||
42 | #define MAX98090_0x05_SAMPLE_RATE 0x05 | ||
43 | #define MAX98090_0x06_DAI_IF 0x06 | ||
44 | #define MAX98090_0x07_DAC_PATH 0x07 | ||
45 | #define MAX98090_0x08_MIC_TO_ADC 0x08 | ||
46 | #define MAX98090_0x09_LINE_TO_ADC 0x09 | ||
47 | #define MAX98090_0x0A_ANALOG_MIC_LOOP 0x0A | ||
48 | #define MAX98090_0x0B_ANALOG_LINE_LOOP 0x0B | ||
49 | |||
50 | /* ANALOG INPUT CONFIGURATION REGISTERS */ | ||
51 | #define MAX98090_0x0D_INPUT_CONFIG 0x0D | ||
52 | #define MAX98090_0x0E_LINE_IN_LVL 0x0E | ||
53 | #define MAX98090_0x0F_LINI_IN_CFG 0x0F | ||
54 | #define MAX98090_0x10_MIC1_IN_LVL 0x10 | ||
55 | #define MAX98090_0x11_MIC2_IN_LVL 0x11 | ||
56 | |||
57 | /* MICROPHONE CONFIGURATION REGISTERS */ | ||
58 | #define MAX98090_0x12_MIC_BIAS_VOL 0x12 | ||
59 | #define MAX98090_0x13_DIGITAL_MIC_CFG 0x13 | ||
60 | #define MAX98090_0x14_DIGITAL_MIC_MODE 0x14 | ||
61 | |||
62 | /* ADC PATH AND CONFIGURATION REGISTERS */ | ||
63 | #define MAX98090_0x15_L_ADC_MIX 0x15 | ||
64 | #define MAX98090_0x16_R_ADC_MIX 0x16 | ||
65 | #define MAX98090_0x17_L_ADC_LVL 0x17 | ||
66 | #define MAX98090_0x18_R_ADC_LVL 0x18 | ||
67 | #define MAX98090_0x19_ADC_BIQUAD_LVL 0x19 | ||
68 | #define MAX98090_0x1A_ADC_SIDETONE 0x1A | ||
69 | |||
70 | /* CLOCK CONFIGURATION REGISTERS */ | ||
71 | #define MAX98090_0x1B_SYS_CLK 0x1B | ||
72 | #define MAX98090_0x1C_CLK_MODE 0x1C | ||
73 | #define MAX98090_0x1D_ANY_CLK1 0x1D | ||
74 | #define MAX98090_0x1E_ANY_CLK2 0x1E | ||
75 | #define MAX98090_0x1F_ANY_CLK3 0x1F | ||
76 | #define MAX98090_0x20_ANY_CLK4 0x20 | ||
77 | #define MAX98090_0x21_MASTER_MODE 0x21 | ||
78 | |||
79 | /* INTERFACE CONTROL REGISTERS */ | ||
80 | #define MAX98090_0x22_DAI_IF_FMT 0x22 | ||
81 | #define MAX98090_0x23_DAI_TDM_FMT1 0x23 | ||
82 | #define MAX98090_0x24_DAI_TDM_FMT2 0x24 | ||
83 | #define MAX98090_0x25_DAI_IO_CFG 0x25 | ||
84 | #define MAX98090_0x26_FILTER_CFG 0x26 | ||
85 | #define MAX98090_0x27_DAI_PLAYBACK_LVL 0x27 | ||
86 | #define MAX98090_0x28_EQ_PLAYBACK_LVL 0x28 | ||
87 | |||
88 | /* HEADPHONE CONTROL REGISTERS */ | ||
89 | #define MAX98090_0x29_L_HP_MIX 0x29 | ||
90 | #define MAX98090_0x2A_R_HP_MIX 0x2A | ||
91 | #define MAX98090_0x2B_HP_CTR 0x2B | ||
92 | #define MAX98090_0x2C_L_HP_VOL 0x2C | ||
93 | #define MAX98090_0x2D_R_HP_VOL 0x2D | ||
94 | |||
95 | /* SPEAKER CONFIGURATION REGISTERS */ | ||
96 | #define MAX98090_0x2E_L_SPK_MIX 0x2E | ||
97 | #define MAX98090_0x2F_R_SPK_MIX 0x2F | ||
98 | #define MAX98090_0x30_SPK_CTR 0x30 | ||
99 | #define MAX98090_0x31_L_SPK_VOL 0x31 | ||
100 | #define MAX98090_0x32_R_SPK_VOL 0x32 | ||
101 | |||
102 | /* ALC CONFIGURATION REGISTERS */ | ||
103 | #define MAX98090_0x33_ALC_TIMING 0x33 | ||
104 | #define MAX98090_0x34_ALC_COMPRESSOR 0x34 | ||
105 | #define MAX98090_0x35_ALC_EXPANDER 0x35 | ||
106 | #define MAX98090_0x36_ALC_GAIN 0x36 | ||
107 | |||
108 | /* RECEIVER AND LINE_OUTPUT REGISTERS */ | ||
109 | #define MAX98090_0x37_RCV_LOUT_L_MIX 0x37 | ||
110 | #define MAX98090_0x38_RCV_LOUT_L_CNTL 0x38 | ||
111 | #define MAX98090_0x39_RCV_LOUT_L_VOL 0x39 | ||
112 | #define MAX98090_0x3A_LOUT_R_MIX 0x3A | ||
113 | #define MAX98090_0x3B_LOUT_R_CNTL 0x3B | ||
114 | #define MAX98090_0x3C_LOUT_R_VOL 0x3C | ||
115 | |||
116 | /* JACK DETECT AND ENABLE REGISTERS */ | ||
117 | #define MAX98090_0x3D_JACK_DETECT 0x3D | ||
118 | #define MAX98090_0x3E_IN_ENABLE 0x3E | ||
119 | #define MAX98090_0x3F_OUT_ENABLE 0x3F | ||
120 | #define MAX98090_0x40_LVL_CTR 0x40 | ||
121 | #define MAX98090_0x41_DSP_FILTER_ENABLE 0x41 | ||
122 | |||
123 | /* BIAS AND POWER MODE CONFIGURATION REGISTERS */ | ||
124 | #define MAX98090_0x42_BIAS_CTR 0x42 | ||
125 | #define MAX98090_0x43_DAC_CTR 0x43 | ||
126 | #define MAX98090_0x44_ADC_CTR 0x44 | ||
127 | #define MAX98090_0x45_DEV_SHUTDOWN 0x45 | ||
128 | |||
129 | /* REVISION ID REGISTER */ | ||
130 | #define MAX98090_0xFF_REV_ID 0xFF | ||
131 | |||
132 | #define MAX98090_REG_MAX_CACHED 0x45 | ||
133 | #define MAX98090_REG_END 0xFF | ||
134 | |||
135 | /* | ||
136 | * | ||
137 | * MAX98090 Registers Bit Fields | ||
138 | * | ||
139 | */ | ||
140 | |||
141 | /* MAX98090_0x06_DAI_IF */ | ||
142 | #define MAX98090_DAI_IF_MASK 0x3F | ||
143 | #define MAX98090_RJ_M (1 << 5) | ||
144 | #define MAX98090_RJ_S (1 << 4) | ||
145 | #define MAX98090_LJ_M (1 << 3) | ||
146 | #define MAX98090_LJ_S (1 << 2) | ||
147 | #define MAX98090_I2S_M (1 << 1) | ||
148 | #define MAX98090_I2S_S (1 << 0) | ||
149 | |||
150 | /* MAX98090_0x45_DEV_SHUTDOWN */ | ||
151 | #define MAX98090_SHDNRUN (1 << 7) | ||
152 | |||
153 | /* codec private data */ | ||
154 | struct max98090_priv { | ||
155 | struct regmap *regmap; | ||
156 | }; | ||
157 | |||
158 | static const struct reg_default max98090_reg_defaults[] = { | ||
159 | /* RESET / STATUS / INTERRUPT REGISTERS */ | ||
160 | {MAX98090_0x00_SW_RESET, 0x00}, | ||
161 | {MAX98090_0x01_INT_STS, 0x00}, | ||
162 | {MAX98090_0x02_JACK_STS, 0x00}, | ||
163 | {MAX98090_0x03_INT_MASK, 0x04}, | ||
164 | |||
165 | /* QUICK SETUP REGISTERS */ | ||
166 | {MAX98090_0x04_SYS_CLK, 0x00}, | ||
167 | {MAX98090_0x05_SAMPLE_RATE, 0x00}, | ||
168 | {MAX98090_0x06_DAI_IF, 0x00}, | ||
169 | {MAX98090_0x07_DAC_PATH, 0x00}, | ||
170 | {MAX98090_0x08_MIC_TO_ADC, 0x00}, | ||
171 | {MAX98090_0x09_LINE_TO_ADC, 0x00}, | ||
172 | {MAX98090_0x0A_ANALOG_MIC_LOOP, 0x00}, | ||
173 | {MAX98090_0x0B_ANALOG_LINE_LOOP, 0x00}, | ||
174 | |||
175 | /* ANALOG INPUT CONFIGURATION REGISTERS */ | ||
176 | {MAX98090_0x0D_INPUT_CONFIG, 0x00}, | ||
177 | {MAX98090_0x0E_LINE_IN_LVL, 0x1B}, | ||
178 | {MAX98090_0x0F_LINI_IN_CFG, 0x00}, | ||
179 | {MAX98090_0x10_MIC1_IN_LVL, 0x11}, | ||
180 | {MAX98090_0x11_MIC2_IN_LVL, 0x11}, | ||
181 | |||
182 | /* MICROPHONE CONFIGURATION REGISTERS */ | ||
183 | {MAX98090_0x12_MIC_BIAS_VOL, 0x00}, | ||
184 | {MAX98090_0x13_DIGITAL_MIC_CFG, 0x00}, | ||
185 | {MAX98090_0x14_DIGITAL_MIC_MODE, 0x00}, | ||
186 | |||
187 | /* ADC PATH AND CONFIGURATION REGISTERS */ | ||
188 | {MAX98090_0x15_L_ADC_MIX, 0x00}, | ||
189 | {MAX98090_0x16_R_ADC_MIX, 0x00}, | ||
190 | {MAX98090_0x17_L_ADC_LVL, 0x03}, | ||
191 | {MAX98090_0x18_R_ADC_LVL, 0x03}, | ||
192 | {MAX98090_0x19_ADC_BIQUAD_LVL, 0x00}, | ||
193 | {MAX98090_0x1A_ADC_SIDETONE, 0x00}, | ||
194 | |||
195 | /* CLOCK CONFIGURATION REGISTERS */ | ||
196 | {MAX98090_0x1B_SYS_CLK, 0x00}, | ||
197 | {MAX98090_0x1C_CLK_MODE, 0x00}, | ||
198 | {MAX98090_0x1D_ANY_CLK1, 0x00}, | ||
199 | {MAX98090_0x1E_ANY_CLK2, 0x00}, | ||
200 | {MAX98090_0x1F_ANY_CLK3, 0x00}, | ||
201 | {MAX98090_0x20_ANY_CLK4, 0x00}, | ||
202 | {MAX98090_0x21_MASTER_MODE, 0x00}, | ||
203 | |||
204 | /* INTERFACE CONTROL REGISTERS */ | ||
205 | {MAX98090_0x22_DAI_IF_FMT, 0x00}, | ||
206 | {MAX98090_0x23_DAI_TDM_FMT1, 0x00}, | ||
207 | {MAX98090_0x24_DAI_TDM_FMT2, 0x00}, | ||
208 | {MAX98090_0x25_DAI_IO_CFG, 0x00}, | ||
209 | {MAX98090_0x26_FILTER_CFG, 0x80}, | ||
210 | {MAX98090_0x27_DAI_PLAYBACK_LVL, 0x00}, | ||
211 | {MAX98090_0x28_EQ_PLAYBACK_LVL, 0x00}, | ||
212 | |||
213 | /* HEADPHONE CONTROL REGISTERS */ | ||
214 | {MAX98090_0x29_L_HP_MIX, 0x00}, | ||
215 | {MAX98090_0x2A_R_HP_MIX, 0x00}, | ||
216 | {MAX98090_0x2B_HP_CTR, 0x00}, | ||
217 | {MAX98090_0x2C_L_HP_VOL, 0x1A}, | ||
218 | {MAX98090_0x2D_R_HP_VOL, 0x1A}, | ||
219 | |||
220 | /* SPEAKER CONFIGURATION REGISTERS */ | ||
221 | {MAX98090_0x2E_L_SPK_MIX, 0x00}, | ||
222 | {MAX98090_0x2F_R_SPK_MIX, 0x00}, | ||
223 | {MAX98090_0x30_SPK_CTR, 0x00}, | ||
224 | {MAX98090_0x31_L_SPK_VOL, 0x2C}, | ||
225 | {MAX98090_0x32_R_SPK_VOL, 0x2C}, | ||
226 | |||
227 | /* ALC CONFIGURATION REGISTERS */ | ||
228 | {MAX98090_0x33_ALC_TIMING, 0x00}, | ||
229 | {MAX98090_0x34_ALC_COMPRESSOR, 0x00}, | ||
230 | {MAX98090_0x35_ALC_EXPANDER, 0x00}, | ||
231 | {MAX98090_0x36_ALC_GAIN, 0x00}, | ||
232 | |||
233 | /* RECEIVER AND LINE_OUTPUT REGISTERS */ | ||
234 | {MAX98090_0x37_RCV_LOUT_L_MIX, 0x00}, | ||
235 | {MAX98090_0x38_RCV_LOUT_L_CNTL, 0x00}, | ||
236 | {MAX98090_0x39_RCV_LOUT_L_VOL, 0x15}, | ||
237 | {MAX98090_0x3A_LOUT_R_MIX, 0x00}, | ||
238 | {MAX98090_0x3B_LOUT_R_CNTL, 0x00}, | ||
239 | {MAX98090_0x3C_LOUT_R_VOL, 0x15}, | ||
240 | |||
241 | /* JACK DETECT AND ENABLE REGISTERS */ | ||
242 | {MAX98090_0x3D_JACK_DETECT, 0x00}, | ||
243 | {MAX98090_0x3E_IN_ENABLE, 0x00}, | ||
244 | {MAX98090_0x3F_OUT_ENABLE, 0x00}, | ||
245 | {MAX98090_0x40_LVL_CTR, 0x00}, | ||
246 | {MAX98090_0x41_DSP_FILTER_ENABLE, 0x00}, | ||
247 | |||
248 | /* BIAS AND POWER MODE CONFIGURATION REGISTERS */ | ||
249 | {MAX98090_0x42_BIAS_CTR, 0x00}, | ||
250 | {MAX98090_0x43_DAC_CTR, 0x00}, | ||
251 | {MAX98090_0x44_ADC_CTR, 0x06}, | ||
252 | {MAX98090_0x45_DEV_SHUTDOWN, 0x00}, | ||
253 | }; | ||
254 | |||
255 | static const unsigned int max98090_hp_tlv[] = { | ||
256 | TLV_DB_RANGE_HEAD(5), | ||
257 | 0x0, 0x6, TLV_DB_SCALE_ITEM(-6700, 400, 0), | ||
258 | 0x7, 0xE, TLV_DB_SCALE_ITEM(-4000, 300, 0), | ||
259 | 0xF, 0x15, TLV_DB_SCALE_ITEM(-1700, 200, 0), | ||
260 | 0x16, 0x1B, TLV_DB_SCALE_ITEM(-400, 100, 0), | ||
261 | 0x1C, 0x1F, TLV_DB_SCALE_ITEM(150, 50, 0), | ||
262 | }; | ||
263 | |||
264 | static struct snd_kcontrol_new max98090_snd_controls[] = { | ||
265 | SOC_DOUBLE_R_TLV("Headphone Volume", MAX98090_0x2C_L_HP_VOL, | ||
266 | MAX98090_0x2D_R_HP_VOL, 0, 31, 0, max98090_hp_tlv), | ||
267 | }; | ||
268 | |||
269 | /* Left HeadPhone Mixer Switch */ | ||
270 | static struct snd_kcontrol_new max98090_left_hp_mixer_controls[] = { | ||
271 | SOC_DAPM_SINGLE("DACR Switch", MAX98090_0x29_L_HP_MIX, 1, 1, 0), | ||
272 | SOC_DAPM_SINGLE("DACL Switch", MAX98090_0x29_L_HP_MIX, 0, 1, 0), | ||
273 | }; | ||
274 | |||
275 | /* Right HeadPhone Mixer Switch */ | ||
276 | static struct snd_kcontrol_new max98090_right_hp_mixer_controls[] = { | ||
277 | SOC_DAPM_SINGLE("DACR Switch", MAX98090_0x2A_R_HP_MIX, 1, 1, 0), | ||
278 | SOC_DAPM_SINGLE("DACL Switch", MAX98090_0x2A_R_HP_MIX, 0, 1, 0), | ||
279 | }; | ||
280 | |||
281 | static struct snd_soc_dapm_widget max98090_dapm_widgets[] = { | ||
282 | /* Output */ | ||
283 | SND_SOC_DAPM_OUTPUT("HPL"), | ||
284 | SND_SOC_DAPM_OUTPUT("HPR"), | ||
285 | |||
286 | /* PGA */ | ||
287 | SND_SOC_DAPM_PGA("HPL Out", MAX98090_0x3F_OUT_ENABLE, 7, 0, NULL, 0), | ||
288 | SND_SOC_DAPM_PGA("HPR Out", MAX98090_0x3F_OUT_ENABLE, 6, 0, NULL, 0), | ||
289 | |||
290 | /* Mixer */ | ||
291 | SND_SOC_DAPM_MIXER("HPL Mixer", SND_SOC_NOPM, 0, 0, | ||
292 | max98090_left_hp_mixer_controls, | ||
293 | ARRAY_SIZE(max98090_left_hp_mixer_controls)), | ||
294 | |||
295 | SND_SOC_DAPM_MIXER("HPR Mixer", SND_SOC_NOPM, 0, 0, | ||
296 | max98090_right_hp_mixer_controls, | ||
297 | ARRAY_SIZE(max98090_right_hp_mixer_controls)), | ||
298 | |||
299 | /* DAC */ | ||
300 | SND_SOC_DAPM_DAC("DACL", "Hifi Playback", MAX98090_0x3F_OUT_ENABLE, 0, 0), | ||
301 | SND_SOC_DAPM_DAC("DACR", "Hifi Playback", MAX98090_0x3F_OUT_ENABLE, 1, 0), | ||
302 | }; | ||
303 | |||
304 | static struct snd_soc_dapm_route max98090_audio_map[] = { | ||
305 | /* Output */ | ||
306 | {"HPL", NULL, "HPL Out"}, | ||
307 | {"HPR", NULL, "HPR Out"}, | ||
308 | |||
309 | /* PGA */ | ||
310 | {"HPL Out", NULL, "HPL Mixer"}, | ||
311 | {"HPR Out", NULL, "HPR Mixer"}, | ||
312 | |||
313 | /* Mixer*/ | ||
314 | {"HPL Mixer", "DACR Switch", "DACR"}, | ||
315 | {"HPL Mixer", "DACL Switch", "DACL"}, | ||
316 | |||
317 | {"HPR Mixer", "DACR Switch", "DACR"}, | ||
318 | {"HPR Mixer", "DACL Switch", "DACL"}, | ||
319 | }; | ||
320 | |||
321 | static bool max98090_volatile(struct device *dev, unsigned int reg) | ||
322 | { | ||
323 | if ((reg == MAX98090_0x01_INT_STS) || | ||
324 | (reg == MAX98090_0x02_JACK_STS) || | ||
325 | (reg > MAX98090_REG_MAX_CACHED)) | ||
326 | return true; | ||
327 | |||
328 | return false; | ||
329 | } | ||
330 | |||
331 | static int max98090_dai_hw_params(struct snd_pcm_substream *substream, | ||
332 | struct snd_pcm_hw_params *params, | ||
333 | struct snd_soc_dai *dai) | ||
334 | { | ||
335 | struct snd_soc_codec *codec = dai->codec; | ||
336 | unsigned int val; | ||
337 | |||
338 | switch (params_rate(params)) { | ||
339 | case 96000: | ||
340 | val = 1 << 5; | ||
341 | break; | ||
342 | case 32000: | ||
343 | val = 1 << 4; | ||
344 | break; | ||
345 | case 48000: | ||
346 | val = 1 << 3; | ||
347 | break; | ||
348 | case 44100: | ||
349 | val = 1 << 2; | ||
350 | break; | ||
351 | case 16000: | ||
352 | val = 1 << 1; | ||
353 | break; | ||
354 | case 8000: | ||
355 | val = 1 << 0; | ||
356 | break; | ||
357 | default: | ||
358 | dev_err(codec->dev, "unsupported rate\n"); | ||
359 | return -EINVAL; | ||
360 | } | ||
361 | snd_soc_update_bits(codec, MAX98090_0x05_SAMPLE_RATE, 0x03F, val); | ||
362 | |||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | static int max98090_dai_set_sysclk(struct snd_soc_dai *dai, | ||
367 | int clk_id, unsigned int freq, int dir) | ||
368 | { | ||
369 | struct snd_soc_codec *codec = dai->codec; | ||
370 | unsigned int val; | ||
371 | |||
372 | snd_soc_update_bits(codec, MAX98090_0x45_DEV_SHUTDOWN, | ||
373 | MAX98090_SHDNRUN, 0); | ||
374 | |||
375 | switch (freq) { | ||
376 | case 26000000: | ||
377 | val = 1 << 7; | ||
378 | break; | ||
379 | case 19200000: | ||
380 | val = 1 << 6; | ||
381 | break; | ||
382 | case 13000000: | ||
383 | val = 1 << 5; | ||
384 | break; | ||
385 | case 12288000: | ||
386 | val = 1 << 4; | ||
387 | break; | ||
388 | case 12000000: | ||
389 | val = 1 << 3; | ||
390 | break; | ||
391 | case 11289600: | ||
392 | val = 1 << 2; | ||
393 | break; | ||
394 | default: | ||
395 | dev_err(codec->dev, "Invalid master clock frequency\n"); | ||
396 | return -EINVAL; | ||
397 | } | ||
398 | snd_soc_update_bits(codec, MAX98090_0x04_SYS_CLK, 0xFD, val); | ||
399 | |||
400 | snd_soc_update_bits(codec, MAX98090_0x45_DEV_SHUTDOWN, | ||
401 | MAX98090_SHDNRUN, MAX98090_SHDNRUN); | ||
402 | |||
403 | dev_dbg(dai->dev, "sysclk is %uHz\n", freq); | ||
404 | |||
405 | return 0; | ||
406 | } | ||
407 | |||
408 | static int max98090_dai_set_fmt(struct snd_soc_dai *dai, | ||
409 | unsigned int fmt) | ||
410 | { | ||
411 | struct snd_soc_codec *codec = dai->codec; | ||
412 | int is_master; | ||
413 | u8 val; | ||
414 | |||
415 | /* master/slave mode */ | ||
416 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
417 | case SND_SOC_DAIFMT_CBM_CFM: | ||
418 | is_master = 1; | ||
419 | break; | ||
420 | case SND_SOC_DAIFMT_CBS_CFS: | ||
421 | is_master = 0; | ||
422 | break; | ||
423 | default: | ||
424 | dev_err(codec->dev, "unsupported clock\n"); | ||
425 | return -EINVAL; | ||
426 | } | ||
427 | |||
428 | /* format */ | ||
429 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
430 | case SND_SOC_DAIFMT_I2S: | ||
431 | val = (is_master) ? MAX98090_I2S_M : MAX98090_I2S_S; | ||
432 | break; | ||
433 | case SND_SOC_DAIFMT_RIGHT_J: | ||
434 | val = (is_master) ? MAX98090_RJ_M : MAX98090_RJ_S; | ||
435 | break; | ||
436 | case SND_SOC_DAIFMT_LEFT_J: | ||
437 | val = (is_master) ? MAX98090_LJ_M : MAX98090_LJ_S; | ||
438 | break; | ||
439 | default: | ||
440 | dev_err(codec->dev, "unsupported format\n"); | ||
441 | return -EINVAL; | ||
442 | } | ||
443 | snd_soc_update_bits(codec, MAX98090_0x06_DAI_IF, | ||
444 | MAX98090_DAI_IF_MASK, val); | ||
445 | |||
446 | return 0; | ||
447 | } | ||
448 | |||
449 | #define MAX98090_RATES SNDRV_PCM_RATE_8000_96000 | ||
450 | #define MAX98090_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) | ||
451 | |||
452 | static struct snd_soc_dai_ops max98090_dai_ops = { | ||
453 | .set_sysclk = max98090_dai_set_sysclk, | ||
454 | .set_fmt = max98090_dai_set_fmt, | ||
455 | .hw_params = max98090_dai_hw_params, | ||
456 | }; | ||
457 | |||
458 | static struct snd_soc_dai_driver max98090_dai = { | ||
459 | .name = "max98090-Hifi", | ||
460 | .playback = { | ||
461 | .stream_name = "Playback", | ||
462 | .channels_min = 1, | ||
463 | .channels_max = 2, | ||
464 | .rates = MAX98090_RATES, | ||
465 | .formats = MAX98090_FORMATS, | ||
466 | }, | ||
467 | .ops = &max98090_dai_ops, | ||
468 | }; | ||
469 | |||
470 | static int max98090_probe(struct snd_soc_codec *codec) | ||
471 | { | ||
472 | struct max98090_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
473 | struct device *dev = codec->dev; | ||
474 | int ret; | ||
475 | |||
476 | codec->control_data = priv->regmap; | ||
477 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
478 | if (ret < 0) { | ||
479 | dev_err(dev, "Failed to set cache I/O: %d\n", ret); | ||
480 | return ret; | ||
481 | } | ||
482 | |||
483 | /* Device active */ | ||
484 | snd_soc_update_bits(codec, MAX98090_0x45_DEV_SHUTDOWN, | ||
485 | MAX98090_SHDNRUN, MAX98090_SHDNRUN); | ||
486 | |||
487 | return 0; | ||
488 | } | ||
489 | |||
490 | static int max98090_remove(struct snd_soc_codec *codec) | ||
491 | { | ||
492 | return 0; | ||
493 | } | ||
494 | |||
495 | static struct snd_soc_codec_driver soc_codec_dev_max98090 = { | ||
496 | .probe = max98090_probe, | ||
497 | .remove = max98090_remove, | ||
498 | .controls = max98090_snd_controls, | ||
499 | .num_controls = ARRAY_SIZE(max98090_snd_controls), | ||
500 | .dapm_widgets = max98090_dapm_widgets, | ||
501 | .num_dapm_widgets = ARRAY_SIZE(max98090_dapm_widgets), | ||
502 | .dapm_routes = max98090_audio_map, | ||
503 | .num_dapm_routes = ARRAY_SIZE(max98090_audio_map), | ||
504 | }; | ||
505 | |||
506 | static const struct regmap_config max98090_regmap = { | ||
507 | .reg_bits = 8, | ||
508 | .val_bits = 8, | ||
509 | .max_register = MAX98090_REG_END, | ||
510 | .volatile_reg = max98090_volatile, | ||
511 | .cache_type = REGCACHE_RBTREE, | ||
512 | .reg_defaults = max98090_reg_defaults, | ||
513 | .num_reg_defaults = ARRAY_SIZE(max98090_reg_defaults), | ||
514 | }; | ||
515 | |||
516 | static int max98090_i2c_probe(struct i2c_client *i2c, | ||
517 | const struct i2c_device_id *id) | ||
518 | { | ||
519 | struct max98090_priv *priv; | ||
520 | struct device *dev = &i2c->dev; | ||
521 | unsigned int val; | ||
522 | int ret; | ||
523 | |||
524 | priv = devm_kzalloc(dev, sizeof(struct max98090_priv), | ||
525 | GFP_KERNEL); | ||
526 | if (!priv) | ||
527 | return -ENOMEM; | ||
528 | |||
529 | priv->regmap = devm_regmap_init_i2c(i2c, &max98090_regmap); | ||
530 | if (IS_ERR(priv->regmap)) { | ||
531 | ret = PTR_ERR(priv->regmap); | ||
532 | dev_err(dev, "Failed to init regmap: %d\n", ret); | ||
533 | return ret; | ||
534 | } | ||
535 | |||
536 | i2c_set_clientdata(i2c, priv); | ||
537 | |||
538 | ret = regmap_read(priv->regmap, MAX98090_0xFF_REV_ID, &val); | ||
539 | if (ret < 0) { | ||
540 | dev_err(dev, "Failed to read device revision: %d\n", ret); | ||
541 | return ret; | ||
542 | } | ||
543 | dev_info(dev, "revision 0x%02x\n", val); | ||
544 | |||
545 | ret = snd_soc_register_codec(dev, | ||
546 | &soc_codec_dev_max98090, | ||
547 | &max98090_dai, 1); | ||
548 | |||
549 | return ret; | ||
550 | } | ||
551 | |||
552 | static int max98090_i2c_remove(struct i2c_client *client) | ||
553 | { | ||
554 | snd_soc_unregister_codec(&client->dev); | ||
555 | return 0; | ||
556 | } | ||
557 | |||
558 | static const struct i2c_device_id max98090_i2c_id[] = { | ||
559 | { "max98090", 0 }, | ||
560 | { } | ||
561 | }; | ||
562 | MODULE_DEVICE_TABLE(i2c, max98090_i2c_id); | ||
563 | |||
564 | static struct i2c_driver max98090_i2c_driver = { | ||
565 | .driver = { | ||
566 | .name = "max98090", | ||
567 | .owner = THIS_MODULE, | ||
568 | }, | ||
569 | .probe = max98090_i2c_probe, | ||
570 | .remove = max98090_i2c_remove, | ||
571 | .id_table = max98090_i2c_id, | ||
572 | }; | ||
573 | module_i2c_driver(max98090_i2c_driver); | ||
574 | |||
575 | MODULE_DESCRIPTION("ALSA SoC MAX98090 driver"); | ||
576 | MODULE_AUTHOR("Peter Hsiang, Kuninori Morimoto"); | ||
577 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c index 960d0e93cce9..d6ca615489ee 100644 --- a/sound/soc/codecs/rt5631.c +++ b/sound/soc/codecs/rt5631.c | |||
@@ -1382,7 +1382,7 @@ static int rt5631_hifi_pcm_params(struct snd_pcm_substream *substream, | |||
1382 | timesofbclk); | 1382 | timesofbclk); |
1383 | if (coeff < 0) { | 1383 | if (coeff < 0) { |
1384 | dev_err(codec->dev, "Fail to get coeff\n"); | 1384 | dev_err(codec->dev, "Fail to get coeff\n"); |
1385 | return -EINVAL; | 1385 | return coeff; |
1386 | } | 1386 | } |
1387 | 1387 | ||
1388 | switch (params_format(params)) { | 1388 | switch (params_format(params)) { |
diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c new file mode 100644 index 000000000000..38145ba74db8 --- /dev/null +++ b/sound/soc/codecs/si476x.c | |||
@@ -0,0 +1,255 @@ | |||
1 | #include <linux/module.h> | ||
2 | #include <linux/slab.h> | ||
3 | #include <sound/pcm.h> | ||
4 | #include <sound/pcm_params.h> | ||
5 | #include <sound/soc.h> | ||
6 | #include <sound/initval.h> | ||
7 | |||
8 | #include <linux/i2c.h> | ||
9 | |||
10 | #include <linux/mfd/si476x-core.h> | ||
11 | |||
12 | enum si476x_audio_registers { | ||
13 | SI476X_DIGITAL_IO_OUTPUT_FORMAT = 0x0203, | ||
14 | SI476X_DIGITAL_IO_OUTPUT_SAMPLE_RATE = 0x0202, | ||
15 | }; | ||
16 | |||
17 | enum si476x_digital_io_output_format { | ||
18 | SI476X_DIGITAL_IO_SLOT_SIZE_SHIFT = 11, | ||
19 | SI476X_DIGITAL_IO_SAMPLE_SIZE_SHIFT = 8, | ||
20 | }; | ||
21 | |||
22 | #define SI476X_DIGITAL_IO_OUTPUT_WIDTH_MASK ((0b111 << SI476X_DIGITAL_IO_SLOT_SIZE_SHIFT) | \ | ||
23 | (0b111 << SI476X_DIGITAL_IO_SAMPLE_SIZE_SHIFT)) | ||
24 | #define SI476X_DIGITAL_IO_OUTPUT_FORMAT_MASK (0b1111110) | ||
25 | |||
26 | enum si476x_daudio_formats { | ||
27 | SI476X_DAUDIO_MODE_I2S = (0x0 << 1), | ||
28 | SI476X_DAUDIO_MODE_DSP_A = (0x6 << 1), | ||
29 | SI476X_DAUDIO_MODE_DSP_B = (0x7 << 1), | ||
30 | SI476X_DAUDIO_MODE_LEFT_J = (0x8 << 1), | ||
31 | SI476X_DAUDIO_MODE_RIGHT_J = (0x9 << 1), | ||
32 | |||
33 | SI476X_DAUDIO_MODE_IB = (1 << 5), | ||
34 | SI476X_DAUDIO_MODE_IF = (1 << 6), | ||
35 | }; | ||
36 | |||
37 | enum si476x_pcm_format { | ||
38 | SI476X_PCM_FORMAT_S8 = 2, | ||
39 | SI476X_PCM_FORMAT_S16_LE = 4, | ||
40 | SI476X_PCM_FORMAT_S20_3LE = 5, | ||
41 | SI476X_PCM_FORMAT_S24_LE = 6, | ||
42 | }; | ||
43 | |||
44 | static unsigned int si476x_codec_read(struct snd_soc_codec *codec, | ||
45 | unsigned int reg) | ||
46 | { | ||
47 | int err; | ||
48 | struct si476x_core *core = codec->control_data; | ||
49 | |||
50 | si476x_core_lock(core); | ||
51 | err = si476x_core_cmd_get_property(core, reg); | ||
52 | si476x_core_unlock(core); | ||
53 | |||
54 | return err; | ||
55 | } | ||
56 | |||
57 | static int si476x_codec_write(struct snd_soc_codec *codec, | ||
58 | unsigned int reg, unsigned int val) | ||
59 | { | ||
60 | int err; | ||
61 | struct si476x_core *core = codec->control_data; | ||
62 | |||
63 | si476x_core_lock(core); | ||
64 | err = si476x_core_cmd_set_property(core, reg, val); | ||
65 | si476x_core_unlock(core); | ||
66 | |||
67 | return err; | ||
68 | } | ||
69 | |||
70 | static int si476x_codec_set_dai_fmt(struct snd_soc_dai *codec_dai, | ||
71 | unsigned int fmt) | ||
72 | { | ||
73 | int err; | ||
74 | u16 format = 0; | ||
75 | |||
76 | if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) | ||
77 | return -EINVAL; | ||
78 | |||
79 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
80 | case SND_SOC_DAIFMT_DSP_A: | ||
81 | format |= SI476X_DAUDIO_MODE_DSP_A; | ||
82 | break; | ||
83 | case SND_SOC_DAIFMT_DSP_B: | ||
84 | format |= SI476X_DAUDIO_MODE_DSP_B; | ||
85 | break; | ||
86 | case SND_SOC_DAIFMT_I2S: | ||
87 | format |= SI476X_DAUDIO_MODE_I2S; | ||
88 | break; | ||
89 | case SND_SOC_DAIFMT_RIGHT_J: | ||
90 | format |= SI476X_DAUDIO_MODE_RIGHT_J; | ||
91 | break; | ||
92 | case SND_SOC_DAIFMT_LEFT_J: | ||
93 | format |= SI476X_DAUDIO_MODE_LEFT_J; | ||
94 | break; | ||
95 | default: | ||
96 | return -EINVAL; | ||
97 | } | ||
98 | |||
99 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
100 | case SND_SOC_DAIFMT_DSP_A: | ||
101 | case SND_SOC_DAIFMT_DSP_B: | ||
102 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
103 | case SND_SOC_DAIFMT_NB_NF: | ||
104 | break; | ||
105 | case SND_SOC_DAIFMT_IB_NF: | ||
106 | format |= SI476X_DAUDIO_MODE_IB; | ||
107 | break; | ||
108 | default: | ||
109 | return -EINVAL; | ||
110 | } | ||
111 | break; | ||
112 | case SND_SOC_DAIFMT_I2S: | ||
113 | case SND_SOC_DAIFMT_RIGHT_J: | ||
114 | case SND_SOC_DAIFMT_LEFT_J: | ||
115 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
116 | case SND_SOC_DAIFMT_NB_NF: | ||
117 | break; | ||
118 | case SND_SOC_DAIFMT_IB_IF: | ||
119 | format |= SI476X_DAUDIO_MODE_IB | | ||
120 | SI476X_DAUDIO_MODE_IF; | ||
121 | break; | ||
122 | case SND_SOC_DAIFMT_IB_NF: | ||
123 | format |= SI476X_DAUDIO_MODE_IB; | ||
124 | break; | ||
125 | case SND_SOC_DAIFMT_NB_IF: | ||
126 | format |= SI476X_DAUDIO_MODE_IF; | ||
127 | break; | ||
128 | default: | ||
129 | return -EINVAL; | ||
130 | } | ||
131 | break; | ||
132 | default: | ||
133 | return -EINVAL; | ||
134 | } | ||
135 | |||
136 | err = snd_soc_update_bits(codec_dai->codec, SI476X_DIGITAL_IO_OUTPUT_FORMAT, | ||
137 | SI476X_DIGITAL_IO_OUTPUT_FORMAT_MASK, | ||
138 | format); | ||
139 | if (err < 0) { | ||
140 | dev_err(codec_dai->codec->dev, "Failed to set output format\n"); | ||
141 | return err; | ||
142 | } | ||
143 | |||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | static int si476x_codec_hw_params(struct snd_pcm_substream *substream, | ||
148 | struct snd_pcm_hw_params *params, | ||
149 | struct snd_soc_dai *dai) | ||
150 | { | ||
151 | int rate, width, err; | ||
152 | |||
153 | rate = params_rate(params); | ||
154 | if (rate < 32000 || rate > 48000) { | ||
155 | dev_err(dai->codec->dev, "Rate: %d is not supported\n", rate); | ||
156 | return -EINVAL; | ||
157 | } | ||
158 | |||
159 | switch (params_format(params)) { | ||
160 | case SNDRV_PCM_FORMAT_S8: | ||
161 | width = SI476X_PCM_FORMAT_S8; | ||
162 | case SNDRV_PCM_FORMAT_S16_LE: | ||
163 | width = SI476X_PCM_FORMAT_S16_LE; | ||
164 | break; | ||
165 | case SNDRV_PCM_FORMAT_S20_3LE: | ||
166 | width = SI476X_PCM_FORMAT_S20_3LE; | ||
167 | break; | ||
168 | case SNDRV_PCM_FORMAT_S24_LE: | ||
169 | width = SI476X_PCM_FORMAT_S24_LE; | ||
170 | break; | ||
171 | default: | ||
172 | return -EINVAL; | ||
173 | } | ||
174 | |||
175 | err = snd_soc_write(dai->codec, SI476X_DIGITAL_IO_OUTPUT_SAMPLE_RATE, | ||
176 | rate); | ||
177 | if (err < 0) { | ||
178 | dev_err(dai->codec->dev, "Failed to set sample rate\n"); | ||
179 | return err; | ||
180 | } | ||
181 | |||
182 | err = snd_soc_update_bits(dai->codec, SI476X_DIGITAL_IO_OUTPUT_FORMAT, | ||
183 | SI476X_DIGITAL_IO_OUTPUT_WIDTH_MASK, | ||
184 | (width << SI476X_DIGITAL_IO_SLOT_SIZE_SHIFT) | | ||
185 | (width << SI476X_DIGITAL_IO_SAMPLE_SIZE_SHIFT)); | ||
186 | if (err < 0) { | ||
187 | dev_err(dai->codec->dev, "Failed to set output width\n"); | ||
188 | return err; | ||
189 | } | ||
190 | |||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | static int si476x_codec_probe(struct snd_soc_codec *codec) | ||
195 | { | ||
196 | codec->control_data = i2c_mfd_cell_to_core(codec->dev); | ||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | static struct snd_soc_dai_ops si476x_dai_ops = { | ||
201 | .hw_params = si476x_codec_hw_params, | ||
202 | .set_fmt = si476x_codec_set_dai_fmt, | ||
203 | }; | ||
204 | |||
205 | static struct snd_soc_dai_driver si476x_dai = { | ||
206 | .name = "si476x-codec", | ||
207 | .capture = { | ||
208 | .stream_name = "Capture", | ||
209 | .channels_min = 2, | ||
210 | .channels_max = 2, | ||
211 | |||
212 | .rates = SNDRV_PCM_RATE_32000 | | ||
213 | SNDRV_PCM_RATE_44100 | | ||
214 | SNDRV_PCM_RATE_48000, | ||
215 | .formats = SNDRV_PCM_FMTBIT_S8 | | ||
216 | SNDRV_PCM_FMTBIT_S16_LE | | ||
217 | SNDRV_PCM_FMTBIT_S20_3LE | | ||
218 | SNDRV_PCM_FMTBIT_S24_LE | ||
219 | }, | ||
220 | .ops = &si476x_dai_ops, | ||
221 | }; | ||
222 | |||
223 | static struct snd_soc_codec_driver soc_codec_dev_si476x = { | ||
224 | .probe = si476x_codec_probe, | ||
225 | .read = si476x_codec_read, | ||
226 | .write = si476x_codec_write, | ||
227 | }; | ||
228 | |||
229 | static int __devinit si476x_platform_probe(struct platform_device *pdev) | ||
230 | { | ||
231 | return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_si476x, | ||
232 | &si476x_dai, 1); | ||
233 | } | ||
234 | |||
235 | static int __devexit si476x_platform_remove(struct platform_device *pdev) | ||
236 | { | ||
237 | snd_soc_unregister_codec(&pdev->dev); | ||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | MODULE_ALIAS("platform:si476x-codec"); | ||
242 | |||
243 | static struct platform_driver si476x_platform_driver = { | ||
244 | .driver = { | ||
245 | .name = "si476x-codec", | ||
246 | .owner = THIS_MODULE, | ||
247 | }, | ||
248 | .probe = si476x_platform_probe, | ||
249 | .remove = __devexit_p(si476x_platform_remove), | ||
250 | }; | ||
251 | module_platform_driver(si476x_platform_driver); | ||
252 | |||
253 | MODULE_AUTHOR("Andrey Smirnov <andrey.smirnov@convergeddevices.net>"); | ||
254 | MODULE_DESCRIPTION("ASoC Si4761/64 codec driver"); | ||
255 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index f230292ba96b..e39e08d5d8e4 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
30 | #include <linux/pm.h> | 30 | #include <linux/pm.h> |
31 | #include <linux/gpio.h> | ||
31 | #include <linux/i2c.h> | 32 | #include <linux/i2c.h> |
32 | #include <linux/cdev.h> | 33 | #include <linux/cdev.h> |
33 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
@@ -65,6 +66,7 @@ struct aic32x4_priv { | |||
65 | u32 power_cfg; | 66 | u32 power_cfg; |
66 | u32 micpga_routing; | 67 | u32 micpga_routing; |
67 | bool swapdacs; | 68 | bool swapdacs; |
69 | int rstn_gpio; | ||
68 | }; | 70 | }; |
69 | 71 | ||
70 | /* 0dB min, 1dB steps */ | 72 | /* 0dB min, 1dB steps */ |
@@ -627,10 +629,20 @@ static int aic32x4_probe(struct snd_soc_codec *codec) | |||
627 | { | 629 | { |
628 | struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); | 630 | struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); |
629 | u32 tmp_reg; | 631 | u32 tmp_reg; |
632 | int ret; | ||
630 | 633 | ||
631 | codec->hw_write = (hw_write_t) i2c_master_send; | 634 | codec->hw_write = (hw_write_t) i2c_master_send; |
632 | codec->control_data = aic32x4->control_data; | 635 | codec->control_data = aic32x4->control_data; |
633 | 636 | ||
637 | if (aic32x4->rstn_gpio >= 0) { | ||
638 | ret = devm_gpio_request_one(codec->dev, aic32x4->rstn_gpio, | ||
639 | GPIOF_OUT_INIT_LOW, "tlv320aic32x4 rstn"); | ||
640 | if (ret != 0) | ||
641 | return ret; | ||
642 | ndelay(10); | ||
643 | gpio_set_value(aic32x4->rstn_gpio, 1); | ||
644 | } | ||
645 | |||
634 | snd_soc_write(codec, AIC32X4_RESET, 0x01); | 646 | snd_soc_write(codec, AIC32X4_RESET, 0x01); |
635 | 647 | ||
636 | /* Power platform configuration */ | 648 | /* Power platform configuration */ |
@@ -675,6 +687,16 @@ static int aic32x4_probe(struct snd_soc_codec *codec) | |||
675 | ARRAY_SIZE(aic32x4_snd_controls)); | 687 | ARRAY_SIZE(aic32x4_snd_controls)); |
676 | aic32x4_add_widgets(codec); | 688 | aic32x4_add_widgets(codec); |
677 | 689 | ||
690 | /* | ||
691 | * Workaround: for an unknown reason, the ADC needs to be powered up | ||
692 | * and down for the first capture to work properly. It seems related to | ||
693 | * a HW BUG or some kind of behavior not documented in the datasheet. | ||
694 | */ | ||
695 | tmp_reg = snd_soc_read(codec, AIC32X4_ADCSETUP); | ||
696 | snd_soc_write(codec, AIC32X4_ADCSETUP, tmp_reg | | ||
697 | AIC32X4_LADC_EN | AIC32X4_RADC_EN); | ||
698 | snd_soc_write(codec, AIC32X4_ADCSETUP, tmp_reg); | ||
699 | |||
678 | return 0; | 700 | return 0; |
679 | } | 701 | } |
680 | 702 | ||
@@ -713,10 +735,12 @@ static __devinit int aic32x4_i2c_probe(struct i2c_client *i2c, | |||
713 | aic32x4->power_cfg = pdata->power_cfg; | 735 | aic32x4->power_cfg = pdata->power_cfg; |
714 | aic32x4->swapdacs = pdata->swapdacs; | 736 | aic32x4->swapdacs = pdata->swapdacs; |
715 | aic32x4->micpga_routing = pdata->micpga_routing; | 737 | aic32x4->micpga_routing = pdata->micpga_routing; |
738 | aic32x4->rstn_gpio = pdata->rstn_gpio; | ||
716 | } else { | 739 | } else { |
717 | aic32x4->power_cfg = 0; | 740 | aic32x4->power_cfg = 0; |
718 | aic32x4->swapdacs = false; | 741 | aic32x4->swapdacs = false; |
719 | aic32x4->micpga_routing = 0; | 742 | aic32x4->micpga_routing = 0; |
743 | aic32x4->rstn_gpio = -1; | ||
720 | } | 744 | } |
721 | 745 | ||
722 | ret = snd_soc_register_codec(&i2c->dev, | 746 | ret = snd_soc_register_codec(&i2c->dev, |
diff --git a/sound/soc/codecs/tlv320aic32x4.h b/sound/soc/codecs/tlv320aic32x4.h index aae2b2440398..35774223fd91 100644 --- a/sound/soc/codecs/tlv320aic32x4.h +++ b/sound/soc/codecs/tlv320aic32x4.h | |||
@@ -94,6 +94,9 @@ | |||
94 | #define AIC32X4_WORD_LEN_24BITS 0x02 | 94 | #define AIC32X4_WORD_LEN_24BITS 0x02 |
95 | #define AIC32X4_WORD_LEN_32BITS 0x03 | 95 | #define AIC32X4_WORD_LEN_32BITS 0x03 |
96 | 96 | ||
97 | #define AIC32X4_LADC_EN (1 << 7) | ||
98 | #define AIC32X4_RADC_EN (1 << 6) | ||
99 | |||
97 | #define AIC32X4_I2S_MODE 0x00 | 100 | #define AIC32X4_I2S_MODE 0x00 |
98 | #define AIC32X4_DSP_MODE 0x01 | 101 | #define AIC32X4_DSP_MODE 0x01 |
99 | #define AIC32X4_RIGHT_JUSTIFIED_MODE 0x02 | 102 | #define AIC32X4_RIGHT_JUSTIFIED_MODE 0x02 |
diff --git a/sound/soc/codecs/wm0010.c b/sound/soc/codecs/wm0010.c index 99afc003a084..40256b526259 100644 --- a/sound/soc/codecs/wm0010.c +++ b/sound/soc/codecs/wm0010.c | |||
@@ -31,6 +31,9 @@ | |||
31 | 31 | ||
32 | #define DEVICE_ID_WM0010 10 | 32 | #define DEVICE_ID_WM0010 10 |
33 | 33 | ||
34 | /* We only support v1 of the .dfw INFO record */ | ||
35 | #define INFO_VERSION 1 | ||
36 | |||
34 | enum dfw_cmd { | 37 | enum dfw_cmd { |
35 | DFW_CMD_FUSE = 0x01, | 38 | DFW_CMD_FUSE = 0x01, |
36 | DFW_CMD_CODE_HDR, | 39 | DFW_CMD_CODE_HDR, |
@@ -46,6 +49,13 @@ struct dfw_binrec { | |||
46 | uint8_t data[0]; | 49 | uint8_t data[0]; |
47 | } __packed; | 50 | } __packed; |
48 | 51 | ||
52 | struct dfw_inforec { | ||
53 | u8 info_version; | ||
54 | u8 tool_major_version; | ||
55 | u8 tool_minor_version; | ||
56 | u8 dsp_target; | ||
57 | }; | ||
58 | |||
49 | struct dfw_pllrec { | 59 | struct dfw_pllrec { |
50 | u8 command; | 60 | u8 command; |
51 | u32 length:24; | 61 | u32 length:24; |
@@ -97,7 +107,6 @@ struct wm0010_priv { | |||
97 | 107 | ||
98 | enum wm0010_state state; | 108 | enum wm0010_state state; |
99 | bool boot_failed; | 109 | bool boot_failed; |
100 | int boot_done; | ||
101 | bool ready; | 110 | bool ready; |
102 | bool pll_running; | 111 | bool pll_running; |
103 | int max_spi_freq; | 112 | int max_spi_freq; |
@@ -234,7 +243,7 @@ static void wm0010_boot_xfer_complete(void *data) | |||
234 | break; | 243 | break; |
235 | 244 | ||
236 | case 0x55555555: | 245 | case 0x55555555: |
237 | if (wm0010->boot_done == 0) | 246 | if (wm0010->state < WM0010_STAGE2) |
238 | break; | 247 | break; |
239 | dev_err(codec->dev, | 248 | dev_err(codec->dev, |
240 | "%d: ROM bootloader running in stage 2\n", i); | 249 | "%d: ROM bootloader running in stage 2\n", i); |
@@ -321,7 +330,6 @@ static void wm0010_boot_xfer_complete(void *data) | |||
321 | break; | 330 | break; |
322 | } | 331 | } |
323 | 332 | ||
324 | wm0010->boot_done++; | ||
325 | if (xfer->done) | 333 | if (xfer->done) |
326 | complete(xfer->done); | 334 | complete(xfer->done); |
327 | } | 335 | } |
@@ -334,94 +342,198 @@ static void byte_swap_64(u64 *data_in, u64 *data_out, u32 len) | |||
334 | data_out[i] = cpu_to_be64(le64_to_cpu(data_in[i])); | 342 | data_out[i] = cpu_to_be64(le64_to_cpu(data_in[i])); |
335 | } | 343 | } |
336 | 344 | ||
337 | static int wm0010_boot(struct snd_soc_codec *codec) | 345 | static int wm0010_firmware_load(char *name, struct snd_soc_codec *codec) |
338 | { | 346 | { |
339 | struct spi_device *spi = to_spi_device(codec->dev); | 347 | struct spi_device *spi = to_spi_device(codec->dev); |
340 | struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec); | 348 | struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec); |
341 | unsigned long flags; | ||
342 | struct list_head xfer_list; | 349 | struct list_head xfer_list; |
343 | struct wm0010_boot_xfer *xfer; | 350 | struct wm0010_boot_xfer *xfer; |
344 | int ret; | 351 | int ret; |
345 | struct completion done; | 352 | struct completion done; |
346 | const struct firmware *fw; | 353 | const struct firmware *fw; |
347 | const struct dfw_binrec *rec; | 354 | const struct dfw_binrec *rec; |
348 | struct spi_message m; | 355 | const struct dfw_inforec *inforec; |
349 | struct spi_transfer t; | 356 | u64 *img; |
350 | struct dfw_pllrec pll_rec; | 357 | u8 *out, dsp; |
351 | u32 *img, *p; | ||
352 | u64 *img_swap; | ||
353 | u8 *out; | ||
354 | u32 len, offset; | 358 | u32 len, offset; |
355 | int i; | ||
356 | 359 | ||
357 | spin_lock_irqsave(&wm0010->irq_lock, flags); | 360 | INIT_LIST_HEAD(&xfer_list); |
358 | if (wm0010->state != WM0010_POWER_OFF) | ||
359 | dev_warn(wm0010->dev, "DSP already powered up!\n"); | ||
360 | spin_unlock_irqrestore(&wm0010->irq_lock, flags); | ||
361 | 361 | ||
362 | if (wm0010->sysclk > 26000000) { | 362 | ret = request_firmware(&fw, name, codec->dev); |
363 | dev_err(codec->dev, "Max DSP clock frequency is 26MHz\n"); | 363 | if (ret != 0) { |
364 | ret = -ECANCELED; | 364 | dev_err(codec->dev, "Failed to request application: %d\n", |
365 | goto err; | 365 | ret); |
366 | return ret; | ||
366 | } | 367 | } |
367 | 368 | ||
368 | INIT_LIST_HEAD(&xfer_list); | 369 | rec = (const struct dfw_binrec *)fw->data; |
370 | inforec = (const struct dfw_inforec *)rec->data; | ||
371 | offset = 0; | ||
372 | dsp = inforec->dsp_target; | ||
373 | wm0010->boot_failed = false; | ||
374 | BUG_ON(!list_empty(&xfer_list)); | ||
375 | init_completion(&done); | ||
369 | 376 | ||
370 | mutex_lock(&wm0010->lock); | 377 | /* First record should be INFO */ |
371 | wm0010->pll_running = false; | 378 | if (rec->command != DFW_CMD_INFO) { |
379 | dev_err(codec->dev, "First record not INFO\r\n"); | ||
380 | ret = -EINVAL; | ||
381 | goto abort; | ||
382 | } | ||
372 | 383 | ||
373 | dev_dbg(codec->dev, "max_spi_freq: %d\n", wm0010->max_spi_freq); | 384 | if (inforec->info_version != INFO_VERSION) { |
385 | dev_err(codec->dev, | ||
386 | "Unsupported version (%02d) of INFO record\r\n", | ||
387 | inforec->info_version); | ||
388 | ret = -EINVAL; | ||
389 | goto abort; | ||
390 | } | ||
374 | 391 | ||
375 | ret = regulator_bulk_enable(ARRAY_SIZE(wm0010->core_supplies), | 392 | dev_dbg(codec->dev, "Version v%02d INFO record found\r\n", |
376 | wm0010->core_supplies); | 393 | inforec->info_version); |
377 | if (ret != 0) { | 394 | |
378 | dev_err(&spi->dev, "Failed to enable core supplies: %d\n", | 395 | /* Check it's a DSP file */ |
379 | ret); | 396 | if (dsp != DEVICE_ID_WM0010) { |
380 | mutex_unlock(&wm0010->lock); | 397 | dev_err(codec->dev, "Not a WM0010 firmware file.\r\n"); |
381 | goto err; | 398 | ret = -EINVAL; |
399 | goto abort; | ||
382 | } | 400 | } |
383 | 401 | ||
384 | ret = regulator_enable(wm0010->dbvdd); | 402 | /* Skip the info record as we don't need to send it */ |
385 | if (ret != 0) { | 403 | offset += ((rec->length) + 8); |
386 | dev_err(&spi->dev, "Failed to enable DBVDD: %d\n", ret); | 404 | rec = (void *)&rec->data[rec->length]; |
387 | goto err_core; | 405 | |
406 | while (offset < fw->size) { | ||
407 | dev_dbg(codec->dev, | ||
408 | "Packet: command %d, data length = 0x%x\r\n", | ||
409 | rec->command, rec->length); | ||
410 | len = rec->length + 8; | ||
411 | |||
412 | out = kzalloc(len, GFP_KERNEL); | ||
413 | if (!out) { | ||
414 | dev_err(codec->dev, | ||
415 | "Failed to allocate RX buffer\n"); | ||
416 | ret = -ENOMEM; | ||
417 | goto abort1; | ||
418 | } | ||
419 | |||
420 | img = kzalloc(len, GFP_KERNEL); | ||
421 | if (!img) { | ||
422 | dev_err(codec->dev, | ||
423 | "Failed to allocate image buffer\n"); | ||
424 | ret = -ENOMEM; | ||
425 | goto abort1; | ||
426 | } | ||
427 | |||
428 | byte_swap_64((u64 *)&rec->command, img, len); | ||
429 | |||
430 | xfer = kzalloc(sizeof(*xfer), GFP_KERNEL); | ||
431 | if (!xfer) { | ||
432 | dev_err(codec->dev, "Failed to allocate xfer\n"); | ||
433 | ret = -ENOMEM; | ||
434 | goto abort1; | ||
435 | } | ||
436 | |||
437 | xfer->codec = codec; | ||
438 | list_add_tail(&xfer->list, &xfer_list); | ||
439 | |||
440 | spi_message_init(&xfer->m); | ||
441 | xfer->m.complete = wm0010_boot_xfer_complete; | ||
442 | xfer->m.context = xfer; | ||
443 | xfer->t.tx_buf = img; | ||
444 | xfer->t.rx_buf = out; | ||
445 | xfer->t.len = len; | ||
446 | xfer->t.bits_per_word = 8; | ||
447 | |||
448 | if (!wm0010->pll_running) { | ||
449 | xfer->t.speed_hz = wm0010->sysclk / 6; | ||
450 | } else { | ||
451 | xfer->t.speed_hz = wm0010->max_spi_freq; | ||
452 | |||
453 | if (wm0010->board_max_spi_speed && | ||
454 | (wm0010->board_max_spi_speed < wm0010->max_spi_freq)) | ||
455 | xfer->t.speed_hz = wm0010->board_max_spi_speed; | ||
456 | } | ||
457 | |||
458 | /* Store max usable spi frequency for later use */ | ||
459 | wm0010->max_spi_freq = xfer->t.speed_hz; | ||
460 | |||
461 | spi_message_add_tail(&xfer->t, &xfer->m); | ||
462 | |||
463 | offset += ((rec->length) + 8); | ||
464 | rec = (void *)&rec->data[rec->length]; | ||
465 | |||
466 | if (offset >= fw->size) { | ||
467 | dev_dbg(codec->dev, "All transfers scheduled\n"); | ||
468 | xfer->done = &done; | ||
469 | } | ||
470 | |||
471 | ret = spi_async(spi, &xfer->m); | ||
472 | if (ret != 0) { | ||
473 | dev_err(codec->dev, "Write failed: %d\n", ret); | ||
474 | goto abort1; | ||
475 | } | ||
476 | |||
477 | if (wm0010->boot_failed) { | ||
478 | dev_dbg(codec->dev, "Boot fail!\n"); | ||
479 | ret = -EINVAL; | ||
480 | goto abort1; | ||
481 | } | ||
388 | } | 482 | } |
389 | 483 | ||
390 | /* Release reset */ | 484 | wait_for_completion(&done); |
391 | gpio_set_value_cansleep(wm0010->gpio_reset, !wm0010->gpio_reset_value); | 485 | |
392 | spin_lock_irqsave(&wm0010->irq_lock, flags); | 486 | ret = 0; |
393 | wm0010->state = WM0010_OUT_OF_RESET; | 487 | |
394 | spin_unlock_irqrestore(&wm0010->irq_lock, flags); | 488 | abort1: |
489 | while (!list_empty(&xfer_list)) { | ||
490 | xfer = list_first_entry(&xfer_list, struct wm0010_boot_xfer, | ||
491 | list); | ||
492 | kfree(xfer->t.rx_buf); | ||
493 | kfree(xfer->t.tx_buf); | ||
494 | list_del(&xfer->list); | ||
495 | kfree(xfer); | ||
496 | } | ||
497 | |||
498 | abort: | ||
499 | release_firmware(fw); | ||
500 | return ret; | ||
501 | } | ||
502 | |||
503 | static int wm0010_stage2_load(struct snd_soc_codec *codec) | ||
504 | { | ||
505 | struct spi_device *spi = to_spi_device(codec->dev); | ||
506 | struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec); | ||
507 | const struct firmware *fw; | ||
508 | struct spi_message m; | ||
509 | struct spi_transfer t; | ||
510 | u32 *img; | ||
511 | u8 *out; | ||
512 | int i; | ||
513 | int ret = 0; | ||
395 | 514 | ||
396 | /* First the bootloader */ | ||
397 | ret = request_firmware(&fw, "wm0010_stage2.bin", codec->dev); | 515 | ret = request_firmware(&fw, "wm0010_stage2.bin", codec->dev); |
398 | if (ret != 0) { | 516 | if (ret != 0) { |
399 | dev_err(codec->dev, "Failed to request stage2 loader: %d\n", | 517 | dev_err(codec->dev, "Failed to request stage2 loader: %d\n", |
400 | ret); | 518 | ret); |
401 | goto abort; | 519 | return ret; |
402 | } | 520 | } |
403 | 521 | ||
404 | if (!wait_for_completion_timeout(&wm0010->boot_completion, | ||
405 | msecs_to_jiffies(10))) | ||
406 | dev_err(codec->dev, "Failed to get interrupt from DSP\n"); | ||
407 | |||
408 | spin_lock_irqsave(&wm0010->irq_lock, flags); | ||
409 | wm0010->state = WM0010_BOOTROM; | ||
410 | spin_unlock_irqrestore(&wm0010->irq_lock, flags); | ||
411 | |||
412 | dev_dbg(codec->dev, "Downloading %zu byte stage 2 loader\n", fw->size); | 522 | dev_dbg(codec->dev, "Downloading %zu byte stage 2 loader\n", fw->size); |
413 | 523 | ||
414 | /* Copy to local buffer first as vmalloc causes problems for dma */ | 524 | /* Copy to local buffer first as vmalloc causes problems for dma */ |
415 | img = kzalloc(fw->size, GFP_KERNEL); | 525 | img = kzalloc(fw->size, GFP_KERNEL); |
416 | if (!img) { | 526 | if (!img) { |
417 | dev_err(codec->dev, "Failed to allocate image buffer\n"); | 527 | dev_err(codec->dev, "Failed to allocate image buffer\n"); |
418 | goto abort; | 528 | ret = -ENOMEM; |
529 | goto abort2; | ||
419 | } | 530 | } |
420 | 531 | ||
421 | out = kzalloc(fw->size, GFP_KERNEL); | 532 | out = kzalloc(fw->size, GFP_KERNEL); |
422 | if (!out) { | 533 | if (!out) { |
423 | dev_err(codec->dev, "Failed to allocate output buffer\n"); | 534 | dev_err(codec->dev, "Failed to allocate output buffer\n"); |
424 | goto abort; | 535 | ret = -ENOMEM; |
536 | goto abort1; | ||
425 | } | 537 | } |
426 | 538 | ||
427 | memcpy(img, &fw->data[0], fw->size); | 539 | memcpy(img, &fw->data[0], fw->size); |
@@ -447,20 +559,97 @@ static int wm0010_boot(struct snd_soc_codec *codec) | |||
447 | /* Look for errors from the boot ROM */ | 559 | /* Look for errors from the boot ROM */ |
448 | for (i = 0; i < fw->size; i++) { | 560 | for (i = 0; i < fw->size; i++) { |
449 | if (out[i] != 0x55) { | 561 | if (out[i] != 0x55) { |
450 | ret = -EBUSY; | ||
451 | dev_err(codec->dev, "Boot ROM error: %x in %d\n", | 562 | dev_err(codec->dev, "Boot ROM error: %x in %d\n", |
452 | out[i], i); | 563 | out[i], i); |
453 | wm0010_mark_boot_failure(wm0010); | 564 | wm0010_mark_boot_failure(wm0010); |
565 | ret = -EBUSY; | ||
454 | goto abort; | 566 | goto abort; |
455 | } | 567 | } |
456 | } | 568 | } |
457 | 569 | abort: | |
458 | release_firmware(fw); | ||
459 | kfree(img); | ||
460 | kfree(out); | 570 | kfree(out); |
571 | abort1: | ||
572 | kfree(img); | ||
573 | abort2: | ||
574 | release_firmware(fw); | ||
575 | |||
576 | return ret; | ||
577 | } | ||
578 | |||
579 | static int wm0010_boot(struct snd_soc_codec *codec) | ||
580 | { | ||
581 | struct spi_device *spi = to_spi_device(codec->dev); | ||
582 | struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec); | ||
583 | unsigned long flags; | ||
584 | int ret; | ||
585 | const struct firmware *fw; | ||
586 | struct spi_message m; | ||
587 | struct spi_transfer t; | ||
588 | struct dfw_pllrec pll_rec; | ||
589 | u32 *p, len; | ||
590 | u64 *img_swap; | ||
591 | u8 *out; | ||
592 | int i; | ||
593 | |||
594 | spin_lock_irqsave(&wm0010->irq_lock, flags); | ||
595 | if (wm0010->state != WM0010_POWER_OFF) | ||
596 | dev_warn(wm0010->dev, "DSP already powered up!\n"); | ||
597 | spin_unlock_irqrestore(&wm0010->irq_lock, flags); | ||
598 | |||
599 | if (wm0010->sysclk > 26000000) { | ||
600 | dev_err(codec->dev, "Max DSP clock frequency is 26MHz\n"); | ||
601 | ret = -ECANCELED; | ||
602 | goto err; | ||
603 | } | ||
604 | |||
605 | mutex_lock(&wm0010->lock); | ||
606 | wm0010->pll_running = false; | ||
607 | |||
608 | dev_dbg(codec->dev, "max_spi_freq: %d\n", wm0010->max_spi_freq); | ||
609 | |||
610 | ret = regulator_bulk_enable(ARRAY_SIZE(wm0010->core_supplies), | ||
611 | wm0010->core_supplies); | ||
612 | if (ret != 0) { | ||
613 | dev_err(&spi->dev, "Failed to enable core supplies: %d\n", | ||
614 | ret); | ||
615 | mutex_unlock(&wm0010->lock); | ||
616 | goto err; | ||
617 | } | ||
618 | |||
619 | ret = regulator_enable(wm0010->dbvdd); | ||
620 | if (ret != 0) { | ||
621 | dev_err(&spi->dev, "Failed to enable DBVDD: %d\n", ret); | ||
622 | goto err_core; | ||
623 | } | ||
624 | |||
625 | /* Release reset */ | ||
626 | gpio_set_value_cansleep(wm0010->gpio_reset, !wm0010->gpio_reset_value); | ||
627 | spin_lock_irqsave(&wm0010->irq_lock, flags); | ||
628 | wm0010->state = WM0010_OUT_OF_RESET; | ||
629 | spin_unlock_irqrestore(&wm0010->irq_lock, flags); | ||
630 | |||
631 | /* First the bootloader */ | ||
632 | ret = request_firmware(&fw, "wm0010_stage2.bin", codec->dev); | ||
633 | if (ret != 0) { | ||
634 | dev_err(codec->dev, "Failed to request stage2 loader: %d\n", | ||
635 | ret); | ||
636 | goto abort; | ||
637 | } | ||
638 | |||
639 | if (!wait_for_completion_timeout(&wm0010->boot_completion, | ||
640 | msecs_to_jiffies(20))) | ||
641 | dev_err(codec->dev, "Failed to get interrupt from DSP\n"); | ||
642 | |||
643 | spin_lock_irqsave(&wm0010->irq_lock, flags); | ||
644 | wm0010->state = WM0010_BOOTROM; | ||
645 | spin_unlock_irqrestore(&wm0010->irq_lock, flags); | ||
646 | |||
647 | ret = wm0010_stage2_load(codec); | ||
648 | if (ret) | ||
649 | goto abort; | ||
461 | 650 | ||
462 | if (!wait_for_completion_timeout(&wm0010->boot_completion, | 651 | if (!wait_for_completion_timeout(&wm0010->boot_completion, |
463 | msecs_to_jiffies(10))) | 652 | msecs_to_jiffies(20))) |
464 | dev_err(codec->dev, "Failed to get interrupt from DSP loader.\n"); | 653 | dev_err(codec->dev, "Failed to get interrupt from DSP loader.\n"); |
465 | 654 | ||
466 | spin_lock_irqsave(&wm0010->irq_lock, flags); | 655 | spin_lock_irqsave(&wm0010->irq_lock, flags); |
@@ -535,110 +724,10 @@ static int wm0010_boot(struct snd_soc_codec *codec) | |||
535 | } else | 724 | } else |
536 | dev_dbg(codec->dev, "Not enabling DSP PLL."); | 725 | dev_dbg(codec->dev, "Not enabling DSP PLL."); |
537 | 726 | ||
538 | ret = request_firmware(&fw, "wm0010.dfw", codec->dev); | 727 | ret = wm0010_firmware_load("wm0010.dfw", codec); |
539 | if (ret != 0) { | ||
540 | dev_err(codec->dev, "Failed to request application: %d\n", | ||
541 | ret); | ||
542 | goto abort; | ||
543 | } | ||
544 | |||
545 | rec = (const struct dfw_binrec *)fw->data; | ||
546 | offset = 0; | ||
547 | wm0010->boot_done = 0; | ||
548 | wm0010->boot_failed = false; | ||
549 | BUG_ON(!list_empty(&xfer_list)); | ||
550 | init_completion(&done); | ||
551 | 728 | ||
552 | /* First record should be INFO */ | 729 | if (ret != 0) |
553 | if (rec->command != DFW_CMD_INFO) { | ||
554 | dev_err(codec->dev, "First record not INFO\r\n"); | ||
555 | goto abort; | ||
556 | } | ||
557 | |||
558 | /* Check it's a 0010 file */ | ||
559 | if (rec->data[0] != DEVICE_ID_WM0010) { | ||
560 | dev_err(codec->dev, "Not a WM0010 firmware file.\r\n"); | ||
561 | goto abort; | 730 | goto abort; |
562 | } | ||
563 | |||
564 | /* Skip the info record as we don't need to send it */ | ||
565 | offset += ((rec->length) + 8); | ||
566 | rec = (void *)&rec->data[rec->length]; | ||
567 | |||
568 | while (offset < fw->size) { | ||
569 | dev_dbg(codec->dev, | ||
570 | "Packet: command %d, data length = 0x%x\r\n", | ||
571 | rec->command, rec->length); | ||
572 | len = rec->length + 8; | ||
573 | |||
574 | out = kzalloc(len, GFP_KERNEL); | ||
575 | if (!out) { | ||
576 | dev_err(codec->dev, | ||
577 | "Failed to allocate RX buffer\n"); | ||
578 | goto abort; | ||
579 | } | ||
580 | |||
581 | img_swap = kzalloc(len, GFP_KERNEL); | ||
582 | if (!img_swap) { | ||
583 | dev_err(codec->dev, | ||
584 | "Failed to allocate image buffer\n"); | ||
585 | goto abort; | ||
586 | } | ||
587 | |||
588 | /* We need to re-order for 0010 */ | ||
589 | byte_swap_64((u64 *)&rec->command, img_swap, len); | ||
590 | |||
591 | xfer = kzalloc(sizeof(*xfer), GFP_KERNEL); | ||
592 | if (!xfer) { | ||
593 | dev_err(codec->dev, "Failed to allocate xfer\n"); | ||
594 | goto abort; | ||
595 | } | ||
596 | |||
597 | xfer->codec = codec; | ||
598 | list_add_tail(&xfer->list, &xfer_list); | ||
599 | |||
600 | spi_message_init(&xfer->m); | ||
601 | xfer->m.complete = wm0010_boot_xfer_complete; | ||
602 | xfer->m.context = xfer; | ||
603 | xfer->t.tx_buf = img_swap; | ||
604 | xfer->t.rx_buf = out; | ||
605 | xfer->t.len = len; | ||
606 | xfer->t.bits_per_word = 8; | ||
607 | |||
608 | if (!wm0010->pll_running) { | ||
609 | xfer->t.speed_hz = wm0010->sysclk / 6; | ||
610 | } else { | ||
611 | xfer->t.speed_hz = wm0010->max_spi_freq; | ||
612 | |||
613 | if (wm0010->board_max_spi_speed && | ||
614 | (wm0010->board_max_spi_speed < wm0010->max_spi_freq)) | ||
615 | xfer->t.speed_hz = wm0010->board_max_spi_speed; | ||
616 | } | ||
617 | |||
618 | /* Store max usable spi frequency for later use */ | ||
619 | wm0010->max_spi_freq = xfer->t.speed_hz; | ||
620 | |||
621 | spi_message_add_tail(&xfer->t, &xfer->m); | ||
622 | |||
623 | offset += ((rec->length) + 8); | ||
624 | rec = (void *)&rec->data[rec->length]; | ||
625 | |||
626 | if (offset >= fw->size) { | ||
627 | dev_dbg(codec->dev, "All transfers scheduled\n"); | ||
628 | xfer->done = &done; | ||
629 | } | ||
630 | |||
631 | ret = spi_async(spi, &xfer->m); | ||
632 | if (ret != 0) { | ||
633 | dev_err(codec->dev, "Write failed: %d\n", ret); | ||
634 | goto abort; | ||
635 | } | ||
636 | |||
637 | if (wm0010->boot_failed) | ||
638 | goto abort; | ||
639 | } | ||
640 | |||
641 | wait_for_completion(&done); | ||
642 | 731 | ||
643 | spin_lock_irqsave(&wm0010->irq_lock, flags); | 732 | spin_lock_irqsave(&wm0010->irq_lock, flags); |
644 | wm0010->state = WM0010_FIRMWARE; | 733 | wm0010->state = WM0010_FIRMWARE; |
@@ -646,17 +735,6 @@ static int wm0010_boot(struct snd_soc_codec *codec) | |||
646 | 735 | ||
647 | mutex_unlock(&wm0010->lock); | 736 | mutex_unlock(&wm0010->lock); |
648 | 737 | ||
649 | release_firmware(fw); | ||
650 | |||
651 | while (!list_empty(&xfer_list)) { | ||
652 | xfer = list_first_entry(&xfer_list, struct wm0010_boot_xfer, | ||
653 | list); | ||
654 | kfree(xfer->t.rx_buf); | ||
655 | kfree(xfer->t.tx_buf); | ||
656 | list_del(&xfer->list); | ||
657 | kfree(xfer); | ||
658 | } | ||
659 | |||
660 | return 0; | 738 | return 0; |
661 | 739 | ||
662 | abort: | 740 | abort: |
@@ -784,7 +862,6 @@ static irqreturn_t wm0010_irq(int irq, void *data) | |||
784 | struct wm0010_priv *wm0010 = data; | 862 | struct wm0010_priv *wm0010 = data; |
785 | 863 | ||
786 | switch (wm0010->state) { | 864 | switch (wm0010->state) { |
787 | case WM0010_POWER_OFF: | ||
788 | case WM0010_OUT_OF_RESET: | 865 | case WM0010_OUT_OF_RESET: |
789 | case WM0010_BOOTROM: | 866 | case WM0010_BOOTROM: |
790 | case WM0010_STAGE2: | 867 | case WM0010_STAGE2: |
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index 683dc43b1d87..02750ab020de 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c | |||
@@ -646,7 +646,7 @@ static const struct snd_kcontrol_new wm2000_controls[] = { | |||
646 | static int wm2000_anc_power_event(struct snd_soc_dapm_widget *w, | 646 | static int wm2000_anc_power_event(struct snd_soc_dapm_widget *w, |
647 | struct snd_kcontrol *kcontrol, int event) | 647 | struct snd_kcontrol *kcontrol, int event) |
648 | { | 648 | { |
649 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 649 | struct snd_soc_codec *codec = w->codec; |
650 | struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); | 650 | struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); |
651 | 651 | ||
652 | if (SND_SOC_DAPM_EVENT_ON(event)) | 652 | if (SND_SOC_DAPM_EVENT_ON(event)) |
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c index eab64a193989..ff45b02a9dff 100644 --- a/sound/soc/codecs/wm2200.c +++ b/sound/soc/codecs/wm2200.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
17 | #include <linux/pm.h> | 17 | #include <linux/pm.h> |
18 | #include <linux/firmware.h> | ||
18 | #include <linux/gcd.h> | 19 | #include <linux/gcd.h> |
19 | #include <linux/gpio.h> | 20 | #include <linux/gpio.h> |
20 | #include <linux/i2c.h> | 21 | #include <linux/i2c.h> |
@@ -32,6 +33,40 @@ | |||
32 | #include <sound/wm2200.h> | 33 | #include <sound/wm2200.h> |
33 | 34 | ||
34 | #include "wm2200.h" | 35 | #include "wm2200.h" |
36 | #include "wmfw.h" | ||
37 | #include "wm_adsp.h" | ||
38 | |||
39 | #define WM2200_DSP_CONTROL_1 0x00 | ||
40 | #define WM2200_DSP_CONTROL_2 0x02 | ||
41 | #define WM2200_DSP_CONTROL_3 0x03 | ||
42 | #define WM2200_DSP_CONTROL_4 0x04 | ||
43 | #define WM2200_DSP_CONTROL_5 0x06 | ||
44 | #define WM2200_DSP_CONTROL_6 0x07 | ||
45 | #define WM2200_DSP_CONTROL_7 0x08 | ||
46 | #define WM2200_DSP_CONTROL_8 0x09 | ||
47 | #define WM2200_DSP_CONTROL_9 0x0A | ||
48 | #define WM2200_DSP_CONTROL_10 0x0B | ||
49 | #define WM2200_DSP_CONTROL_11 0x0C | ||
50 | #define WM2200_DSP_CONTROL_12 0x0D | ||
51 | #define WM2200_DSP_CONTROL_13 0x0F | ||
52 | #define WM2200_DSP_CONTROL_14 0x10 | ||
53 | #define WM2200_DSP_CONTROL_15 0x11 | ||
54 | #define WM2200_DSP_CONTROL_16 0x12 | ||
55 | #define WM2200_DSP_CONTROL_17 0x13 | ||
56 | #define WM2200_DSP_CONTROL_18 0x14 | ||
57 | #define WM2200_DSP_CONTROL_19 0x16 | ||
58 | #define WM2200_DSP_CONTROL_20 0x17 | ||
59 | #define WM2200_DSP_CONTROL_21 0x18 | ||
60 | #define WM2200_DSP_CONTROL_22 0x1A | ||
61 | #define WM2200_DSP_CONTROL_23 0x1B | ||
62 | #define WM2200_DSP_CONTROL_24 0x1C | ||
63 | #define WM2200_DSP_CONTROL_25 0x1E | ||
64 | #define WM2200_DSP_CONTROL_26 0x20 | ||
65 | #define WM2200_DSP_CONTROL_27 0x21 | ||
66 | #define WM2200_DSP_CONTROL_28 0x22 | ||
67 | #define WM2200_DSP_CONTROL_29 0x23 | ||
68 | #define WM2200_DSP_CONTROL_30 0x24 | ||
69 | #define WM2200_DSP_CONTROL_31 0x26 | ||
35 | 70 | ||
36 | /* The code assumes DCVDD is generated internally */ | 71 | /* The code assumes DCVDD is generated internally */ |
37 | #define WM2200_NUM_CORE_SUPPLIES 2 | 72 | #define WM2200_NUM_CORE_SUPPLIES 2 |
@@ -49,6 +84,7 @@ struct wm2200_fll { | |||
49 | 84 | ||
50 | /* codec private data */ | 85 | /* codec private data */ |
51 | struct wm2200_priv { | 86 | struct wm2200_priv { |
87 | struct wm_adsp dsp[2]; | ||
52 | struct regmap *regmap; | 88 | struct regmap *regmap; |
53 | struct device *dev; | 89 | struct device *dev; |
54 | struct snd_soc_codec *codec; | 90 | struct snd_soc_codec *codec; |
@@ -64,6 +100,72 @@ struct wm2200_priv { | |||
64 | int sysclk; | 100 | int sysclk; |
65 | }; | 101 | }; |
66 | 102 | ||
103 | #define WM2200_DSP_RANGE_BASE (WM2200_MAX_REGISTER + 1) | ||
104 | #define WM2200_DSP_SPACING 12288 | ||
105 | |||
106 | #define WM2200_DSP1_DM_BASE (WM2200_DSP_RANGE_BASE + (0 * WM2200_DSP_SPACING)) | ||
107 | #define WM2200_DSP1_PM_BASE (WM2200_DSP_RANGE_BASE + (1 * WM2200_DSP_SPACING)) | ||
108 | #define WM2200_DSP1_ZM_BASE (WM2200_DSP_RANGE_BASE + (2 * WM2200_DSP_SPACING)) | ||
109 | #define WM2200_DSP2_DM_BASE (WM2200_DSP_RANGE_BASE + (3 * WM2200_DSP_SPACING)) | ||
110 | #define WM2200_DSP2_PM_BASE (WM2200_DSP_RANGE_BASE + (4 * WM2200_DSP_SPACING)) | ||
111 | #define WM2200_DSP2_ZM_BASE (WM2200_DSP_RANGE_BASE + (5 * WM2200_DSP_SPACING)) | ||
112 | |||
113 | static const struct regmap_range_cfg wm2200_ranges[] = { | ||
114 | { .name = "DSP1DM", .range_min = WM2200_DSP1_DM_BASE, | ||
115 | .range_max = WM2200_DSP1_DM_BASE + 12287, | ||
116 | .selector_reg = WM2200_DSP1_CONTROL_3, | ||
117 | .selector_mask = WM2200_DSP1_PAGE_BASE_DM_0_MASK, | ||
118 | .selector_shift = WM2200_DSP1_PAGE_BASE_DM_0_SHIFT, | ||
119 | .window_start = WM2200_DSP1_DM_0, .window_len = 2048, }, | ||
120 | |||
121 | { .name = "DSP1PM", .range_min = WM2200_DSP1_PM_BASE, | ||
122 | .range_max = WM2200_DSP1_PM_BASE + 12287, | ||
123 | .selector_reg = WM2200_DSP1_CONTROL_2, | ||
124 | .selector_mask = WM2200_DSP1_PAGE_BASE_PM_0_MASK, | ||
125 | .selector_shift = WM2200_DSP1_PAGE_BASE_PM_0_SHIFT, | ||
126 | .window_start = WM2200_DSP1_PM_0, .window_len = 768, }, | ||
127 | |||
128 | { .name = "DSP1ZM", .range_min = WM2200_DSP1_ZM_BASE, | ||
129 | .range_max = WM2200_DSP1_ZM_BASE + 2047, | ||
130 | .selector_reg = WM2200_DSP1_CONTROL_4, | ||
131 | .selector_mask = WM2200_DSP1_PAGE_BASE_ZM_0_MASK, | ||
132 | .selector_shift = WM2200_DSP1_PAGE_BASE_ZM_0_SHIFT, | ||
133 | .window_start = WM2200_DSP1_ZM_0, .window_len = 1024, }, | ||
134 | |||
135 | { .name = "DSP2DM", .range_min = WM2200_DSP2_DM_BASE, | ||
136 | .range_max = WM2200_DSP2_DM_BASE + 4095, | ||
137 | .selector_reg = WM2200_DSP2_CONTROL_3, | ||
138 | .selector_mask = WM2200_DSP2_PAGE_BASE_DM_0_MASK, | ||
139 | .selector_shift = WM2200_DSP2_PAGE_BASE_DM_0_SHIFT, | ||
140 | .window_start = WM2200_DSP2_DM_0, .window_len = 2048, }, | ||
141 | |||
142 | { .name = "DSP2PM", .range_min = WM2200_DSP2_PM_BASE, | ||
143 | .range_max = WM2200_DSP2_PM_BASE + 11287, | ||
144 | .selector_reg = WM2200_DSP2_CONTROL_2, | ||
145 | .selector_mask = WM2200_DSP2_PAGE_BASE_PM_0_MASK, | ||
146 | .selector_shift = WM2200_DSP2_PAGE_BASE_PM_0_SHIFT, | ||
147 | .window_start = WM2200_DSP2_PM_0, .window_len = 768, }, | ||
148 | |||
149 | { .name = "DSP2ZM", .range_min = WM2200_DSP2_ZM_BASE, | ||
150 | .range_max = WM2200_DSP2_ZM_BASE + 2047, | ||
151 | .selector_reg = WM2200_DSP2_CONTROL_4, | ||
152 | .selector_mask = WM2200_DSP2_PAGE_BASE_ZM_0_MASK, | ||
153 | .selector_shift = WM2200_DSP2_PAGE_BASE_ZM_0_SHIFT, | ||
154 | .window_start = WM2200_DSP2_ZM_0, .window_len = 1024, }, | ||
155 | }; | ||
156 | |||
157 | static const struct wm_adsp_region wm2200_dsp1_regions[] = { | ||
158 | { .type = WMFW_ADSP1_PM, .base = WM2200_DSP1_PM_BASE }, | ||
159 | { .type = WMFW_ADSP1_DM, .base = WM2200_DSP1_DM_BASE }, | ||
160 | { .type = WMFW_ADSP1_ZM, .base = WM2200_DSP1_ZM_BASE }, | ||
161 | }; | ||
162 | |||
163 | static const struct wm_adsp_region wm2200_dsp2_regions[] = { | ||
164 | { .type = WMFW_ADSP1_PM, .base = WM2200_DSP2_PM_BASE }, | ||
165 | { .type = WMFW_ADSP1_DM, .base = WM2200_DSP2_DM_BASE }, | ||
166 | { .type = WMFW_ADSP1_ZM, .base = WM2200_DSP2_ZM_BASE }, | ||
167 | }; | ||
168 | |||
67 | static struct reg_default wm2200_reg_defaults[] = { | 169 | static struct reg_default wm2200_reg_defaults[] = { |
68 | { 0x000B, 0x0000 }, /* R11 - Tone Generator 1 */ | 170 | { 0x000B, 0x0000 }, /* R11 - Tone Generator 1 */ |
69 | { 0x0102, 0x0000 }, /* R258 - Clocking 3 */ | 171 | { 0x0102, 0x0000 }, /* R258 - Clocking 3 */ |
@@ -407,6 +509,16 @@ static struct reg_default wm2200_reg_defaults[] = { | |||
407 | 509 | ||
408 | static bool wm2200_volatile_register(struct device *dev, unsigned int reg) | 510 | static bool wm2200_volatile_register(struct device *dev, unsigned int reg) |
409 | { | 511 | { |
512 | int i; | ||
513 | |||
514 | for (i = 0; i < ARRAY_SIZE(wm2200_ranges); i++) | ||
515 | if ((reg >= wm2200_ranges[i].window_start && | ||
516 | reg <= wm2200_ranges[i].window_start + | ||
517 | wm2200_ranges[i].window_len) || | ||
518 | (reg >= wm2200_ranges[i].range_min && | ||
519 | reg <= wm2200_ranges[i].range_max)) | ||
520 | return true; | ||
521 | |||
410 | switch (reg) { | 522 | switch (reg) { |
411 | case WM2200_SOFTWARE_RESET: | 523 | case WM2200_SOFTWARE_RESET: |
412 | case WM2200_DEVICE_REVISION: | 524 | case WM2200_DEVICE_REVISION: |
@@ -423,6 +535,16 @@ static bool wm2200_volatile_register(struct device *dev, unsigned int reg) | |||
423 | 535 | ||
424 | static bool wm2200_readable_register(struct device *dev, unsigned int reg) | 536 | static bool wm2200_readable_register(struct device *dev, unsigned int reg) |
425 | { | 537 | { |
538 | int i; | ||
539 | |||
540 | for (i = 0; i < ARRAY_SIZE(wm2200_ranges); i++) | ||
541 | if ((reg >= wm2200_ranges[i].window_start && | ||
542 | reg <= wm2200_ranges[i].window_start + | ||
543 | wm2200_ranges[i].window_len) || | ||
544 | (reg >= wm2200_ranges[i].range_min && | ||
545 | reg <= wm2200_ranges[i].range_max)) | ||
546 | return true; | ||
547 | |||
426 | switch (reg) { | 548 | switch (reg) { |
427 | case WM2200_SOFTWARE_RESET: | 549 | case WM2200_SOFTWARE_RESET: |
428 | case WM2200_DEVICE_REVISION: | 550 | case WM2200_DEVICE_REVISION: |
@@ -880,7 +1002,7 @@ static DECLARE_TLV_DB_SCALE(out_tlv, -6400, 100, 0); | |||
880 | static const char *wm2200_mixer_texts[] = { | 1002 | static const char *wm2200_mixer_texts[] = { |
881 | "None", | 1003 | "None", |
882 | "Tone Generator", | 1004 | "Tone Generator", |
883 | "AEC loopback", | 1005 | "AEC Loopback", |
884 | "IN1L", | 1006 | "IN1L", |
885 | "IN1R", | 1007 | "IN1R", |
886 | "IN2L", | 1008 | "IN2L", |
@@ -976,6 +1098,20 @@ static int wm2200_mixer_values[] = { | |||
976 | static WM2200_MUX_CTL_DECL(name##_in3); \ | 1098 | static WM2200_MUX_CTL_DECL(name##_in3); \ |
977 | static WM2200_MUX_CTL_DECL(name##_in4) | 1099 | static WM2200_MUX_CTL_DECL(name##_in4) |
978 | 1100 | ||
1101 | #define WM2200_DSP_ENUMS(name, base_reg) \ | ||
1102 | static WM2200_MUX_ENUM_DECL(name##_aux1_enum, base_reg); \ | ||
1103 | static WM2200_MUX_ENUM_DECL(name##_aux2_enum, base_reg + 1); \ | ||
1104 | static WM2200_MUX_ENUM_DECL(name##_aux3_enum, base_reg + 2); \ | ||
1105 | static WM2200_MUX_ENUM_DECL(name##_aux4_enum, base_reg + 3); \ | ||
1106 | static WM2200_MUX_ENUM_DECL(name##_aux5_enum, base_reg + 4); \ | ||
1107 | static WM2200_MUX_ENUM_DECL(name##_aux6_enum, base_reg + 5); \ | ||
1108 | static WM2200_MUX_CTL_DECL(name##_aux1); \ | ||
1109 | static WM2200_MUX_CTL_DECL(name##_aux2); \ | ||
1110 | static WM2200_MUX_CTL_DECL(name##_aux3); \ | ||
1111 | static WM2200_MUX_CTL_DECL(name##_aux4); \ | ||
1112 | static WM2200_MUX_CTL_DECL(name##_aux5); \ | ||
1113 | static WM2200_MUX_CTL_DECL(name##_aux6); | ||
1114 | |||
979 | static const struct snd_kcontrol_new wm2200_snd_controls[] = { | 1115 | static const struct snd_kcontrol_new wm2200_snd_controls[] = { |
980 | SOC_SINGLE("IN1 High Performance Switch", WM2200_IN1L_CONTROL, | 1116 | SOC_SINGLE("IN1 High Performance Switch", WM2200_IN1L_CONTROL, |
981 | WM2200_IN1_OSR_SHIFT, 1, 0), | 1117 | WM2200_IN1_OSR_SHIFT, 1, 0), |
@@ -1051,6 +1187,9 @@ WM2200_MIXER_ENUMS(DSP1R, WM2200_DSP1RMIX_INPUT_1_SOURCE); | |||
1051 | WM2200_MIXER_ENUMS(DSP2L, WM2200_DSP2LMIX_INPUT_1_SOURCE); | 1187 | WM2200_MIXER_ENUMS(DSP2L, WM2200_DSP2LMIX_INPUT_1_SOURCE); |
1052 | WM2200_MIXER_ENUMS(DSP2R, WM2200_DSP2RMIX_INPUT_1_SOURCE); | 1188 | WM2200_MIXER_ENUMS(DSP2R, WM2200_DSP2RMIX_INPUT_1_SOURCE); |
1053 | 1189 | ||
1190 | WM2200_DSP_ENUMS(DSP1, WM2200_DSP1AUX1MIX_INPUT_1_SOURCE); | ||
1191 | WM2200_DSP_ENUMS(DSP2, WM2200_DSP2AUX1MIX_INPUT_1_SOURCE); | ||
1192 | |||
1054 | WM2200_MIXER_ENUMS(LHPF1, WM2200_LHPF1MIX_INPUT_1_SOURCE); | 1193 | WM2200_MIXER_ENUMS(LHPF1, WM2200_LHPF1MIX_INPUT_1_SOURCE); |
1055 | WM2200_MIXER_ENUMS(LHPF2, WM2200_LHPF2MIX_INPUT_1_SOURCE); | 1194 | WM2200_MIXER_ENUMS(LHPF2, WM2200_LHPF2MIX_INPUT_1_SOURCE); |
1056 | 1195 | ||
@@ -1064,8 +1203,19 @@ WM2200_MIXER_ENUMS(LHPF2, WM2200_LHPF2MIX_INPUT_1_SOURCE); | |||
1064 | WM2200_MUX(name_str " Input 4", &name##_in4_mux), \ | 1203 | WM2200_MUX(name_str " Input 4", &name##_in4_mux), \ |
1065 | SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0) | 1204 | SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0) |
1066 | 1205 | ||
1206 | #define WM2200_DSP_WIDGETS(name, name_str) \ | ||
1207 | WM2200_MIXER_WIDGETS(name##L, name_str "L"), \ | ||
1208 | WM2200_MIXER_WIDGETS(name##R, name_str "R"), \ | ||
1209 | WM2200_MUX(name_str " Aux 1", &name##_aux1_mux), \ | ||
1210 | WM2200_MUX(name_str " Aux 2", &name##_aux2_mux), \ | ||
1211 | WM2200_MUX(name_str " Aux 3", &name##_aux3_mux), \ | ||
1212 | WM2200_MUX(name_str " Aux 4", &name##_aux4_mux), \ | ||
1213 | WM2200_MUX(name_str " Aux 5", &name##_aux5_mux), \ | ||
1214 | WM2200_MUX(name_str " Aux 6", &name##_aux6_mux) | ||
1215 | |||
1067 | #define WM2200_MIXER_INPUT_ROUTES(name) \ | 1216 | #define WM2200_MIXER_INPUT_ROUTES(name) \ |
1068 | { name, "Tone Generator", "Tone Generator" }, \ | 1217 | { name, "Tone Generator", "Tone Generator" }, \ |
1218 | { name, "AEC Loopback", "AEC Loopback" }, \ | ||
1069 | { name, "IN1L", "IN1L PGA" }, \ | 1219 | { name, "IN1L", "IN1L PGA" }, \ |
1070 | { name, "IN1R", "IN1R PGA" }, \ | 1220 | { name, "IN1R", "IN1R PGA" }, \ |
1071 | { name, "IN2L", "IN2L PGA" }, \ | 1221 | { name, "IN2L", "IN2L PGA" }, \ |
@@ -1106,6 +1256,33 @@ WM2200_MIXER_ENUMS(LHPF2, WM2200_LHPF2MIX_INPUT_1_SOURCE); | |||
1106 | WM2200_MIXER_INPUT_ROUTES(name " Input 3"), \ | 1256 | WM2200_MIXER_INPUT_ROUTES(name " Input 3"), \ |
1107 | WM2200_MIXER_INPUT_ROUTES(name " Input 4") | 1257 | WM2200_MIXER_INPUT_ROUTES(name " Input 4") |
1108 | 1258 | ||
1259 | #define WM2200_DSP_AUX_ROUTES(name) \ | ||
1260 | { name, NULL, name " Aux 1" }, \ | ||
1261 | { name, NULL, name " Aux 2" }, \ | ||
1262 | { name, NULL, name " Aux 3" }, \ | ||
1263 | { name, NULL, name " Aux 4" }, \ | ||
1264 | { name, NULL, name " Aux 5" }, \ | ||
1265 | { name, NULL, name " Aux 6" }, \ | ||
1266 | WM2200_MIXER_INPUT_ROUTES(name " Aux 1"), \ | ||
1267 | WM2200_MIXER_INPUT_ROUTES(name " Aux 2"), \ | ||
1268 | WM2200_MIXER_INPUT_ROUTES(name " Aux 3"), \ | ||
1269 | WM2200_MIXER_INPUT_ROUTES(name " Aux 4"), \ | ||
1270 | WM2200_MIXER_INPUT_ROUTES(name " Aux 5"), \ | ||
1271 | WM2200_MIXER_INPUT_ROUTES(name " Aux 6") | ||
1272 | |||
1273 | static const char *wm2200_aec_loopback_texts[] = { | ||
1274 | "OUT1L", "OUT1R", "OUT2L", "OUT2R", | ||
1275 | }; | ||
1276 | |||
1277 | static const struct soc_enum wm2200_aec_loopback = | ||
1278 | SOC_ENUM_SINGLE(WM2200_DAC_AEC_CONTROL_1, | ||
1279 | WM2200_AEC_LOOPBACK_SRC_SHIFT, | ||
1280 | ARRAY_SIZE(wm2200_aec_loopback_texts), | ||
1281 | wm2200_aec_loopback_texts); | ||
1282 | |||
1283 | static const struct snd_kcontrol_new wm2200_aec_loopback_mux = | ||
1284 | SOC_DAPM_ENUM("AEC Loopback", wm2200_aec_loopback); | ||
1285 | |||
1109 | static const struct snd_soc_dapm_widget wm2200_dapm_widgets[] = { | 1286 | static const struct snd_soc_dapm_widget wm2200_dapm_widgets[] = { |
1110 | SND_SOC_DAPM_SUPPLY("SYSCLK", WM2200_CLOCKING_3, WM2200_SYSCLK_ENA_SHIFT, 0, | 1287 | SND_SOC_DAPM_SUPPLY("SYSCLK", WM2200_CLOCKING_3, WM2200_SYSCLK_ENA_SHIFT, 0, |
1111 | NULL, 0), | 1288 | NULL, 0), |
@@ -1165,8 +1342,8 @@ SND_SOC_DAPM_PGA("LHPF1", WM2200_HPLPF1_1, WM2200_LHPF1_ENA_SHIFT, 0, | |||
1165 | SND_SOC_DAPM_PGA("LHPF2", WM2200_HPLPF2_1, WM2200_LHPF2_ENA_SHIFT, 0, | 1342 | SND_SOC_DAPM_PGA("LHPF2", WM2200_HPLPF2_1, WM2200_LHPF2_ENA_SHIFT, 0, |
1166 | NULL, 0), | 1343 | NULL, 0), |
1167 | 1344 | ||
1168 | SND_SOC_DAPM_PGA_E("DSP1", SND_SOC_NOPM, 0, 0, NULL, 0, NULL, 0), | 1345 | WM_ADSP1("DSP1", 0), |
1169 | SND_SOC_DAPM_PGA_E("DSP2", SND_SOC_NOPM, 1, 0, NULL, 0, NULL, 0), | 1346 | WM_ADSP1("DSP2", 1), |
1170 | 1347 | ||
1171 | SND_SOC_DAPM_AIF_OUT("AIF1TX1", "Capture", 0, | 1348 | SND_SOC_DAPM_AIF_OUT("AIF1TX1", "Capture", 0, |
1172 | WM2200_AUDIO_IF_1_22, WM2200_AIF1TX1_ENA_SHIFT, 0), | 1349 | WM2200_AUDIO_IF_1_22, WM2200_AIF1TX1_ENA_SHIFT, 0), |
@@ -1181,6 +1358,9 @@ SND_SOC_DAPM_AIF_OUT("AIF1TX5", "Capture", 4, | |||
1181 | SND_SOC_DAPM_AIF_OUT("AIF1TX6", "Capture", 5, | 1358 | SND_SOC_DAPM_AIF_OUT("AIF1TX6", "Capture", 5, |
1182 | WM2200_AUDIO_IF_1_22, WM2200_AIF1TX6_ENA_SHIFT, 0), | 1359 | WM2200_AUDIO_IF_1_22, WM2200_AIF1TX6_ENA_SHIFT, 0), |
1183 | 1360 | ||
1361 | SND_SOC_DAPM_MUX("AEC Loopback", WM2200_DAC_AEC_CONTROL_1, | ||
1362 | WM2200_AEC_LOOPBACK_ENA_SHIFT, 0, &wm2200_aec_loopback_mux), | ||
1363 | |||
1184 | SND_SOC_DAPM_PGA_S("OUT1L", 0, WM2200_OUTPUT_ENABLES, | 1364 | SND_SOC_DAPM_PGA_S("OUT1L", 0, WM2200_OUTPUT_ENABLES, |
1185 | WM2200_OUT1L_ENA_SHIFT, 0, NULL, 0), | 1365 | WM2200_OUT1L_ENA_SHIFT, 0, NULL, 0), |
1186 | SND_SOC_DAPM_PGA_S("OUT1R", 0, WM2200_OUTPUT_ENABLES, | 1366 | SND_SOC_DAPM_PGA_S("OUT1R", 0, WM2200_OUTPUT_ENABLES, |
@@ -1231,10 +1411,8 @@ WM2200_MIXER_WIDGETS(EQR, "EQR"), | |||
1231 | WM2200_MIXER_WIDGETS(LHPF1, "LHPF1"), | 1411 | WM2200_MIXER_WIDGETS(LHPF1, "LHPF1"), |
1232 | WM2200_MIXER_WIDGETS(LHPF2, "LHPF2"), | 1412 | WM2200_MIXER_WIDGETS(LHPF2, "LHPF2"), |
1233 | 1413 | ||
1234 | WM2200_MIXER_WIDGETS(DSP1L, "DSP1L"), | 1414 | WM2200_DSP_WIDGETS(DSP1, "DSP1"), |
1235 | WM2200_MIXER_WIDGETS(DSP1R, "DSP1R"), | 1415 | WM2200_DSP_WIDGETS(DSP2, "DSP2"), |
1236 | WM2200_MIXER_WIDGETS(DSP2L, "DSP2L"), | ||
1237 | WM2200_MIXER_WIDGETS(DSP2R, "DSP2R"), | ||
1238 | 1416 | ||
1239 | WM2200_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"), | 1417 | WM2200_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"), |
1240 | WM2200_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"), | 1418 | WM2200_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"), |
@@ -1326,11 +1504,19 @@ static const struct snd_soc_dapm_route wm2200_dapm_routes[] = { | |||
1326 | { "SPK", NULL, "OUT2L" }, | 1504 | { "SPK", NULL, "OUT2L" }, |
1327 | { "SPK", NULL, "OUT2R" }, | 1505 | { "SPK", NULL, "OUT2R" }, |
1328 | 1506 | ||
1507 | { "AEC Loopback", "OUT1L", "OUT1L" }, | ||
1508 | { "AEC Loopback", "OUT1R", "OUT1R" }, | ||
1509 | { "AEC Loopback", "OUT2L", "OUT2L" }, | ||
1510 | { "AEC Loopback", "OUT2R", "OUT2R" }, | ||
1511 | |||
1329 | WM2200_MIXER_ROUTES("DSP1", "DSP1L"), | 1512 | WM2200_MIXER_ROUTES("DSP1", "DSP1L"), |
1330 | WM2200_MIXER_ROUTES("DSP1", "DSP1R"), | 1513 | WM2200_MIXER_ROUTES("DSP1", "DSP1R"), |
1331 | WM2200_MIXER_ROUTES("DSP2", "DSP2L"), | 1514 | WM2200_MIXER_ROUTES("DSP2", "DSP2L"), |
1332 | WM2200_MIXER_ROUTES("DSP2", "DSP2R"), | 1515 | WM2200_MIXER_ROUTES("DSP2", "DSP2R"), |
1333 | 1516 | ||
1517 | WM2200_DSP_AUX_ROUTES("DSP1"), | ||
1518 | WM2200_DSP_AUX_ROUTES("DSP2"), | ||
1519 | |||
1334 | WM2200_MIXER_ROUTES("OUT1L", "OUT1L"), | 1520 | WM2200_MIXER_ROUTES("OUT1L", "OUT1L"), |
1335 | WM2200_MIXER_ROUTES("OUT1R", "OUT1R"), | 1521 | WM2200_MIXER_ROUTES("OUT1R", "OUT1R"), |
1336 | WM2200_MIXER_ROUTES("OUT2L", "OUT2L"), | 1522 | WM2200_MIXER_ROUTES("OUT2L", "OUT2L"), |
@@ -1968,12 +2154,15 @@ static const struct regmap_config wm2200_regmap = { | |||
1968 | .reg_bits = 16, | 2154 | .reg_bits = 16, |
1969 | .val_bits = 16, | 2155 | .val_bits = 16, |
1970 | 2156 | ||
1971 | .max_register = WM2200_MAX_REGISTER, | 2157 | .max_register = WM2200_MAX_REGISTER + (ARRAY_SIZE(wm2200_ranges) * |
2158 | WM2200_DSP_SPACING), | ||
1972 | .reg_defaults = wm2200_reg_defaults, | 2159 | .reg_defaults = wm2200_reg_defaults, |
1973 | .num_reg_defaults = ARRAY_SIZE(wm2200_reg_defaults), | 2160 | .num_reg_defaults = ARRAY_SIZE(wm2200_reg_defaults), |
1974 | .volatile_reg = wm2200_volatile_register, | 2161 | .volatile_reg = wm2200_volatile_register, |
1975 | .readable_reg = wm2200_readable_register, | 2162 | .readable_reg = wm2200_readable_register, |
1976 | .cache_type = REGCACHE_RBTREE, | 2163 | .cache_type = REGCACHE_RBTREE, |
2164 | .ranges = wm2200_ranges, | ||
2165 | .num_ranges = ARRAY_SIZE(wm2200_ranges), | ||
1977 | }; | 2166 | }; |
1978 | 2167 | ||
1979 | static const unsigned int wm2200_dig_vu[] = { | 2168 | static const unsigned int wm2200_dig_vu[] = { |
@@ -2011,14 +2200,30 @@ static __devinit int wm2200_i2c_probe(struct i2c_client *i2c, | |||
2011 | wm2200->dev = &i2c->dev; | 2200 | wm2200->dev = &i2c->dev; |
2012 | init_completion(&wm2200->fll_lock); | 2201 | init_completion(&wm2200->fll_lock); |
2013 | 2202 | ||
2014 | wm2200->regmap = regmap_init_i2c(i2c, &wm2200_regmap); | 2203 | wm2200->regmap = devm_regmap_init_i2c(i2c, &wm2200_regmap); |
2015 | if (IS_ERR(wm2200->regmap)) { | 2204 | if (IS_ERR(wm2200->regmap)) { |
2016 | ret = PTR_ERR(wm2200->regmap); | 2205 | ret = PTR_ERR(wm2200->regmap); |
2017 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | 2206 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", |
2018 | ret); | 2207 | ret); |
2019 | goto err; | 2208 | return ret; |
2209 | } | ||
2210 | |||
2211 | for (i = 0; i < 2; i++) { | ||
2212 | wm2200->dsp[i].type = WMFW_ADSP1; | ||
2213 | wm2200->dsp[i].part = "wm2200"; | ||
2214 | wm2200->dsp[i].num = i + 1; | ||
2215 | wm2200->dsp[i].dev = &i2c->dev; | ||
2216 | wm2200->dsp[i].regmap = wm2200->regmap; | ||
2020 | } | 2217 | } |
2021 | 2218 | ||
2219 | wm2200->dsp[0].base = WM2200_DSP1_CONTROL_1; | ||
2220 | wm2200->dsp[0].mem = wm2200_dsp1_regions; | ||
2221 | wm2200->dsp[0].num_mems = ARRAY_SIZE(wm2200_dsp1_regions); | ||
2222 | |||
2223 | wm2200->dsp[1].base = WM2200_DSP2_CONTROL_1; | ||
2224 | wm2200->dsp[1].mem = wm2200_dsp2_regions; | ||
2225 | wm2200->dsp[1].num_mems = ARRAY_SIZE(wm2200_dsp2_regions); | ||
2226 | |||
2022 | if (pdata) | 2227 | if (pdata) |
2023 | wm2200->pdata = *pdata; | 2228 | wm2200->pdata = *pdata; |
2024 | 2229 | ||
@@ -2027,12 +2232,13 @@ static __devinit int wm2200_i2c_probe(struct i2c_client *i2c, | |||
2027 | for (i = 0; i < ARRAY_SIZE(wm2200->core_supplies); i++) | 2232 | for (i = 0; i < ARRAY_SIZE(wm2200->core_supplies); i++) |
2028 | wm2200->core_supplies[i].supply = wm2200_core_supply_names[i]; | 2233 | wm2200->core_supplies[i].supply = wm2200_core_supply_names[i]; |
2029 | 2234 | ||
2030 | ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm2200->core_supplies), | 2235 | ret = devm_regulator_bulk_get(&i2c->dev, |
2031 | wm2200->core_supplies); | 2236 | ARRAY_SIZE(wm2200->core_supplies), |
2237 | wm2200->core_supplies); | ||
2032 | if (ret != 0) { | 2238 | if (ret != 0) { |
2033 | dev_err(&i2c->dev, "Failed to request core supplies: %d\n", | 2239 | dev_err(&i2c->dev, "Failed to request core supplies: %d\n", |
2034 | ret); | 2240 | ret); |
2035 | goto err_regmap; | 2241 | return ret; |
2036 | } | 2242 | } |
2037 | 2243 | ||
2038 | ret = regulator_bulk_enable(ARRAY_SIZE(wm2200->core_supplies), | 2244 | ret = regulator_bulk_enable(ARRAY_SIZE(wm2200->core_supplies), |
@@ -2040,12 +2246,13 @@ static __devinit int wm2200_i2c_probe(struct i2c_client *i2c, | |||
2040 | if (ret != 0) { | 2246 | if (ret != 0) { |
2041 | dev_err(&i2c->dev, "Failed to enable core supplies: %d\n", | 2247 | dev_err(&i2c->dev, "Failed to enable core supplies: %d\n", |
2042 | ret); | 2248 | ret); |
2043 | goto err_core; | 2249 | return ret; |
2044 | } | 2250 | } |
2045 | 2251 | ||
2046 | if (wm2200->pdata.ldo_ena) { | 2252 | if (wm2200->pdata.ldo_ena) { |
2047 | ret = gpio_request_one(wm2200->pdata.ldo_ena, | 2253 | ret = devm_gpio_request_one(&i2c->dev, wm2200->pdata.ldo_ena, |
2048 | GPIOF_OUT_INIT_HIGH, "WM2200 LDOENA"); | 2254 | GPIOF_OUT_INIT_HIGH, |
2255 | "WM2200 LDOENA"); | ||
2049 | if (ret < 0) { | 2256 | if (ret < 0) { |
2050 | dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n", | 2257 | dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n", |
2051 | wm2200->pdata.ldo_ena, ret); | 2258 | wm2200->pdata.ldo_ena, ret); |
@@ -2055,8 +2262,9 @@ static __devinit int wm2200_i2c_probe(struct i2c_client *i2c, | |||
2055 | } | 2262 | } |
2056 | 2263 | ||
2057 | if (wm2200->pdata.reset) { | 2264 | if (wm2200->pdata.reset) { |
2058 | ret = gpio_request_one(wm2200->pdata.reset, | 2265 | ret = devm_gpio_request_one(&i2c->dev, wm2200->pdata.reset, |
2059 | GPIOF_OUT_INIT_HIGH, "WM2200 /RESET"); | 2266 | GPIOF_OUT_INIT_HIGH, |
2267 | "WM2200 /RESET"); | ||
2060 | if (ret < 0) { | 2268 | if (ret < 0) { |
2061 | dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n", | 2269 | dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n", |
2062 | wm2200->pdata.reset, ret); | 2270 | wm2200->pdata.reset, ret); |
@@ -2166,24 +2374,14 @@ static __devinit int wm2200_i2c_probe(struct i2c_client *i2c, | |||
2166 | err_pm_runtime: | 2374 | err_pm_runtime: |
2167 | pm_runtime_disable(&i2c->dev); | 2375 | pm_runtime_disable(&i2c->dev); |
2168 | err_reset: | 2376 | err_reset: |
2169 | if (wm2200->pdata.reset) { | 2377 | if (wm2200->pdata.reset) |
2170 | gpio_set_value_cansleep(wm2200->pdata.reset, 0); | 2378 | gpio_set_value_cansleep(wm2200->pdata.reset, 0); |
2171 | gpio_free(wm2200->pdata.reset); | ||
2172 | } | ||
2173 | err_ldo: | 2379 | err_ldo: |
2174 | if (wm2200->pdata.ldo_ena) { | 2380 | if (wm2200->pdata.ldo_ena) |
2175 | gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0); | 2381 | gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0); |
2176 | gpio_free(wm2200->pdata.ldo_ena); | ||
2177 | } | ||
2178 | err_enable: | 2382 | err_enable: |
2179 | regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies), | 2383 | regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies), |
2180 | wm2200->core_supplies); | 2384 | wm2200->core_supplies); |
2181 | err_core: | ||
2182 | regulator_bulk_free(ARRAY_SIZE(wm2200->core_supplies), | ||
2183 | wm2200->core_supplies); | ||
2184 | err_regmap: | ||
2185 | regmap_exit(wm2200->regmap); | ||
2186 | err: | ||
2187 | return ret; | 2385 | return ret; |
2188 | } | 2386 | } |
2189 | 2387 | ||
@@ -2194,17 +2392,10 @@ static __devexit int wm2200_i2c_remove(struct i2c_client *i2c) | |||
2194 | snd_soc_unregister_codec(&i2c->dev); | 2392 | snd_soc_unregister_codec(&i2c->dev); |
2195 | if (i2c->irq) | 2393 | if (i2c->irq) |
2196 | free_irq(i2c->irq, wm2200); | 2394 | free_irq(i2c->irq, wm2200); |
2197 | if (wm2200->pdata.reset) { | 2395 | if (wm2200->pdata.reset) |
2198 | gpio_set_value_cansleep(wm2200->pdata.reset, 0); | 2396 | gpio_set_value_cansleep(wm2200->pdata.reset, 0); |
2199 | gpio_free(wm2200->pdata.reset); | 2397 | if (wm2200->pdata.ldo_ena) |
2200 | } | ||
2201 | if (wm2200->pdata.ldo_ena) { | ||
2202 | gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0); | 2398 | gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0); |
2203 | gpio_free(wm2200->pdata.ldo_ena); | ||
2204 | } | ||
2205 | regulator_bulk_free(ARRAY_SIZE(wm2200->core_supplies), | ||
2206 | wm2200->core_supplies); | ||
2207 | regmap_exit(wm2200->regmap); | ||
2208 | 2399 | ||
2209 | return 0; | 2400 | return 0; |
2210 | } | 2401 | } |
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index 7f567585832e..9f57996ff272 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c | |||
@@ -1233,7 +1233,7 @@ static const struct snd_soc_dapm_route wm5100_dapm_routes[] = { | |||
1233 | { "PWM2", NULL, "PWM2 Driver" }, | 1233 | { "PWM2", NULL, "PWM2 Driver" }, |
1234 | }; | 1234 | }; |
1235 | 1235 | ||
1236 | static const __devinitconst struct reg_default wm5100_reva_patches[] = { | 1236 | static const struct reg_default wm5100_reva_patches[] = { |
1237 | { WM5100_AUDIO_IF_1_10, 0 }, | 1237 | { WM5100_AUDIO_IF_1_10, 0 }, |
1238 | { WM5100_AUDIO_IF_1_11, 1 }, | 1238 | { WM5100_AUDIO_IF_1_11, 1 }, |
1239 | { WM5100_AUDIO_IF_1_12, 2 }, | 1239 | { WM5100_AUDIO_IF_1_12, 2 }, |
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 7394e73fa43c..53793b1849f7 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c | |||
@@ -31,6 +31,7 @@ | |||
31 | 31 | ||
32 | #include "arizona.h" | 32 | #include "arizona.h" |
33 | #include "wm5102.h" | 33 | #include "wm5102.h" |
34 | #include "wm_adsp.h" | ||
34 | 35 | ||
35 | struct wm5102_priv { | 36 | struct wm5102_priv { |
36 | struct arizona_priv core; | 37 | struct arizona_priv core; |
@@ -42,6 +43,13 @@ static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); | |||
42 | static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0); | 43 | static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0); |
43 | static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0); | 44 | static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0); |
44 | 45 | ||
46 | static const struct wm_adsp_region wm5102_dsp1_regions[] = { | ||
47 | { .type = WMFW_ADSP2_PM, .base = 0x100000 }, | ||
48 | { .type = WMFW_ADSP2_ZM, .base = 0x180000 }, | ||
49 | { .type = WMFW_ADSP2_XM, .base = 0x190000 }, | ||
50 | { .type = WMFW_ADSP2_YM, .base = 0x1a8000 }, | ||
51 | }; | ||
52 | |||
45 | static const struct reg_default wm5102_sysclk_reva_patch[] = { | 53 | static const struct reg_default wm5102_sysclk_reva_patch[] = { |
46 | { 0x3000, 0x2225 }, | 54 | { 0x3000, 0x2225 }, |
47 | { 0x3001, 0x3a03 }, | 55 | { 0x3001, 0x3a03 }, |
@@ -687,6 +695,9 @@ ARIZONA_MIXER_CONTROLS("LHPF2", ARIZONA_HPLP2MIX_INPUT_1_SOURCE), | |||
687 | ARIZONA_MIXER_CONTROLS("LHPF3", ARIZONA_HPLP3MIX_INPUT_1_SOURCE), | 695 | ARIZONA_MIXER_CONTROLS("LHPF3", ARIZONA_HPLP3MIX_INPUT_1_SOURCE), |
688 | ARIZONA_MIXER_CONTROLS("LHPF4", ARIZONA_HPLP4MIX_INPUT_1_SOURCE), | 696 | ARIZONA_MIXER_CONTROLS("LHPF4", ARIZONA_HPLP4MIX_INPUT_1_SOURCE), |
689 | 697 | ||
698 | ARIZONA_MIXER_CONTROLS("DSP1L", ARIZONA_DSP1LMIX_INPUT_1_SOURCE), | ||
699 | ARIZONA_MIXER_CONTROLS("DSP1R", ARIZONA_DSP1RMIX_INPUT_1_SOURCE), | ||
700 | |||
690 | SOC_ENUM("LHPF1 Mode", arizona_lhpf1_mode), | 701 | SOC_ENUM("LHPF1 Mode", arizona_lhpf1_mode), |
691 | SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode), | 702 | SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode), |
692 | SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), | 703 | SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), |
@@ -708,14 +719,6 @@ ARIZONA_MIXER_CONTROLS("SPKOUTR", ARIZONA_OUT4RMIX_INPUT_1_SOURCE), | |||
708 | ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE), | 719 | ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE), |
709 | ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE), | 720 | ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE), |
710 | 721 | ||
711 | SOC_SINGLE("HPOUT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_1L, | ||
712 | ARIZONA_OUT1_OSR_SHIFT, 1, 0), | ||
713 | SOC_SINGLE("OUT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_2L, | ||
714 | ARIZONA_OUT2_OSR_SHIFT, 1, 0), | ||
715 | SOC_SINGLE("EPOUT High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_3L, | ||
716 | ARIZONA_OUT3_OSR_SHIFT, 1, 0), | ||
717 | SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L, | ||
718 | ARIZONA_OUT4_OSR_SHIFT, 1, 0), | ||
719 | SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L, | 722 | SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L, |
720 | ARIZONA_OUT5_OSR_SHIFT, 1, 0), | 723 | ARIZONA_OUT5_OSR_SHIFT, 1, 0), |
721 | 724 | ||
@@ -745,17 +748,6 @@ SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L, | |||
745 | ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT, | 748 | ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT, |
746 | 0xbf, 0, digital_tlv), | 749 | 0xbf, 0, digital_tlv), |
747 | 750 | ||
748 | SOC_DOUBLE_R_RANGE_TLV("HPOUT1 Volume", ARIZONA_OUTPUT_PATH_CONFIG_1L, | ||
749 | ARIZONA_OUTPUT_PATH_CONFIG_1R, | ||
750 | ARIZONA_OUT1L_PGA_VOL_SHIFT, | ||
751 | 0x34, 0x40, 0, ana_tlv), | ||
752 | SOC_DOUBLE_R_RANGE_TLV("OUT2 Volume", ARIZONA_OUTPUT_PATH_CONFIG_2L, | ||
753 | ARIZONA_OUTPUT_PATH_CONFIG_2R, | ||
754 | ARIZONA_OUT2L_PGA_VOL_SHIFT, | ||
755 | 0x34, 0x40, 0, ana_tlv), | ||
756 | SOC_SINGLE_RANGE_TLV("EPOUT Volume", ARIZONA_OUTPUT_PATH_CONFIG_3L, | ||
757 | ARIZONA_OUT3L_PGA_VOL_SHIFT, 0x34, 0x40, 0, ana_tlv), | ||
758 | |||
759 | SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT, | 751 | SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT, |
760 | ARIZONA_SPK1R_MUTE_SHIFT, 1, 1), | 752 | ARIZONA_SPK1R_MUTE_SHIFT, 1, 1), |
761 | 753 | ||
@@ -819,11 +811,15 @@ ARIZONA_MIXER_ENUMS(AIF2TX2, ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE); | |||
819 | ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE); | 811 | ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE); |
820 | ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE); | 812 | ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE); |
821 | 813 | ||
822 | ARIZONA_MIXER_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE); | 814 | ARIZONA_MUX_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE); |
823 | ARIZONA_MIXER_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE); | 815 | ARIZONA_MUX_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE); |
824 | ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); | 816 | ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); |
825 | ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); | 817 | ARIZONA_MUX_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); |
818 | |||
819 | ARIZONA_MIXER_ENUMS(DSP1L, ARIZONA_DSP1LMIX_INPUT_1_SOURCE); | ||
820 | ARIZONA_MIXER_ENUMS(DSP1R, ARIZONA_DSP1RMIX_INPUT_1_SOURCE); | ||
826 | 821 | ||
822 | ARIZONA_DSP_AUX_ENUMS(DSP1, ARIZONA_DSP1AUX1MIX_INPUT_1_SOURCE); | ||
827 | 823 | ||
828 | static const char *wm5102_aec_loopback_texts[] = { | 824 | static const char *wm5102_aec_loopback_texts[] = { |
829 | "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "EPOUT", | 825 | "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "EPOUT", |
@@ -864,6 +860,7 @@ SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0, 0), | |||
864 | 860 | ||
865 | SND_SOC_DAPM_SIGGEN("TONE"), | 861 | SND_SOC_DAPM_SIGGEN("TONE"), |
866 | SND_SOC_DAPM_SIGGEN("NOISE"), | 862 | SND_SOC_DAPM_SIGGEN("NOISE"), |
863 | SND_SOC_DAPM_SIGGEN("HAPTICS"), | ||
867 | 864 | ||
868 | SND_SOC_DAPM_INPUT("IN1L"), | 865 | SND_SOC_DAPM_INPUT("IN1L"), |
869 | SND_SOC_DAPM_INPUT("IN1R"), | 866 | SND_SOC_DAPM_INPUT("IN1R"), |
@@ -894,9 +891,9 @@ SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT, | |||
894 | SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1, | 891 | SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1, |
895 | ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), | 892 | ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), |
896 | SND_SOC_DAPM_SUPPLY("MICBIAS2", ARIZONA_MIC_BIAS_CTRL_2, | 893 | SND_SOC_DAPM_SUPPLY("MICBIAS2", ARIZONA_MIC_BIAS_CTRL_2, |
897 | ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), | 894 | ARIZONA_MICB2_ENA_SHIFT, 0, NULL, 0), |
898 | SND_SOC_DAPM_SUPPLY("MICBIAS3", ARIZONA_MIC_BIAS_CTRL_3, | 895 | SND_SOC_DAPM_SUPPLY("MICBIAS3", ARIZONA_MIC_BIAS_CTRL_3, |
899 | ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), | 896 | ARIZONA_MICB3_ENA_SHIFT, 0, NULL, 0), |
900 | 897 | ||
901 | SND_SOC_DAPM_PGA("Noise Generator", ARIZONA_COMFORT_NOISE_GENERATOR, | 898 | SND_SOC_DAPM_PGA("Noise Generator", ARIZONA_COMFORT_NOISE_GENERATOR, |
902 | ARIZONA_NOISE_GEN_ENA_SHIFT, 0, NULL, 0), | 899 | ARIZONA_NOISE_GEN_ENA_SHIFT, 0, NULL, 0), |
@@ -996,6 +993,8 @@ SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0, | |||
996 | SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0, | 993 | SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0, |
997 | ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0), | 994 | ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0), |
998 | 995 | ||
996 | ARIZONA_DSP_WIDGETS(DSP1, "DSP1"), | ||
997 | |||
999 | SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, | 998 | SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, |
1000 | ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5102_aec_loopback_mux), | 999 | ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5102_aec_loopback_mux), |
1001 | 1000 | ||
@@ -1071,10 +1070,12 @@ ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"), | |||
1071 | ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"), | 1070 | ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"), |
1072 | ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"), | 1071 | ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"), |
1073 | 1072 | ||
1074 | ARIZONA_MIXER_WIDGETS(ASRC1L, "ASRC1L"), | 1073 | ARIZONA_MUX_WIDGETS(ASRC1L, "ASRC1L"), |
1075 | ARIZONA_MIXER_WIDGETS(ASRC1R, "ASRC1R"), | 1074 | ARIZONA_MUX_WIDGETS(ASRC1R, "ASRC1R"), |
1076 | ARIZONA_MIXER_WIDGETS(ASRC2L, "ASRC2L"), | 1075 | ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"), |
1077 | ARIZONA_MIXER_WIDGETS(ASRC2R, "ASRC2R"), | 1076 | ARIZONA_MUX_WIDGETS(ASRC2R, "ASRC2R"), |
1077 | |||
1078 | WM_ADSP2("DSP1", 0), | ||
1078 | 1079 | ||
1079 | SND_SOC_DAPM_OUTPUT("HPOUT1L"), | 1080 | SND_SOC_DAPM_OUTPUT("HPOUT1L"), |
1080 | SND_SOC_DAPM_OUTPUT("HPOUT1R"), | 1081 | SND_SOC_DAPM_OUTPUT("HPOUT1R"), |
@@ -1094,6 +1095,7 @@ SND_SOC_DAPM_OUTPUT("SPKDAT1R"), | |||
1094 | { name, "Noise Generator", "Noise Generator" }, \ | 1095 | { name, "Noise Generator", "Noise Generator" }, \ |
1095 | { name, "Tone Generator 1", "Tone Generator 1" }, \ | 1096 | { name, "Tone Generator 1", "Tone Generator 1" }, \ |
1096 | { name, "Tone Generator 2", "Tone Generator 2" }, \ | 1097 | { name, "Tone Generator 2", "Tone Generator 2" }, \ |
1098 | { name, "Haptics", "HAPTICS" }, \ | ||
1097 | { name, "AEC", "AEC Loopback" }, \ | 1099 | { name, "AEC", "AEC Loopback" }, \ |
1098 | { name, "IN1L", "IN1L PGA" }, \ | 1100 | { name, "IN1L", "IN1L PGA" }, \ |
1099 | { name, "IN1R", "IN1R PGA" }, \ | 1101 | { name, "IN1R", "IN1R PGA" }, \ |
@@ -1127,7 +1129,13 @@ SND_SOC_DAPM_OUTPUT("SPKDAT1R"), | |||
1127 | { name, "ASRC1L", "ASRC1L" }, \ | 1129 | { name, "ASRC1L", "ASRC1L" }, \ |
1128 | { name, "ASRC1R", "ASRC1R" }, \ | 1130 | { name, "ASRC1R", "ASRC1R" }, \ |
1129 | { name, "ASRC2L", "ASRC2L" }, \ | 1131 | { name, "ASRC2L", "ASRC2L" }, \ |
1130 | { name, "ASRC2R", "ASRC2R" } | 1132 | { name, "ASRC2R", "ASRC2R" }, \ |
1133 | { name, "DSP1.1", "DSP1" }, \ | ||
1134 | { name, "DSP1.2", "DSP1" }, \ | ||
1135 | { name, "DSP1.3", "DSP1" }, \ | ||
1136 | { name, "DSP1.4", "DSP1" }, \ | ||
1137 | { name, "DSP1.5", "DSP1" }, \ | ||
1138 | { name, "DSP1.6", "DSP1" } | ||
1131 | 1139 | ||
1132 | static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { | 1140 | static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { |
1133 | { "AIF2 Capture", NULL, "DBVDD2" }, | 1141 | { "AIF2 Capture", NULL, "DBVDD2" }, |
@@ -1213,6 +1221,11 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { | |||
1213 | { "IN3L PGA", NULL, "IN3L" }, | 1221 | { "IN3L PGA", NULL, "IN3L" }, |
1214 | { "IN3R PGA", NULL, "IN3R" }, | 1222 | { "IN3R PGA", NULL, "IN3R" }, |
1215 | 1223 | ||
1224 | { "ASRC1L", NULL, "ASRC1L Input" }, | ||
1225 | { "ASRC1R", NULL, "ASRC1R Input" }, | ||
1226 | { "ASRC2L", NULL, "ASRC2L Input" }, | ||
1227 | { "ASRC2R", NULL, "ASRC2R Input" }, | ||
1228 | |||
1216 | ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"), | 1229 | ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"), |
1217 | ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"), | 1230 | ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"), |
1218 | ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"), | 1231 | ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"), |
@@ -1255,10 +1268,12 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { | |||
1255 | ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"), | 1268 | ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"), |
1256 | ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"), | 1269 | ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"), |
1257 | 1270 | ||
1258 | ARIZONA_MIXER_ROUTES("ASRC1L", "ASRC1L"), | 1271 | ARIZONA_MUX_ROUTES("ASRC1L"), |
1259 | ARIZONA_MIXER_ROUTES("ASRC1R", "ASRC1R"), | 1272 | ARIZONA_MUX_ROUTES("ASRC1R"), |
1260 | ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"), | 1273 | ARIZONA_MUX_ROUTES("ASRC2L"), |
1261 | ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"), | 1274 | ARIZONA_MUX_ROUTES("ASRC2R"), |
1275 | |||
1276 | ARIZONA_DSP_ROUTES("DSP1"), | ||
1262 | 1277 | ||
1263 | { "AEC Loopback", "HPOUT1L", "OUT1L" }, | 1278 | { "AEC Loopback", "HPOUT1L", "OUT1L" }, |
1264 | { "AEC Loopback", "HPOUT1R", "OUT1R" }, | 1279 | { "AEC Loopback", "HPOUT1R", "OUT1R" }, |
@@ -1377,9 +1392,28 @@ static struct snd_soc_dai_driver wm5102_dai[] = { | |||
1377 | static int wm5102_codec_probe(struct snd_soc_codec *codec) | 1392 | static int wm5102_codec_probe(struct snd_soc_codec *codec) |
1378 | { | 1393 | { |
1379 | struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); | 1394 | struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); |
1395 | int ret; | ||
1380 | 1396 | ||
1381 | codec->control_data = priv->core.arizona->regmap; | 1397 | codec->control_data = priv->core.arizona->regmap; |
1382 | return snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP); | 1398 | |
1399 | ret = snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP); | ||
1400 | if (ret != 0) | ||
1401 | return ret; | ||
1402 | |||
1403 | snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS"); | ||
1404 | |||
1405 | priv->core.arizona->dapm = &codec->dapm; | ||
1406 | |||
1407 | return 0; | ||
1408 | } | ||
1409 | |||
1410 | static int wm5102_codec_remove(struct snd_soc_codec *codec) | ||
1411 | { | ||
1412 | struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
1413 | |||
1414 | priv->core.arizona->dapm = NULL; | ||
1415 | |||
1416 | return 0; | ||
1383 | } | 1417 | } |
1384 | 1418 | ||
1385 | #define WM5102_DIG_VU 0x0200 | 1419 | #define WM5102_DIG_VU 0x0200 |
@@ -1406,6 +1440,7 @@ static unsigned int wm5102_digital_vu[] = { | |||
1406 | 1440 | ||
1407 | static struct snd_soc_codec_driver soc_codec_dev_wm5102 = { | 1441 | static struct snd_soc_codec_driver soc_codec_dev_wm5102 = { |
1408 | .probe = wm5102_codec_probe, | 1442 | .probe = wm5102_codec_probe, |
1443 | .remove = wm5102_codec_remove, | ||
1409 | 1444 | ||
1410 | .idle_bias_off = true, | 1445 | .idle_bias_off = true, |
1411 | 1446 | ||
@@ -1424,7 +1459,7 @@ static int __devinit wm5102_probe(struct platform_device *pdev) | |||
1424 | { | 1459 | { |
1425 | struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); | 1460 | struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); |
1426 | struct wm5102_priv *wm5102; | 1461 | struct wm5102_priv *wm5102; |
1427 | int i; | 1462 | int i, ret; |
1428 | 1463 | ||
1429 | wm5102 = devm_kzalloc(&pdev->dev, sizeof(struct wm5102_priv), | 1464 | wm5102 = devm_kzalloc(&pdev->dev, sizeof(struct wm5102_priv), |
1430 | GFP_KERNEL); | 1465 | GFP_KERNEL); |
@@ -1434,6 +1469,19 @@ static int __devinit wm5102_probe(struct platform_device *pdev) | |||
1434 | 1469 | ||
1435 | wm5102->core.arizona = arizona; | 1470 | wm5102->core.arizona = arizona; |
1436 | 1471 | ||
1472 | wm5102->core.adsp[0].part = "wm5102"; | ||
1473 | wm5102->core.adsp[0].num = 1; | ||
1474 | wm5102->core.adsp[0].type = WMFW_ADSP2; | ||
1475 | wm5102->core.adsp[0].base = ARIZONA_DSP1_CONTROL_1; | ||
1476 | wm5102->core.adsp[0].dev = arizona->dev; | ||
1477 | wm5102->core.adsp[0].regmap = arizona->regmap; | ||
1478 | wm5102->core.adsp[0].mem = wm5102_dsp1_regions; | ||
1479 | wm5102->core.adsp[0].num_mems = ARRAY_SIZE(wm5102_dsp1_regions); | ||
1480 | |||
1481 | ret = wm_adsp2_init(&wm5102->core.adsp[0], true); | ||
1482 | if (ret != 0) | ||
1483 | return ret; | ||
1484 | |||
1437 | for (i = 0; i < ARRAY_SIZE(wm5102->fll); i++) | 1485 | for (i = 0; i < ARRAY_SIZE(wm5102->fll); i++) |
1438 | wm5102->fll[i].vco_mult = 1; | 1486 | wm5102->fll[i].vco_mult = 1; |
1439 | 1487 | ||
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 9211e4192f71..2a075ad00d5b 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c | |||
@@ -308,10 +308,10 @@ ARIZONA_MIXER_ENUMS(AIF2TX2, ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE); | |||
308 | ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE); | 308 | ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE); |
309 | ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE); | 309 | ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE); |
310 | 310 | ||
311 | ARIZONA_MIXER_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE); | 311 | ARIZONA_MUX_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE); |
312 | ARIZONA_MIXER_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE); | 312 | ARIZONA_MUX_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE); |
313 | ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); | 313 | ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); |
314 | ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); | 314 | ARIZONA_MUX_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); |
315 | 315 | ||
316 | static const char *wm5110_aec_loopback_texts[] = { | 316 | static const char *wm5110_aec_loopback_texts[] = { |
317 | "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "HPOUT3L", "HPOUT3R", | 317 | "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "HPOUT3L", "HPOUT3R", |
@@ -352,6 +352,7 @@ SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0, 0), | |||
352 | 352 | ||
353 | SND_SOC_DAPM_SIGGEN("TONE"), | 353 | SND_SOC_DAPM_SIGGEN("TONE"), |
354 | SND_SOC_DAPM_SIGGEN("NOISE"), | 354 | SND_SOC_DAPM_SIGGEN("NOISE"), |
355 | SND_SOC_DAPM_SIGGEN("HAPTICS"), | ||
355 | 356 | ||
356 | SND_SOC_DAPM_INPUT("IN1L"), | 357 | SND_SOC_DAPM_INPUT("IN1L"), |
357 | SND_SOC_DAPM_INPUT("IN1R"), | 358 | SND_SOC_DAPM_INPUT("IN1R"), |
@@ -585,10 +586,10 @@ ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"), | |||
585 | ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"), | 586 | ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"), |
586 | ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"), | 587 | ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"), |
587 | 588 | ||
588 | ARIZONA_MIXER_WIDGETS(ASRC1L, "ASRC1L"), | 589 | ARIZONA_MUX_WIDGETS(ASRC1L, "ASRC1L"), |
589 | ARIZONA_MIXER_WIDGETS(ASRC1R, "ASRC1R"), | 590 | ARIZONA_MUX_WIDGETS(ASRC1R, "ASRC1R"), |
590 | ARIZONA_MIXER_WIDGETS(ASRC2L, "ASRC2L"), | 591 | ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"), |
591 | ARIZONA_MIXER_WIDGETS(ASRC2R, "ASRC2R"), | 592 | ARIZONA_MUX_WIDGETS(ASRC2R, "ASRC2R"), |
592 | 593 | ||
593 | SND_SOC_DAPM_OUTPUT("HPOUT1L"), | 594 | SND_SOC_DAPM_OUTPUT("HPOUT1L"), |
594 | SND_SOC_DAPM_OUTPUT("HPOUT1R"), | 595 | SND_SOC_DAPM_OUTPUT("HPOUT1R"), |
@@ -610,6 +611,7 @@ SND_SOC_DAPM_OUTPUT("SPKDAT2R"), | |||
610 | { name, "Noise Generator", "Noise Generator" }, \ | 611 | { name, "Noise Generator", "Noise Generator" }, \ |
611 | { name, "Tone Generator 1", "Tone Generator 1" }, \ | 612 | { name, "Tone Generator 1", "Tone Generator 1" }, \ |
612 | { name, "Tone Generator 2", "Tone Generator 2" }, \ | 613 | { name, "Tone Generator 2", "Tone Generator 2" }, \ |
614 | { name, "Haptics", "HAPTICS" }, \ | ||
613 | { name, "AEC", "AEC Loopback" }, \ | 615 | { name, "AEC", "AEC Loopback" }, \ |
614 | { name, "IN1L", "IN1L PGA" }, \ | 616 | { name, "IN1L", "IN1L PGA" }, \ |
615 | { name, "IN1R", "IN1R PGA" }, \ | 617 | { name, "IN1R", "IN1R PGA" }, \ |
@@ -786,10 +788,10 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = { | |||
786 | ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"), | 788 | ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"), |
787 | ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"), | 789 | ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"), |
788 | 790 | ||
789 | ARIZONA_MIXER_ROUTES("ASRC1L", "ASRC1L"), | 791 | ARIZONA_MUX_ROUTES("ASRC1L"), |
790 | ARIZONA_MIXER_ROUTES("ASRC1R", "ASRC1R"), | 792 | ARIZONA_MUX_ROUTES("ASRC1R"), |
791 | ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"), | 793 | ARIZONA_MUX_ROUTES("ASRC2L"), |
792 | ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"), | 794 | ARIZONA_MUX_ROUTES("ASRC2R"), |
793 | 795 | ||
794 | { "HPOUT1L", NULL, "OUT1L" }, | 796 | { "HPOUT1L", NULL, "OUT1L" }, |
795 | { "HPOUT1R", NULL, "OUT1R" }, | 797 | { "HPOUT1R", NULL, "OUT1R" }, |
@@ -902,9 +904,29 @@ static struct snd_soc_dai_driver wm5110_dai[] = { | |||
902 | static int wm5110_codec_probe(struct snd_soc_codec *codec) | 904 | static int wm5110_codec_probe(struct snd_soc_codec *codec) |
903 | { | 905 | { |
904 | struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec); | 906 | struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec); |
907 | int ret; | ||
905 | 908 | ||
906 | codec->control_data = priv->core.arizona->regmap; | 909 | codec->control_data = priv->core.arizona->regmap; |
907 | return snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP); | 910 | priv->core.arizona->dapm = &codec->dapm; |
911 | |||
912 | ret = snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP); | ||
913 | if (ret != 0) | ||
914 | return ret; | ||
915 | |||
916 | snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS"); | ||
917 | |||
918 | priv->core.arizona->dapm = &codec->dapm; | ||
919 | |||
920 | return 0; | ||
921 | } | ||
922 | |||
923 | static int wm5110_codec_remove(struct snd_soc_codec *codec) | ||
924 | { | ||
925 | struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
926 | |||
927 | priv->core.arizona->dapm = NULL; | ||
928 | |||
929 | return 0; | ||
908 | } | 930 | } |
909 | 931 | ||
910 | #define WM5110_DIG_VU 0x0200 | 932 | #define WM5110_DIG_VU 0x0200 |
@@ -935,6 +957,7 @@ static unsigned int wm5110_digital_vu[] = { | |||
935 | 957 | ||
936 | static struct snd_soc_codec_driver soc_codec_dev_wm5110 = { | 958 | static struct snd_soc_codec_driver soc_codec_dev_wm5110 = { |
937 | .probe = wm5110_codec_probe, | 959 | .probe = wm5110_codec_probe, |
960 | .remove = wm5110_codec_remove, | ||
938 | 961 | ||
939 | .idle_bias_off = true, | 962 | .idle_bias_off = true, |
940 | 963 | ||
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index a4cae060bf26..32b8f0852f6e 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c | |||
@@ -1500,7 +1500,7 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec) | |||
1500 | for (i = 0; i < ARRAY_SIZE(supply_names); i++) | 1500 | for (i = 0; i < ARRAY_SIZE(supply_names); i++) |
1501 | priv->supplies[i].supply = supply_names[i]; | 1501 | priv->supplies[i].supply = supply_names[i]; |
1502 | 1502 | ||
1503 | ret = regulator_bulk_get(wm8350->dev, ARRAY_SIZE(priv->supplies), | 1503 | ret = devm_regulator_bulk_get(wm8350->dev, ARRAY_SIZE(priv->supplies), |
1504 | priv->supplies); | 1504 | priv->supplies); |
1505 | if (ret != 0) | 1505 | if (ret != 0) |
1506 | return ret; | 1506 | return ret; |
@@ -1607,8 +1607,6 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec) | |||
1607 | 1607 | ||
1608 | wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); | 1608 | wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); |
1609 | 1609 | ||
1610 | regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies); | ||
1611 | |||
1612 | return 0; | 1610 | return 0; |
1613 | } | 1611 | } |
1614 | 1612 | ||
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index 5d277a915f81..262c44082eb0 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c | |||
@@ -1373,7 +1373,7 @@ static int wm8400_codec_probe(struct snd_soc_codec *codec) | |||
1373 | codec->control_data = priv->wm8400 = wm8400; | 1373 | codec->control_data = priv->wm8400 = wm8400; |
1374 | priv->codec = codec; | 1374 | priv->codec = codec; |
1375 | 1375 | ||
1376 | ret = regulator_bulk_get(wm8400->dev, | 1376 | ret = devm_regulator_bulk_get(wm8400->dev, |
1377 | ARRAY_SIZE(power), &power[0]); | 1377 | ARRAY_SIZE(power), &power[0]); |
1378 | if (ret != 0) { | 1378 | if (ret != 0) { |
1379 | dev_err(codec->dev, "Failed to get regulators: %d\n", ret); | 1379 | dev_err(codec->dev, "Failed to get regulators: %d\n", ret); |
@@ -1398,15 +1398,9 @@ static int wm8400_codec_probe(struct snd_soc_codec *codec) | |||
1398 | snd_soc_write(codec, WM8400_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); | 1398 | snd_soc_write(codec, WM8400_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); |
1399 | snd_soc_write(codec, WM8400_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); | 1399 | snd_soc_write(codec, WM8400_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); |
1400 | 1400 | ||
1401 | if (!schedule_work(&priv->work)) { | 1401 | if (!schedule_work(&priv->work)) |
1402 | ret = -EINVAL; | 1402 | return -EINVAL; |
1403 | goto err_regulator; | ||
1404 | } | ||
1405 | return 0; | 1403 | return 0; |
1406 | |||
1407 | err_regulator: | ||
1408 | regulator_bulk_free(ARRAY_SIZE(power), power); | ||
1409 | return ret; | ||
1410 | } | 1404 | } |
1411 | 1405 | ||
1412 | static int wm8400_codec_remove(struct snd_soc_codec *codec) | 1406 | static int wm8400_codec_remove(struct snd_soc_codec *codec) |
@@ -1417,8 +1411,6 @@ static int wm8400_codec_remove(struct snd_soc_codec *codec) | |||
1417 | snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, | 1411 | snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, |
1418 | reg & (~WM8400_CODEC_ENA)); | 1412 | reg & (~WM8400_CODEC_ENA)); |
1419 | 1413 | ||
1420 | regulator_bulk_free(ARRAY_SIZE(power), power); | ||
1421 | |||
1422 | return 0; | 1414 | return 0; |
1423 | } | 1415 | } |
1424 | 1416 | ||
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index c12a54e72e89..923e7e1f6704 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c | |||
@@ -608,10 +608,7 @@ static int wm8510_probe(struct snd_soc_codec *codec) | |||
608 | /* power down chip */ | 608 | /* power down chip */ |
609 | static int wm8510_remove(struct snd_soc_codec *codec) | 609 | static int wm8510_remove(struct snd_soc_codec *codec) |
610 | { | 610 | { |
611 | struct wm8510_priv *wm8510 = snd_soc_codec_get_drvdata(codec); | ||
612 | |||
613 | wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF); | 611 | wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF); |
614 | kfree(wm8510); | ||
615 | return 0; | 612 | return 0; |
616 | } | 613 | } |
617 | 614 | ||
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c index 4281a0802138..99b8ebe93424 100644 --- a/sound/soc/codecs/wm8741.c +++ b/sound/soc/codecs/wm8741.c | |||
@@ -522,7 +522,7 @@ static int wm8741_i2c_probe(struct i2c_client *i2c, | |||
522 | return ret; | 522 | return ret; |
523 | } | 523 | } |
524 | 524 | ||
525 | wm8741->regmap = regmap_init_i2c(i2c, &wm8741_regmap); | 525 | wm8741->regmap = devm_regmap_init_i2c(i2c, &wm8741_regmap); |
526 | if (IS_ERR(wm8741->regmap)) { | 526 | if (IS_ERR(wm8741->regmap)) { |
527 | ret = PTR_ERR(wm8741->regmap); | 527 | ret = PTR_ERR(wm8741->regmap); |
528 | dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret); | 528 | dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret); |
@@ -582,7 +582,7 @@ static int __devinit wm8741_spi_probe(struct spi_device *spi) | |||
582 | return ret; | 582 | return ret; |
583 | } | 583 | } |
584 | 584 | ||
585 | wm8741->regmap = regmap_init_spi(spi, &wm8741_regmap); | 585 | wm8741->regmap = devm_regmap_init_spi(spi, &wm8741_regmap); |
586 | if (IS_ERR(wm8741->regmap)) { | 586 | if (IS_ERR(wm8741->regmap)) { |
587 | ret = PTR_ERR(wm8741->regmap); | 587 | ret = PTR_ERR(wm8741->regmap); |
588 | dev_err(&spi->dev, "Failed to init regmap: %d\n", ret); | 588 | dev_err(&spi->dev, "Failed to init regmap: %d\n", ret); |
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index 89151ca5e776..7665d68c4558 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/pm.h> | 19 | #include <linux/pm.h> |
20 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
21 | #include <linux/regmap.h> | ||
21 | #include <linux/spi/spi.h> | 22 | #include <linux/spi/spi.h> |
22 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
23 | #include <linux/of_device.h> | 24 | #include <linux/of_device.h> |
@@ -34,24 +35,55 @@ | |||
34 | * We can't read the WM8750 register space when we | 35 | * We can't read the WM8750 register space when we |
35 | * are using 2 wire for device control, so we cache them instead. | 36 | * are using 2 wire for device control, so we cache them instead. |
36 | */ | 37 | */ |
37 | static const u16 wm8750_reg[] = { | 38 | static const struct reg_default wm8750_reg_defaults[] = { |
38 | 0x0097, 0x0097, 0x0079, 0x0079, /* 0 */ | 39 | { 0, 0x0097 }, |
39 | 0x0000, 0x0008, 0x0000, 0x000a, /* 4 */ | 40 | { 1, 0x0097 }, |
40 | 0x0000, 0x0000, 0x00ff, 0x00ff, /* 8 */ | 41 | { 2, 0x0079 }, |
41 | 0x000f, 0x000f, 0x0000, 0x0000, /* 12 */ | 42 | { 3, 0x0079 }, |
42 | 0x0000, 0x007b, 0x0000, 0x0032, /* 16 */ | 43 | { 4, 0x0000 }, |
43 | 0x0000, 0x00c3, 0x00c3, 0x00c0, /* 20 */ | 44 | { 5, 0x0008 }, |
44 | 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */ | 45 | { 6, 0x0000 }, |
45 | 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */ | 46 | { 7, 0x000a }, |
46 | 0x0000, 0x0000, 0x0050, 0x0050, /* 32 */ | 47 | { 8, 0x0000 }, |
47 | 0x0050, 0x0050, 0x0050, 0x0050, /* 36 */ | 48 | { 9, 0x0000 }, |
48 | 0x0079, 0x0079, 0x0079, /* 40 */ | 49 | { 10, 0x00ff }, |
50 | { 11, 0x00ff }, | ||
51 | { 12, 0x000f }, | ||
52 | { 13, 0x000f }, | ||
53 | { 14, 0x0000 }, | ||
54 | { 15, 0x0000 }, | ||
55 | { 16, 0x0000 }, | ||
56 | { 17, 0x007b }, | ||
57 | { 18, 0x0000 }, | ||
58 | { 19, 0x0032 }, | ||
59 | { 20, 0x0000 }, | ||
60 | { 21, 0x00c3 }, | ||
61 | { 22, 0x00c3 }, | ||
62 | { 23, 0x00c0 }, | ||
63 | { 24, 0x0000 }, | ||
64 | { 25, 0x0000 }, | ||
65 | { 26, 0x0000 }, | ||
66 | { 27, 0x0000 }, | ||
67 | { 28, 0x0000 }, | ||
68 | { 29, 0x0000 }, | ||
69 | { 30, 0x0000 }, | ||
70 | { 31, 0x0000 }, | ||
71 | { 32, 0x0000 }, | ||
72 | { 33, 0x0000 }, | ||
73 | { 34, 0x0050 }, | ||
74 | { 35, 0x0050 }, | ||
75 | { 36, 0x0050 }, | ||
76 | { 37, 0x0050 }, | ||
77 | { 38, 0x0050 }, | ||
78 | { 39, 0x0050 }, | ||
79 | { 40, 0x0079 }, | ||
80 | { 41, 0x0079 }, | ||
81 | { 42, 0x0079 }, | ||
49 | }; | 82 | }; |
50 | 83 | ||
51 | /* codec private data */ | 84 | /* codec private data */ |
52 | struct wm8750_priv { | 85 | struct wm8750_priv { |
53 | unsigned int sysclk; | 86 | unsigned int sysclk; |
54 | enum snd_soc_control_type control_type; | ||
55 | }; | 87 | }; |
56 | 88 | ||
57 | #define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0) | 89 | #define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0) |
@@ -668,10 +700,9 @@ static int wm8750_resume(struct snd_soc_codec *codec) | |||
668 | 700 | ||
669 | static int wm8750_probe(struct snd_soc_codec *codec) | 701 | static int wm8750_probe(struct snd_soc_codec *codec) |
670 | { | 702 | { |
671 | struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec); | ||
672 | int ret; | 703 | int ret; |
673 | 704 | ||
674 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8750->control_type); | 705 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); |
675 | if (ret < 0) { | 706 | if (ret < 0) { |
676 | printk(KERN_ERR "wm8750: failed to set cache I/O: %d\n", ret); | 707 | printk(KERN_ERR "wm8750: failed to set cache I/O: %d\n", ret); |
677 | return ret; | 708 | return ret; |
@@ -711,9 +742,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8750 = { | |||
711 | .suspend = wm8750_suspend, | 742 | .suspend = wm8750_suspend, |
712 | .resume = wm8750_resume, | 743 | .resume = wm8750_resume, |
713 | .set_bias_level = wm8750_set_bias_level, | 744 | .set_bias_level = wm8750_set_bias_level, |
714 | .reg_cache_size = ARRAY_SIZE(wm8750_reg), | ||
715 | .reg_word_size = sizeof(u16), | ||
716 | .reg_cache_default = wm8750_reg, | ||
717 | 745 | ||
718 | .controls = wm8750_snd_controls, | 746 | .controls = wm8750_snd_controls, |
719 | .num_controls = ARRAY_SIZE(wm8750_snd_controls), | 747 | .num_controls = ARRAY_SIZE(wm8750_snd_controls), |
@@ -730,10 +758,21 @@ static const struct of_device_id wm8750_of_match[] = { | |||
730 | }; | 758 | }; |
731 | MODULE_DEVICE_TABLE(of, wm8750_of_match); | 759 | MODULE_DEVICE_TABLE(of, wm8750_of_match); |
732 | 760 | ||
761 | static const struct regmap_config wm8750_regmap = { | ||
762 | .reg_bits = 7, | ||
763 | .val_bits = 9, | ||
764 | .max_register = WM8750_MOUTV, | ||
765 | |||
766 | .reg_defaults = wm8750_reg_defaults, | ||
767 | .num_reg_defaults = ARRAY_SIZE(wm8750_reg_defaults), | ||
768 | .cache_type = REGCACHE_RBTREE, | ||
769 | }; | ||
770 | |||
733 | #if defined(CONFIG_SPI_MASTER) | 771 | #if defined(CONFIG_SPI_MASTER) |
734 | static int __devinit wm8750_spi_probe(struct spi_device *spi) | 772 | static int __devinit wm8750_spi_probe(struct spi_device *spi) |
735 | { | 773 | { |
736 | struct wm8750_priv *wm8750; | 774 | struct wm8750_priv *wm8750; |
775 | struct regmap *regmap; | ||
737 | int ret; | 776 | int ret; |
738 | 777 | ||
739 | wm8750 = devm_kzalloc(&spi->dev, sizeof(struct wm8750_priv), | 778 | wm8750 = devm_kzalloc(&spi->dev, sizeof(struct wm8750_priv), |
@@ -741,7 +780,10 @@ static int __devinit wm8750_spi_probe(struct spi_device *spi) | |||
741 | if (wm8750 == NULL) | 780 | if (wm8750 == NULL) |
742 | return -ENOMEM; | 781 | return -ENOMEM; |
743 | 782 | ||
744 | wm8750->control_type = SND_SOC_SPI; | 783 | regmap = devm_regmap_init_spi(spi, &wm8750_regmap); |
784 | if (IS_ERR(regmap)) | ||
785 | return PTR_ERR(regmap); | ||
786 | |||
745 | spi_set_drvdata(spi, wm8750); | 787 | spi_set_drvdata(spi, wm8750); |
746 | 788 | ||
747 | ret = snd_soc_register_codec(&spi->dev, | 789 | ret = snd_soc_register_codec(&spi->dev, |
@@ -779,6 +821,7 @@ static __devinit int wm8750_i2c_probe(struct i2c_client *i2c, | |||
779 | const struct i2c_device_id *id) | 821 | const struct i2c_device_id *id) |
780 | { | 822 | { |
781 | struct wm8750_priv *wm8750; | 823 | struct wm8750_priv *wm8750; |
824 | struct regmap *regmap; | ||
782 | int ret; | 825 | int ret; |
783 | 826 | ||
784 | wm8750 = devm_kzalloc(&i2c->dev, sizeof(struct wm8750_priv), | 827 | wm8750 = devm_kzalloc(&i2c->dev, sizeof(struct wm8750_priv), |
@@ -787,7 +830,10 @@ static __devinit int wm8750_i2c_probe(struct i2c_client *i2c, | |||
787 | return -ENOMEM; | 830 | return -ENOMEM; |
788 | 831 | ||
789 | i2c_set_clientdata(i2c, wm8750); | 832 | i2c_set_clientdata(i2c, wm8750); |
790 | wm8750->control_type = SND_SOC_I2C; | 833 | |
834 | regmap = devm_regmap_init_i2c(i2c, &wm8750_regmap); | ||
835 | if (IS_ERR(regmap)) | ||
836 | return PTR_ERR(regmap); | ||
791 | 837 | ||
792 | ret = snd_soc_register_codec(&i2c->dev, | 838 | ret = snd_soc_register_codec(&i2c->dev, |
793 | &soc_codec_dev_wm8750, &wm8750_dai, 1); | 839 | &soc_codec_dev_wm8750, &wm8750_dai, 1); |
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index 2e4a775ae560..50a5dc7974e1 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c | |||
@@ -1562,36 +1562,25 @@ static int __devinit wm8753_spi_probe(struct spi_device *spi) | |||
1562 | 1562 | ||
1563 | spi_set_drvdata(spi, wm8753); | 1563 | spi_set_drvdata(spi, wm8753); |
1564 | 1564 | ||
1565 | wm8753->regmap = regmap_init_spi(spi, &wm8753_regmap); | 1565 | wm8753->regmap = devm_regmap_init_spi(spi, &wm8753_regmap); |
1566 | if (IS_ERR(wm8753->regmap)) { | 1566 | if (IS_ERR(wm8753->regmap)) { |
1567 | ret = PTR_ERR(wm8753->regmap); | 1567 | ret = PTR_ERR(wm8753->regmap); |
1568 | dev_err(&spi->dev, "Failed to allocate register map: %d\n", | 1568 | dev_err(&spi->dev, "Failed to allocate register map: %d\n", |
1569 | ret); | 1569 | ret); |
1570 | goto err; | 1570 | return ret; |
1571 | } | 1571 | } |
1572 | 1572 | ||
1573 | ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_wm8753, | 1573 | ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_wm8753, |
1574 | wm8753_dai, ARRAY_SIZE(wm8753_dai)); | 1574 | wm8753_dai, ARRAY_SIZE(wm8753_dai)); |
1575 | if (ret != 0) { | 1575 | if (ret != 0) |
1576 | dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret); | 1576 | dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret); |
1577 | goto err_regmap; | ||
1578 | } | ||
1579 | 1577 | ||
1580 | return 0; | ||
1581 | |||
1582 | err_regmap: | ||
1583 | regmap_exit(wm8753->regmap); | ||
1584 | err: | ||
1585 | return ret; | 1578 | return ret; |
1586 | } | 1579 | } |
1587 | 1580 | ||
1588 | static int __devexit wm8753_spi_remove(struct spi_device *spi) | 1581 | static int __devexit wm8753_spi_remove(struct spi_device *spi) |
1589 | { | 1582 | { |
1590 | struct wm8753_priv *wm8753 = spi_get_drvdata(spi); | ||
1591 | |||
1592 | snd_soc_unregister_codec(&spi->dev); | 1583 | snd_soc_unregister_codec(&spi->dev); |
1593 | regmap_exit(wm8753->regmap); | ||
1594 | kfree(wm8753); | ||
1595 | return 0; | 1584 | return 0; |
1596 | } | 1585 | } |
1597 | 1586 | ||
@@ -1620,35 +1609,25 @@ static __devinit int wm8753_i2c_probe(struct i2c_client *i2c, | |||
1620 | 1609 | ||
1621 | i2c_set_clientdata(i2c, wm8753); | 1610 | i2c_set_clientdata(i2c, wm8753); |
1622 | 1611 | ||
1623 | wm8753->regmap = regmap_init_i2c(i2c, &wm8753_regmap); | 1612 | wm8753->regmap = devm_regmap_init_i2c(i2c, &wm8753_regmap); |
1624 | if (IS_ERR(wm8753->regmap)) { | 1613 | if (IS_ERR(wm8753->regmap)) { |
1625 | ret = PTR_ERR(wm8753->regmap); | 1614 | ret = PTR_ERR(wm8753->regmap); |
1626 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | 1615 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", |
1627 | ret); | 1616 | ret); |
1628 | goto err; | 1617 | return ret; |
1629 | } | 1618 | } |
1630 | 1619 | ||
1631 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8753, | 1620 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8753, |
1632 | wm8753_dai, ARRAY_SIZE(wm8753_dai)); | 1621 | wm8753_dai, ARRAY_SIZE(wm8753_dai)); |
1633 | if (ret != 0) { | 1622 | if (ret != 0) |
1634 | dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); | 1623 | dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); |
1635 | goto err_regmap; | ||
1636 | } | ||
1637 | 1624 | ||
1638 | return 0; | ||
1639 | |||
1640 | err_regmap: | ||
1641 | regmap_exit(wm8753->regmap); | ||
1642 | err: | ||
1643 | return ret; | 1625 | return ret; |
1644 | } | 1626 | } |
1645 | 1627 | ||
1646 | static __devexit int wm8753_i2c_remove(struct i2c_client *client) | 1628 | static __devexit int wm8753_i2c_remove(struct i2c_client *client) |
1647 | { | 1629 | { |
1648 | struct wm8753_priv *wm8753 = i2c_get_clientdata(client); | ||
1649 | |||
1650 | snd_soc_unregister_codec(&client->dev); | 1630 | snd_soc_unregister_codec(&client->dev); |
1651 | regmap_exit(wm8753->regmap); | ||
1652 | return 0; | 1631 | return 0; |
1653 | } | 1632 | } |
1654 | 1633 | ||
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c index c7c0034d3966..0b690ba875f8 100644 --- a/sound/soc/codecs/wm8770.c +++ b/sound/soc/codecs/wm8770.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/of_device.h> | 17 | #include <linux/of_device.h> |
18 | #include <linux/pm.h> | 18 | #include <linux/pm.h> |
19 | #include <linux/spi/spi.h> | 19 | #include <linux/spi/spi.h> |
20 | #include <linux/regmap.h> | ||
20 | #include <linux/regulator/consumer.h> | 21 | #include <linux/regulator/consumer.h> |
21 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
22 | #include <sound/core.h> | 23 | #include <sound/core.h> |
@@ -35,19 +36,52 @@ static const char *wm8770_supply_names[WM8770_NUM_SUPPLIES] = { | |||
35 | "DVDD" | 36 | "DVDD" |
36 | }; | 37 | }; |
37 | 38 | ||
38 | static const u16 wm8770_reg_defs[WM8770_CACHEREGNUM] = { | 39 | static const struct reg_default wm8770_reg_defaults[] = { |
39 | 0x7f, 0x7f, 0x7f, 0x7f, | 40 | { 0, 0x7f }, |
40 | 0x7f, 0x7f, 0x7f, 0x7f, | 41 | { 1, 0x7f }, |
41 | 0x7f, 0xff, 0xff, 0xff, | 42 | { 2, 0x7f }, |
42 | 0xff, 0xff, 0xff, 0xff, | 43 | { 3, 0x7f }, |
43 | 0xff, 0xff, 0, 0x90, 0, | 44 | { 4, 0x7f }, |
44 | 0, 0x22, 0x22, 0x3e, | 45 | { 5, 0x7f }, |
45 | 0xc, 0xc, 0x100, 0x189, | 46 | { 6, 0x7f }, |
46 | 0x189, 0x8770 | 47 | { 7, 0x7f }, |
48 | { 8, 0x7f }, | ||
49 | { 9, 0xff }, | ||
50 | { 10, 0xff }, | ||
51 | { 11, 0xff }, | ||
52 | { 12, 0xff }, | ||
53 | { 13, 0xff }, | ||
54 | { 14, 0xff }, | ||
55 | { 15, 0xff }, | ||
56 | { 16, 0xff }, | ||
57 | { 17, 0xff }, | ||
58 | { 18, 0 }, | ||
59 | { 19, 0x90 }, | ||
60 | { 20, 0 }, | ||
61 | { 21, 0 }, | ||
62 | { 22, 0x22 }, | ||
63 | { 23, 0x22 }, | ||
64 | { 24, 0x3e }, | ||
65 | { 25, 0xc }, | ||
66 | { 26, 0xc }, | ||
67 | { 27, 0x100 }, | ||
68 | { 28, 0x189 }, | ||
69 | { 29, 0x189 }, | ||
70 | { 30, 0x8770 }, | ||
47 | }; | 71 | }; |
48 | 72 | ||
73 | static bool wm8770_volatile_reg(struct device *dev, unsigned int reg) | ||
74 | { | ||
75 | switch (reg) { | ||
76 | case WM8770_RESET: | ||
77 | return true; | ||
78 | default: | ||
79 | return false; | ||
80 | } | ||
81 | } | ||
82 | |||
49 | struct wm8770_priv { | 83 | struct wm8770_priv { |
50 | enum snd_soc_control_type control_type; | 84 | struct regmap *regmap; |
51 | struct regulator_bulk_data supplies[WM8770_NUM_SUPPLIES]; | 85 | struct regulator_bulk_data supplies[WM8770_NUM_SUPPLIES]; |
52 | struct notifier_block disable_nb[WM8770_NUM_SUPPLIES]; | 86 | struct notifier_block disable_nb[WM8770_NUM_SUPPLIES]; |
53 | struct snd_soc_codec *codec; | 87 | struct snd_soc_codec *codec; |
@@ -71,7 +105,7 @@ static int wm8770_regulator_event_##n(struct notifier_block *nb, \ | |||
71 | struct wm8770_priv *wm8770 = container_of(nb, struct wm8770_priv, \ | 105 | struct wm8770_priv *wm8770 = container_of(nb, struct wm8770_priv, \ |
72 | disable_nb[n]); \ | 106 | disable_nb[n]); \ |
73 | if (event & REGULATOR_EVENT_DISABLE) { \ | 107 | if (event & REGULATOR_EVENT_DISABLE) { \ |
74 | wm8770->codec->cache_sync = 1; \ | 108 | regcache_mark_dirty(wm8770->regmap); \ |
75 | } \ | 109 | } \ |
76 | return 0; \ | 110 | return 0; \ |
77 | } | 111 | } |
@@ -466,24 +500,6 @@ static int wm8770_set_sysclk(struct snd_soc_dai *dai, | |||
466 | return 0; | 500 | return 0; |
467 | } | 501 | } |
468 | 502 | ||
469 | static void wm8770_sync_cache(struct snd_soc_codec *codec) | ||
470 | { | ||
471 | int i; | ||
472 | u16 *cache; | ||
473 | |||
474 | if (!codec->cache_sync) | ||
475 | return; | ||
476 | |||
477 | codec->cache_only = 0; | ||
478 | cache = codec->reg_cache; | ||
479 | for (i = 0; i < codec->driver->reg_cache_size; i++) { | ||
480 | if (i == WM8770_RESET || cache[i] == wm8770_reg_defs[i]) | ||
481 | continue; | ||
482 | snd_soc_write(codec, i, cache[i]); | ||
483 | } | ||
484 | codec->cache_sync = 0; | ||
485 | } | ||
486 | |||
487 | static int wm8770_set_bias_level(struct snd_soc_codec *codec, | 503 | static int wm8770_set_bias_level(struct snd_soc_codec *codec, |
488 | enum snd_soc_bias_level level) | 504 | enum snd_soc_bias_level level) |
489 | { | 505 | { |
@@ -507,7 +523,9 @@ static int wm8770_set_bias_level(struct snd_soc_codec *codec, | |||
507 | ret); | 523 | ret); |
508 | return ret; | 524 | return ret; |
509 | } | 525 | } |
510 | wm8770_sync_cache(codec); | 526 | |
527 | regcache_sync(wm8770->regmap); | ||
528 | |||
511 | /* global powerup */ | 529 | /* global powerup */ |
512 | snd_soc_write(codec, WM8770_PWDNCTRL, 0); | 530 | snd_soc_write(codec, WM8770_PWDNCTRL, 0); |
513 | } | 531 | } |
@@ -554,68 +572,25 @@ static struct snd_soc_dai_driver wm8770_dai = { | |||
554 | .symmetric_rates = 1 | 572 | .symmetric_rates = 1 |
555 | }; | 573 | }; |
556 | 574 | ||
557 | #ifdef CONFIG_PM | ||
558 | static int wm8770_suspend(struct snd_soc_codec *codec) | ||
559 | { | ||
560 | wm8770_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
561 | return 0; | ||
562 | } | ||
563 | |||
564 | static int wm8770_resume(struct snd_soc_codec *codec) | ||
565 | { | ||
566 | wm8770_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
567 | return 0; | ||
568 | } | ||
569 | #else | ||
570 | #define wm8770_suspend NULL | ||
571 | #define wm8770_resume NULL | ||
572 | #endif | ||
573 | |||
574 | static int wm8770_probe(struct snd_soc_codec *codec) | 575 | static int wm8770_probe(struct snd_soc_codec *codec) |
575 | { | 576 | { |
576 | struct wm8770_priv *wm8770; | 577 | struct wm8770_priv *wm8770; |
577 | int ret; | 578 | int ret; |
578 | int i; | ||
579 | 579 | ||
580 | wm8770 = snd_soc_codec_get_drvdata(codec); | 580 | wm8770 = snd_soc_codec_get_drvdata(codec); |
581 | wm8770->codec = codec; | 581 | wm8770->codec = codec; |
582 | 582 | ||
583 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8770->control_type); | 583 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); |
584 | if (ret < 0) { | 584 | if (ret < 0) { |
585 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 585 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
586 | return ret; | 586 | return ret; |
587 | } | 587 | } |
588 | 588 | ||
589 | for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++) | ||
590 | wm8770->supplies[i].supply = wm8770_supply_names[i]; | ||
591 | |||
592 | ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8770->supplies), | ||
593 | wm8770->supplies); | ||
594 | if (ret) { | ||
595 | dev_err(codec->dev, "Failed to request supplies: %d\n", ret); | ||
596 | return ret; | ||
597 | } | ||
598 | |||
599 | wm8770->disable_nb[0].notifier_call = wm8770_regulator_event_0; | ||
600 | wm8770->disable_nb[1].notifier_call = wm8770_regulator_event_1; | ||
601 | wm8770->disable_nb[2].notifier_call = wm8770_regulator_event_2; | ||
602 | |||
603 | /* This should really be moved into the regulator core */ | ||
604 | for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++) { | ||
605 | ret = regulator_register_notifier(wm8770->supplies[i].consumer, | ||
606 | &wm8770->disable_nb[i]); | ||
607 | if (ret) { | ||
608 | dev_err(codec->dev, | ||
609 | "Failed to register regulator notifier: %d\n", | ||
610 | ret); | ||
611 | } | ||
612 | } | ||
613 | |||
614 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies), | 589 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies), |
615 | wm8770->supplies); | 590 | wm8770->supplies); |
616 | if (ret) { | 591 | if (ret) { |
617 | dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); | 592 | dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); |
618 | goto err_reg_get; | 593 | return ret; |
619 | } | 594 | } |
620 | 595 | ||
621 | ret = wm8770_reset(codec); | 596 | ret = wm8770_reset(codec); |
@@ -624,8 +599,6 @@ static int wm8770_probe(struct snd_soc_codec *codec) | |||
624 | goto err_reg_enable; | 599 | goto err_reg_enable; |
625 | } | 600 | } |
626 | 601 | ||
627 | wm8770_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
628 | |||
629 | /* latch the volume update bits */ | 602 | /* latch the volume update bits */ |
630 | snd_soc_update_bits(codec, WM8770_MSDIGVOL, 0x100, 0x100); | 603 | snd_soc_update_bits(codec, WM8770_MSDIGVOL, 0x100, 0x100); |
631 | snd_soc_update_bits(codec, WM8770_MSALGVOL, 0x100, 0x100); | 604 | snd_soc_update_bits(codec, WM8770_MSALGVOL, 0x100, 0x100); |
@@ -641,46 +614,22 @@ static int wm8770_probe(struct snd_soc_codec *codec) | |||
641 | /* mute all DACs */ | 614 | /* mute all DACs */ |
642 | snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10, 0x10); | 615 | snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10, 0x10); |
643 | 616 | ||
644 | snd_soc_add_codec_controls(codec, wm8770_snd_controls, | ||
645 | ARRAY_SIZE(wm8770_snd_controls)); | ||
646 | snd_soc_dapm_new_controls(&codec->dapm, wm8770_dapm_widgets, | ||
647 | ARRAY_SIZE(wm8770_dapm_widgets)); | ||
648 | snd_soc_dapm_add_routes(&codec->dapm, wm8770_intercon, | ||
649 | ARRAY_SIZE(wm8770_intercon)); | ||
650 | return 0; | ||
651 | |||
652 | err_reg_enable: | 617 | err_reg_enable: |
653 | regulator_bulk_disable(ARRAY_SIZE(wm8770->supplies), wm8770->supplies); | 618 | regulator_bulk_disable(ARRAY_SIZE(wm8770->supplies), wm8770->supplies); |
654 | err_reg_get: | ||
655 | regulator_bulk_free(ARRAY_SIZE(wm8770->supplies), wm8770->supplies); | ||
656 | return ret; | 619 | return ret; |
657 | } | 620 | } |
658 | 621 | ||
659 | static int wm8770_remove(struct snd_soc_codec *codec) | ||
660 | { | ||
661 | struct wm8770_priv *wm8770; | ||
662 | int i; | ||
663 | |||
664 | wm8770 = snd_soc_codec_get_drvdata(codec); | ||
665 | wm8770_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
666 | |||
667 | for (i = 0; i < ARRAY_SIZE(wm8770->supplies); ++i) | ||
668 | regulator_unregister_notifier(wm8770->supplies[i].consumer, | ||
669 | &wm8770->disable_nb[i]); | ||
670 | regulator_bulk_free(ARRAY_SIZE(wm8770->supplies), wm8770->supplies); | ||
671 | return 0; | ||
672 | } | ||
673 | |||
674 | static struct snd_soc_codec_driver soc_codec_dev_wm8770 = { | 622 | static struct snd_soc_codec_driver soc_codec_dev_wm8770 = { |
675 | .probe = wm8770_probe, | 623 | .probe = wm8770_probe, |
676 | .remove = wm8770_remove, | ||
677 | .suspend = wm8770_suspend, | ||
678 | .resume = wm8770_resume, | ||
679 | .set_bias_level = wm8770_set_bias_level, | 624 | .set_bias_level = wm8770_set_bias_level, |
680 | .idle_bias_off = true, | 625 | .idle_bias_off = true, |
681 | .reg_cache_size = ARRAY_SIZE(wm8770_reg_defs), | 626 | |
682 | .reg_word_size = sizeof (u16), | 627 | .controls = wm8770_snd_controls, |
683 | .reg_cache_default = wm8770_reg_defs | 628 | .num_controls = ARRAY_SIZE(wm8770_snd_controls), |
629 | .dapm_widgets = wm8770_dapm_widgets, | ||
630 | .num_dapm_widgets = ARRAY_SIZE(wm8770_dapm_widgets), | ||
631 | .dapm_routes = wm8770_intercon, | ||
632 | .num_dapm_routes = ARRAY_SIZE(wm8770_intercon), | ||
684 | }; | 633 | }; |
685 | 634 | ||
686 | static const struct of_device_id wm8770_of_match[] = { | 635 | static const struct of_device_id wm8770_of_match[] = { |
@@ -689,17 +638,57 @@ static const struct of_device_id wm8770_of_match[] = { | |||
689 | }; | 638 | }; |
690 | MODULE_DEVICE_TABLE(of, wm8770_of_match); | 639 | MODULE_DEVICE_TABLE(of, wm8770_of_match); |
691 | 640 | ||
641 | static const struct regmap_config wm8770_regmap = { | ||
642 | .reg_bits = 7, | ||
643 | .val_bits = 9, | ||
644 | .max_register = WM8770_RESET, | ||
645 | |||
646 | .reg_defaults = wm8770_reg_defaults, | ||
647 | .num_reg_defaults = ARRAY_SIZE(wm8770_reg_defaults), | ||
648 | .cache_type = REGCACHE_RBTREE, | ||
649 | |||
650 | .volatile_reg = wm8770_volatile_reg, | ||
651 | }; | ||
652 | |||
692 | static int __devinit wm8770_spi_probe(struct spi_device *spi) | 653 | static int __devinit wm8770_spi_probe(struct spi_device *spi) |
693 | { | 654 | { |
694 | struct wm8770_priv *wm8770; | 655 | struct wm8770_priv *wm8770; |
695 | int ret; | 656 | int ret, i; |
696 | 657 | ||
697 | wm8770 = devm_kzalloc(&spi->dev, sizeof(struct wm8770_priv), | 658 | wm8770 = devm_kzalloc(&spi->dev, sizeof(struct wm8770_priv), |
698 | GFP_KERNEL); | 659 | GFP_KERNEL); |
699 | if (!wm8770) | 660 | if (!wm8770) |
700 | return -ENOMEM; | 661 | return -ENOMEM; |
701 | 662 | ||
702 | wm8770->control_type = SND_SOC_SPI; | 663 | for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++) |
664 | wm8770->supplies[i].supply = wm8770_supply_names[i]; | ||
665 | |||
666 | ret = devm_regulator_bulk_get(&spi->dev, ARRAY_SIZE(wm8770->supplies), | ||
667 | wm8770->supplies); | ||
668 | if (ret) { | ||
669 | dev_err(&spi->dev, "Failed to request supplies: %d\n", ret); | ||
670 | return ret; | ||
671 | } | ||
672 | |||
673 | wm8770->disable_nb[0].notifier_call = wm8770_regulator_event_0; | ||
674 | wm8770->disable_nb[1].notifier_call = wm8770_regulator_event_1; | ||
675 | wm8770->disable_nb[2].notifier_call = wm8770_regulator_event_2; | ||
676 | |||
677 | /* This should really be moved into the regulator core */ | ||
678 | for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++) { | ||
679 | ret = regulator_register_notifier(wm8770->supplies[i].consumer, | ||
680 | &wm8770->disable_nb[i]); | ||
681 | if (ret) { | ||
682 | dev_err(&spi->dev, | ||
683 | "Failed to register regulator notifier: %d\n", | ||
684 | ret); | ||
685 | } | ||
686 | } | ||
687 | |||
688 | wm8770->regmap = devm_regmap_init_spi(spi, &wm8770_regmap); | ||
689 | if (IS_ERR(wm8770->regmap)) | ||
690 | return PTR_ERR(wm8770->regmap); | ||
691 | |||
703 | spi_set_drvdata(spi, wm8770); | 692 | spi_set_drvdata(spi, wm8770); |
704 | 693 | ||
705 | ret = snd_soc_register_codec(&spi->dev, | 694 | ret = snd_soc_register_codec(&spi->dev, |
@@ -710,7 +699,15 @@ static int __devinit wm8770_spi_probe(struct spi_device *spi) | |||
710 | 699 | ||
711 | static int __devexit wm8770_spi_remove(struct spi_device *spi) | 700 | static int __devexit wm8770_spi_remove(struct spi_device *spi) |
712 | { | 701 | { |
702 | struct wm8770_priv *wm8770 = spi_get_drvdata(spi); | ||
703 | int i; | ||
704 | |||
705 | for (i = 0; i < ARRAY_SIZE(wm8770->supplies); ++i) | ||
706 | regulator_unregister_notifier(wm8770->supplies[i].consumer, | ||
707 | &wm8770->disable_nb[i]); | ||
708 | |||
713 | snd_soc_unregister_codec(&spi->dev); | 709 | snd_soc_unregister_codec(&spi->dev); |
710 | |||
714 | return 0; | 711 | return 0; |
715 | } | 712 | } |
716 | 713 | ||
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index c088020172ab..837bfb51cebf 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c | |||
@@ -711,7 +711,7 @@ static int __devinit wm8804_spi_probe(struct spi_device *spi) | |||
711 | if (!wm8804) | 711 | if (!wm8804) |
712 | return -ENOMEM; | 712 | return -ENOMEM; |
713 | 713 | ||
714 | wm8804->regmap = regmap_init_spi(spi, &wm8804_regmap_config); | 714 | wm8804->regmap = devm_regmap_init_spi(spi, &wm8804_regmap_config); |
715 | if (IS_ERR(wm8804->regmap)) { | 715 | if (IS_ERR(wm8804->regmap)) { |
716 | ret = PTR_ERR(wm8804->regmap); | 716 | ret = PTR_ERR(wm8804->regmap); |
717 | return ret; | 717 | return ret; |
@@ -727,9 +727,7 @@ static int __devinit wm8804_spi_probe(struct spi_device *spi) | |||
727 | 727 | ||
728 | static int __devexit wm8804_spi_remove(struct spi_device *spi) | 728 | static int __devexit wm8804_spi_remove(struct spi_device *spi) |
729 | { | 729 | { |
730 | struct wm8804_priv *wm8804 = spi_get_drvdata(spi); | ||
731 | snd_soc_unregister_codec(&spi->dev); | 730 | snd_soc_unregister_codec(&spi->dev); |
732 | regmap_exit(wm8804->regmap); | ||
733 | return 0; | 731 | return 0; |
734 | } | 732 | } |
735 | 733 | ||
@@ -755,7 +753,7 @@ static __devinit int wm8804_i2c_probe(struct i2c_client *i2c, | |||
755 | if (!wm8804) | 753 | if (!wm8804) |
756 | return -ENOMEM; | 754 | return -ENOMEM; |
757 | 755 | ||
758 | wm8804->regmap = regmap_init_i2c(i2c, &wm8804_regmap_config); | 756 | wm8804->regmap = devm_regmap_init_i2c(i2c, &wm8804_regmap_config); |
759 | if (IS_ERR(wm8804->regmap)) { | 757 | if (IS_ERR(wm8804->regmap)) { |
760 | ret = PTR_ERR(wm8804->regmap); | 758 | ret = PTR_ERR(wm8804->regmap); |
761 | return ret; | 759 | return ret; |
@@ -765,23 +763,12 @@ static __devinit int wm8804_i2c_probe(struct i2c_client *i2c, | |||
765 | 763 | ||
766 | ret = snd_soc_register_codec(&i2c->dev, | 764 | ret = snd_soc_register_codec(&i2c->dev, |
767 | &soc_codec_dev_wm8804, &wm8804_dai, 1); | 765 | &soc_codec_dev_wm8804, &wm8804_dai, 1); |
768 | if (ret != 0) | ||
769 | goto err; | ||
770 | |||
771 | return 0; | ||
772 | |||
773 | err: | ||
774 | regmap_exit(wm8804->regmap); | ||
775 | return ret; | 766 | return ret; |
776 | } | 767 | } |
777 | 768 | ||
778 | static __devexit int wm8804_i2c_remove(struct i2c_client *i2c) | 769 | static __devexit int wm8804_i2c_remove(struct i2c_client *i2c) |
779 | { | 770 | { |
780 | struct wm8804_priv *wm8804 = i2c_get_clientdata(i2c); | ||
781 | |||
782 | snd_soc_unregister_codec(&i2c->dev); | 771 | snd_soc_unregister_codec(&i2c->dev); |
783 | regmap_exit(wm8804->regmap); | ||
784 | |||
785 | return 0; | 772 | return 0; |
786 | } | 773 | } |
787 | 774 | ||
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index 2f1c075755b1..7a82b7d28dcd 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c | |||
@@ -1023,7 +1023,7 @@ static __devinit int wm8955_i2c_probe(struct i2c_client *i2c, | |||
1023 | if (wm8955 == NULL) | 1023 | if (wm8955 == NULL) |
1024 | return -ENOMEM; | 1024 | return -ENOMEM; |
1025 | 1025 | ||
1026 | wm8955->regmap = regmap_init_i2c(i2c, &wm8955_regmap); | 1026 | wm8955->regmap = devm_regmap_init_i2c(i2c, &wm8955_regmap); |
1027 | if (IS_ERR(wm8955->regmap)) { | 1027 | if (IS_ERR(wm8955->regmap)) { |
1028 | ret = PTR_ERR(wm8955->regmap); | 1028 | ret = PTR_ERR(wm8955->regmap); |
1029 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | 1029 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", |
@@ -1035,22 +1035,13 @@ static __devinit int wm8955_i2c_probe(struct i2c_client *i2c, | |||
1035 | 1035 | ||
1036 | ret = snd_soc_register_codec(&i2c->dev, | 1036 | ret = snd_soc_register_codec(&i2c->dev, |
1037 | &soc_codec_dev_wm8955, &wm8955_dai, 1); | 1037 | &soc_codec_dev_wm8955, &wm8955_dai, 1); |
1038 | if (ret != 0) | ||
1039 | goto err; | ||
1040 | 1038 | ||
1041 | return ret; | 1039 | return ret; |
1042 | |||
1043 | err: | ||
1044 | regmap_exit(wm8955->regmap); | ||
1045 | return ret; | ||
1046 | } | 1040 | } |
1047 | 1041 | ||
1048 | static __devexit int wm8955_i2c_remove(struct i2c_client *client) | 1042 | static __devexit int wm8955_i2c_remove(struct i2c_client *client) |
1049 | { | 1043 | { |
1050 | struct wm8955_priv *wm8955 = i2c_get_clientdata(client); | ||
1051 | |||
1052 | snd_soc_unregister_codec(&client->dev); | 1044 | snd_soc_unregister_codec(&client->dev); |
1053 | regmap_exit(wm8955->regmap); | ||
1054 | 1045 | ||
1055 | return 0; | 1046 | return 0; |
1056 | } | 1047 | } |
diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c index 00121ba36597..b0710d817a65 100644 --- a/sound/soc/codecs/wm8958-dsp2.c +++ b/sound/soc/codecs/wm8958-dsp2.c | |||
@@ -195,7 +195,7 @@ ok: | |||
195 | static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path) | 195 | static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path) |
196 | { | 196 | { |
197 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 197 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
198 | struct wm8994_pdata *pdata = wm8994->pdata; | 198 | struct wm8994 *control = wm8994->wm8994; |
199 | int i; | 199 | int i; |
200 | 200 | ||
201 | /* If the DSP is already running then noop */ | 201 | /* If the DSP is already running then noop */ |
@@ -210,9 +210,9 @@ static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path) | |||
210 | WM8958_DSP2_ENA, WM8958_DSP2_ENA); | 210 | WM8958_DSP2_ENA, WM8958_DSP2_ENA); |
211 | 211 | ||
212 | /* If we've got user supplied MBC settings use them */ | 212 | /* If we've got user supplied MBC settings use them */ |
213 | if (pdata && pdata->num_mbc_cfgs) { | 213 | if (control->pdata.num_mbc_cfgs) { |
214 | struct wm8958_mbc_cfg *cfg | 214 | struct wm8958_mbc_cfg *cfg |
215 | = &pdata->mbc_cfgs[wm8994->mbc_cfg]; | 215 | = &control->pdata.mbc_cfgs[wm8994->mbc_cfg]; |
216 | 216 | ||
217 | for (i = 0; i < ARRAY_SIZE(cfg->coeff_regs); i++) | 217 | for (i = 0; i < ARRAY_SIZE(cfg->coeff_regs); i++) |
218 | snd_soc_write(codec, i + WM8958_MBC_BAND_1_K_1, | 218 | snd_soc_write(codec, i + WM8958_MBC_BAND_1_K_1, |
@@ -239,7 +239,7 @@ static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path) | |||
239 | static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path) | 239 | static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path) |
240 | { | 240 | { |
241 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 241 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
242 | struct wm8994_pdata *pdata = wm8994->pdata; | 242 | struct wm8994 *control = wm8994->wm8994; |
243 | int i, ena; | 243 | int i, ena; |
244 | 244 | ||
245 | if (wm8994->mbc_vss) | 245 | if (wm8994->mbc_vss) |
@@ -249,26 +249,26 @@ static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path) | |||
249 | WM8958_DSP2_ENA, WM8958_DSP2_ENA); | 249 | WM8958_DSP2_ENA, WM8958_DSP2_ENA); |
250 | 250 | ||
251 | /* If we've got user supplied settings use them */ | 251 | /* If we've got user supplied settings use them */ |
252 | if (pdata && pdata->num_mbc_cfgs) { | 252 | if (control->pdata.num_mbc_cfgs) { |
253 | struct wm8958_mbc_cfg *cfg | 253 | struct wm8958_mbc_cfg *cfg |
254 | = &pdata->mbc_cfgs[wm8994->mbc_cfg]; | 254 | = &control->pdata.mbc_cfgs[wm8994->mbc_cfg]; |
255 | 255 | ||
256 | for (i = 0; i < ARRAY_SIZE(cfg->combined_regs); i++) | 256 | for (i = 0; i < ARRAY_SIZE(cfg->combined_regs); i++) |
257 | snd_soc_write(codec, i + 0x2800, | 257 | snd_soc_write(codec, i + 0x2800, |
258 | cfg->combined_regs[i]); | 258 | cfg->combined_regs[i]); |
259 | } | 259 | } |
260 | 260 | ||
261 | if (pdata && pdata->num_vss_cfgs) { | 261 | if (control->pdata.num_vss_cfgs) { |
262 | struct wm8958_vss_cfg *cfg | 262 | struct wm8958_vss_cfg *cfg |
263 | = &pdata->vss_cfgs[wm8994->vss_cfg]; | 263 | = &control->pdata.vss_cfgs[wm8994->vss_cfg]; |
264 | 264 | ||
265 | for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) | 265 | for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) |
266 | snd_soc_write(codec, i + 0x2600, cfg->regs[i]); | 266 | snd_soc_write(codec, i + 0x2600, cfg->regs[i]); |
267 | } | 267 | } |
268 | 268 | ||
269 | if (pdata && pdata->num_vss_hpf_cfgs) { | 269 | if (control->pdata.num_vss_hpf_cfgs) { |
270 | struct wm8958_vss_hpf_cfg *cfg | 270 | struct wm8958_vss_hpf_cfg *cfg |
271 | = &pdata->vss_hpf_cfgs[wm8994->vss_hpf_cfg]; | 271 | = &control->pdata.vss_hpf_cfgs[wm8994->vss_hpf_cfg]; |
272 | 272 | ||
273 | for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) | 273 | for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) |
274 | snd_soc_write(codec, i + 0x2400, cfg->regs[i]); | 274 | snd_soc_write(codec, i + 0x2400, cfg->regs[i]); |
@@ -300,7 +300,7 @@ static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path) | |||
300 | static void wm8958_dsp_start_enh_eq(struct snd_soc_codec *codec, int path) | 300 | static void wm8958_dsp_start_enh_eq(struct snd_soc_codec *codec, int path) |
301 | { | 301 | { |
302 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 302 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
303 | struct wm8994_pdata *pdata = wm8994->pdata; | 303 | struct wm8994 *control = wm8994->wm8994; |
304 | int i; | 304 | int i; |
305 | 305 | ||
306 | wm8958_dsp2_fw(codec, "ENH_EQ", wm8994->enh_eq, false); | 306 | wm8958_dsp2_fw(codec, "ENH_EQ", wm8994->enh_eq, false); |
@@ -309,9 +309,9 @@ static void wm8958_dsp_start_enh_eq(struct snd_soc_codec *codec, int path) | |||
309 | WM8958_DSP2_ENA, WM8958_DSP2_ENA); | 309 | WM8958_DSP2_ENA, WM8958_DSP2_ENA); |
310 | 310 | ||
311 | /* If we've got user supplied settings use them */ | 311 | /* If we've got user supplied settings use them */ |
312 | if (pdata && pdata->num_enh_eq_cfgs) { | 312 | if (control->pdata.num_enh_eq_cfgs) { |
313 | struct wm8958_enh_eq_cfg *cfg | 313 | struct wm8958_enh_eq_cfg *cfg |
314 | = &pdata->enh_eq_cfgs[wm8994->enh_eq_cfg]; | 314 | = &control->pdata.enh_eq_cfgs[wm8994->enh_eq_cfg]; |
315 | 315 | ||
316 | for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) | 316 | for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) |
317 | snd_soc_write(codec, i + 0x2200, | 317 | snd_soc_write(codec, i + 0x2200, |
@@ -458,7 +458,7 @@ static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol, | |||
458 | { | 458 | { |
459 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 459 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
460 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 460 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
461 | struct wm8994_pdata *pdata = wm8994->pdata; | 461 | struct wm8994 *control = wm8994->wm8994; |
462 | int value = ucontrol->value.integer.value[0]; | 462 | int value = ucontrol->value.integer.value[0]; |
463 | int reg; | 463 | int reg; |
464 | 464 | ||
@@ -467,7 +467,7 @@ static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol, | |||
467 | if (reg < 0 || reg & WM8958_DSP2CLK_ENA) | 467 | if (reg < 0 || reg & WM8958_DSP2CLK_ENA) |
468 | return -EBUSY; | 468 | return -EBUSY; |
469 | 469 | ||
470 | if (value >= pdata->num_mbc_cfgs) | 470 | if (value >= control->pdata.num_mbc_cfgs) |
471 | return -EINVAL; | 471 | return -EINVAL; |
472 | 472 | ||
473 | wm8994->mbc_cfg = value; | 473 | wm8994->mbc_cfg = value; |
@@ -548,7 +548,7 @@ static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol, | |||
548 | { | 548 | { |
549 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 549 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
550 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 550 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
551 | struct wm8994_pdata *pdata = wm8994->pdata; | 551 | struct wm8994 *control = wm8994->wm8994; |
552 | int value = ucontrol->value.integer.value[0]; | 552 | int value = ucontrol->value.integer.value[0]; |
553 | int reg; | 553 | int reg; |
554 | 554 | ||
@@ -557,7 +557,7 @@ static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol, | |||
557 | if (reg < 0 || reg & WM8958_DSP2CLK_ENA) | 557 | if (reg < 0 || reg & WM8958_DSP2CLK_ENA) |
558 | return -EBUSY; | 558 | return -EBUSY; |
559 | 559 | ||
560 | if (value >= pdata->num_vss_cfgs) | 560 | if (value >= control->pdata.num_vss_cfgs) |
561 | return -EINVAL; | 561 | return -EINVAL; |
562 | 562 | ||
563 | wm8994->vss_cfg = value; | 563 | wm8994->vss_cfg = value; |
@@ -581,7 +581,7 @@ static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol, | |||
581 | { | 581 | { |
582 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 582 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
583 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 583 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
584 | struct wm8994_pdata *pdata = wm8994->pdata; | 584 | struct wm8994 *control = wm8994->wm8994; |
585 | int value = ucontrol->value.integer.value[0]; | 585 | int value = ucontrol->value.integer.value[0]; |
586 | int reg; | 586 | int reg; |
587 | 587 | ||
@@ -590,7 +590,7 @@ static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol, | |||
590 | if (reg < 0 || reg & WM8958_DSP2CLK_ENA) | 590 | if (reg < 0 || reg & WM8958_DSP2CLK_ENA) |
591 | return -EBUSY; | 591 | return -EBUSY; |
592 | 592 | ||
593 | if (value >= pdata->num_vss_hpf_cfgs) | 593 | if (value >= control->pdata.num_vss_hpf_cfgs) |
594 | return -EINVAL; | 594 | return -EINVAL; |
595 | 595 | ||
596 | wm8994->vss_hpf_cfg = value; | 596 | wm8994->vss_hpf_cfg = value; |
@@ -748,7 +748,7 @@ static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol, | |||
748 | { | 748 | { |
749 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 749 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
750 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 750 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
751 | struct wm8994_pdata *pdata = wm8994->pdata; | 751 | struct wm8994 *control = wm8994->wm8994; |
752 | int value = ucontrol->value.integer.value[0]; | 752 | int value = ucontrol->value.integer.value[0]; |
753 | int reg; | 753 | int reg; |
754 | 754 | ||
@@ -757,7 +757,7 @@ static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol, | |||
757 | if (reg < 0 || reg & WM8958_DSP2CLK_ENA) | 757 | if (reg < 0 || reg & WM8958_DSP2CLK_ENA) |
758 | return -EBUSY; | 758 | return -EBUSY; |
759 | 759 | ||
760 | if (value >= pdata->num_enh_eq_cfgs) | 760 | if (value >= control->pdata.num_enh_eq_cfgs) |
761 | return -EINVAL; | 761 | return -EINVAL; |
762 | 762 | ||
763 | wm8994->enh_eq_cfg = value; | 763 | wm8994->enh_eq_cfg = value; |
@@ -883,13 +883,6 @@ static void wm8958_mbc_vss_loaded(const struct firmware *fw, void *context) | |||
883 | wm8994->mbc_vss = fw; | 883 | wm8994->mbc_vss = fw; |
884 | mutex_unlock(&codec->mutex); | 884 | mutex_unlock(&codec->mutex); |
885 | } | 885 | } |
886 | |||
887 | /* We can't have more than one request outstanding at once so | ||
888 | * we daisy chain. | ||
889 | */ | ||
890 | request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, | ||
891 | "wm8958_enh_eq.wfw", codec->dev, GFP_KERNEL, | ||
892 | codec, wm8958_enh_eq_loaded); | ||
893 | } | 886 | } |
894 | 887 | ||
895 | static void wm8958_mbc_loaded(const struct firmware *fw, void *context) | 888 | static void wm8958_mbc_loaded(const struct firmware *fw, void *context) |
@@ -897,25 +890,18 @@ static void wm8958_mbc_loaded(const struct firmware *fw, void *context) | |||
897 | struct snd_soc_codec *codec = context; | 890 | struct snd_soc_codec *codec = context; |
898 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 891 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
899 | 892 | ||
900 | if (wm8958_dsp2_fw(codec, "MBC", fw, true) != 0) | 893 | if (fw && (wm8958_dsp2_fw(codec, "MBC", fw, true) == 0)) { |
901 | return; | 894 | mutex_lock(&codec->mutex); |
902 | 895 | wm8994->mbc = fw; | |
903 | mutex_lock(&codec->mutex); | 896 | mutex_unlock(&codec->mutex); |
904 | wm8994->mbc = fw; | 897 | } |
905 | mutex_unlock(&codec->mutex); | ||
906 | |||
907 | /* We can't have more than one request outstanding at once so | ||
908 | * we daisy chain. | ||
909 | */ | ||
910 | request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, | ||
911 | "wm8958_mbc_vss.wfw", codec->dev, GFP_KERNEL, | ||
912 | codec, wm8958_mbc_vss_loaded); | ||
913 | } | 898 | } |
914 | 899 | ||
915 | void wm8958_dsp2_init(struct snd_soc_codec *codec) | 900 | void wm8958_dsp2_init(struct snd_soc_codec *codec) |
916 | { | 901 | { |
917 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 902 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
918 | struct wm8994_pdata *pdata = wm8994->pdata; | 903 | struct wm8994 *control = wm8994->wm8994; |
904 | struct wm8994_pdata *pdata = &control->pdata; | ||
919 | int ret, i; | 905 | int ret, i; |
920 | 906 | ||
921 | wm8994->dsp_active = -1; | 907 | wm8994->dsp_active = -1; |
@@ -932,9 +918,12 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
932 | request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, | 918 | request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, |
933 | "wm8958_mbc.wfw", codec->dev, GFP_KERNEL, | 919 | "wm8958_mbc.wfw", codec->dev, GFP_KERNEL, |
934 | codec, wm8958_mbc_loaded); | 920 | codec, wm8958_mbc_loaded); |
935 | 921 | request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, | |
936 | if (!pdata) | 922 | "wm8958_mbc_vss.wfw", codec->dev, GFP_KERNEL, |
937 | return; | 923 | codec, wm8958_mbc_vss_loaded); |
924 | request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, | ||
925 | "wm8958_enh_eq.wfw", codec->dev, GFP_KERNEL, | ||
926 | codec, wm8958_enh_eq_loaded); | ||
938 | 927 | ||
939 | if (pdata->num_mbc_cfgs) { | 928 | if (pdata->num_mbc_cfgs) { |
940 | struct snd_kcontrol_new control[] = { | 929 | struct snd_kcontrol_new control[] = { |
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index f0f6f6601785..cf09cb625a7b 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c | |||
@@ -1040,7 +1040,7 @@ static __devinit int wm8960_i2c_probe(struct i2c_client *i2c, | |||
1040 | if (wm8960 == NULL) | 1040 | if (wm8960 == NULL) |
1041 | return -ENOMEM; | 1041 | return -ENOMEM; |
1042 | 1042 | ||
1043 | wm8960->regmap = regmap_init_i2c(i2c, &wm8960_regmap); | 1043 | wm8960->regmap = devm_regmap_init_i2c(i2c, &wm8960_regmap); |
1044 | if (IS_ERR(wm8960->regmap)) | 1044 | if (IS_ERR(wm8960->regmap)) |
1045 | return PTR_ERR(wm8960->regmap); | 1045 | return PTR_ERR(wm8960->regmap); |
1046 | 1046 | ||
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index ce6720073798..8fd38cb4ba48 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c | |||
@@ -3610,7 +3610,7 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c, | |||
3610 | for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++) | 3610 | for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++) |
3611 | wm8962->supplies[i].supply = wm8962_supply_names[i]; | 3611 | wm8962->supplies[i].supply = wm8962_supply_names[i]; |
3612 | 3612 | ||
3613 | ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8962->supplies), | 3613 | ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8962->supplies), |
3614 | wm8962->supplies); | 3614 | wm8962->supplies); |
3615 | if (ret != 0) { | 3615 | if (ret != 0) { |
3616 | dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); | 3616 | dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); |
@@ -3621,10 +3621,10 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c, | |||
3621 | wm8962->supplies); | 3621 | wm8962->supplies); |
3622 | if (ret != 0) { | 3622 | if (ret != 0) { |
3623 | dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); | 3623 | dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); |
3624 | goto err_get; | 3624 | return ret; |
3625 | } | 3625 | } |
3626 | 3626 | ||
3627 | wm8962->regmap = regmap_init_i2c(i2c, &wm8962_regmap); | 3627 | wm8962->regmap = devm_regmap_init_i2c(i2c, &wm8962_regmap); |
3628 | if (IS_ERR(wm8962->regmap)) { | 3628 | if (IS_ERR(wm8962->regmap)) { |
3629 | ret = PTR_ERR(wm8962->regmap); | 3629 | ret = PTR_ERR(wm8962->regmap); |
3630 | dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret); | 3630 | dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret); |
@@ -3641,20 +3641,20 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c, | |||
3641 | ret = regmap_read(wm8962->regmap, WM8962_SOFTWARE_RESET, ®); | 3641 | ret = regmap_read(wm8962->regmap, WM8962_SOFTWARE_RESET, ®); |
3642 | if (ret < 0) { | 3642 | if (ret < 0) { |
3643 | dev_err(&i2c->dev, "Failed to read ID register\n"); | 3643 | dev_err(&i2c->dev, "Failed to read ID register\n"); |
3644 | goto err_regmap; | 3644 | goto err_enable; |
3645 | } | 3645 | } |
3646 | if (reg != 0x6243) { | 3646 | if (reg != 0x6243) { |
3647 | dev_err(&i2c->dev, | 3647 | dev_err(&i2c->dev, |
3648 | "Device is not a WM8962, ID %x != 0x6243\n", reg); | 3648 | "Device is not a WM8962, ID %x != 0x6243\n", reg); |
3649 | ret = -EINVAL; | 3649 | ret = -EINVAL; |
3650 | goto err_regmap; | 3650 | goto err_enable; |
3651 | } | 3651 | } |
3652 | 3652 | ||
3653 | ret = regmap_read(wm8962->regmap, WM8962_RIGHT_INPUT_VOLUME, ®); | 3653 | ret = regmap_read(wm8962->regmap, WM8962_RIGHT_INPUT_VOLUME, ®); |
3654 | if (ret < 0) { | 3654 | if (ret < 0) { |
3655 | dev_err(&i2c->dev, "Failed to read device revision: %d\n", | 3655 | dev_err(&i2c->dev, "Failed to read device revision: %d\n", |
3656 | ret); | 3656 | ret); |
3657 | goto err_regmap; | 3657 | goto err_enable; |
3658 | } | 3658 | } |
3659 | 3659 | ||
3660 | dev_info(&i2c->dev, "customer id %x revision %c\n", | 3660 | dev_info(&i2c->dev, "customer id %x revision %c\n", |
@@ -3667,7 +3667,7 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c, | |||
3667 | ret = wm8962_reset(wm8962); | 3667 | ret = wm8962_reset(wm8962); |
3668 | if (ret < 0) { | 3668 | if (ret < 0) { |
3669 | dev_err(&i2c->dev, "Failed to issue reset\n"); | 3669 | dev_err(&i2c->dev, "Failed to issue reset\n"); |
3670 | goto err_regmap; | 3670 | goto err_enable; |
3671 | } | 3671 | } |
3672 | 3672 | ||
3673 | if (pdata && pdata->in4_dc_measure) { | 3673 | if (pdata && pdata->in4_dc_measure) { |
@@ -3686,30 +3686,22 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c, | |||
3686 | ret = snd_soc_register_codec(&i2c->dev, | 3686 | ret = snd_soc_register_codec(&i2c->dev, |
3687 | &soc_codec_dev_wm8962, &wm8962_dai, 1); | 3687 | &soc_codec_dev_wm8962, &wm8962_dai, 1); |
3688 | if (ret < 0) | 3688 | if (ret < 0) |
3689 | goto err_regmap; | 3689 | goto err_enable; |
3690 | 3690 | ||
3691 | /* The drivers should power up as needed */ | 3691 | /* The drivers should power up as needed */ |
3692 | regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); | 3692 | regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); |
3693 | 3693 | ||
3694 | return 0; | 3694 | return 0; |
3695 | 3695 | ||
3696 | err_regmap: | ||
3697 | regmap_exit(wm8962->regmap); | ||
3698 | err_enable: | 3696 | err_enable: |
3699 | regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); | 3697 | regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); |
3700 | err_get: | ||
3701 | regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); | ||
3702 | err: | 3698 | err: |
3703 | return ret; | 3699 | return ret; |
3704 | } | 3700 | } |
3705 | 3701 | ||
3706 | static __devexit int wm8962_i2c_remove(struct i2c_client *client) | 3702 | static __devexit int wm8962_i2c_remove(struct i2c_client *client) |
3707 | { | 3703 | { |
3708 | struct wm8962_priv *wm8962 = dev_get_drvdata(&client->dev); | ||
3709 | |||
3710 | snd_soc_unregister_codec(&client->dev); | 3704 | snd_soc_unregister_codec(&client->dev); |
3711 | regmap_exit(wm8962->regmap); | ||
3712 | regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); | ||
3713 | return 0; | 3705 | return 0; |
3714 | } | 3706 | } |
3715 | 3707 | ||
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c index 5ce647758443..70dd27e94514 100644 --- a/sound/soc/codecs/wm8971.c +++ b/sound/soc/codecs/wm8971.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
20 | #include <linux/pm.h> | 20 | #include <linux/pm.h> |
21 | #include <linux/i2c.h> | 21 | #include <linux/i2c.h> |
22 | #include <linux/regmap.h> | ||
22 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
23 | #include <sound/core.h> | 24 | #include <sound/core.h> |
24 | #include <sound/pcm.h> | 25 | #include <sound/pcm.h> |
@@ -34,7 +35,6 @@ static struct workqueue_struct *wm8971_workq = NULL; | |||
34 | 35 | ||
35 | /* codec private data */ | 36 | /* codec private data */ |
36 | struct wm8971_priv { | 37 | struct wm8971_priv { |
37 | enum snd_soc_control_type control_type; | ||
38 | unsigned int sysclk; | 38 | unsigned int sysclk; |
39 | }; | 39 | }; |
40 | 40 | ||
@@ -43,18 +43,50 @@ struct wm8971_priv { | |||
43 | * We can't read the WM8971 register space when we | 43 | * We can't read the WM8971 register space when we |
44 | * are using 2 wire for device control, so we cache them instead. | 44 | * are using 2 wire for device control, so we cache them instead. |
45 | */ | 45 | */ |
46 | static const u16 wm8971_reg[] = { | 46 | static const struct reg_default wm8971_reg_defaults[] = { |
47 | 0x0097, 0x0097, 0x0079, 0x0079, /* 0 */ | 47 | { 0, 0x0097 }, |
48 | 0x0000, 0x0008, 0x0000, 0x000a, /* 4 */ | 48 | { 1, 0x0097 }, |
49 | 0x0000, 0x0000, 0x00ff, 0x00ff, /* 8 */ | 49 | { 2, 0x0079 }, |
50 | 0x000f, 0x000f, 0x0000, 0x0000, /* 12 */ | 50 | { 3, 0x0079 }, |
51 | 0x0000, 0x007b, 0x0000, 0x0032, /* 16 */ | 51 | { 4, 0x0000 }, |
52 | 0x0000, 0x00c3, 0x00c3, 0x00c0, /* 20 */ | 52 | { 5, 0x0008 }, |
53 | 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */ | 53 | { 6, 0x0000 }, |
54 | 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */ | 54 | { 7, 0x000a }, |
55 | 0x0000, 0x0000, 0x0050, 0x0050, /* 32 */ | 55 | { 8, 0x0000 }, |
56 | 0x0050, 0x0050, 0x0050, 0x0050, /* 36 */ | 56 | { 9, 0x0000 }, |
57 | 0x0079, 0x0079, 0x0079, /* 40 */ | 57 | { 10, 0x00ff }, |
58 | { 11, 0x00ff }, | ||
59 | { 12, 0x000f }, | ||
60 | { 13, 0x000f }, | ||
61 | { 14, 0x0000 }, | ||
62 | { 15, 0x0000 }, | ||
63 | { 16, 0x0000 }, | ||
64 | { 17, 0x007b }, | ||
65 | { 18, 0x0000 }, | ||
66 | { 19, 0x0032 }, | ||
67 | { 20, 0x0000 }, | ||
68 | { 21, 0x00c3 }, | ||
69 | { 22, 0x00c3 }, | ||
70 | { 23, 0x00c0 }, | ||
71 | { 24, 0x0000 }, | ||
72 | { 25, 0x0000 }, | ||
73 | { 26, 0x0000 }, | ||
74 | { 27, 0x0000 }, | ||
75 | { 28, 0x0000 }, | ||
76 | { 29, 0x0000 }, | ||
77 | { 30, 0x0000 }, | ||
78 | { 31, 0x0000 }, | ||
79 | { 32, 0x0000 }, | ||
80 | { 33, 0x0000 }, | ||
81 | { 34, 0x0050 }, | ||
82 | { 35, 0x0050 }, | ||
83 | { 36, 0x0050 }, | ||
84 | { 37, 0x0050 }, | ||
85 | { 38, 0x0050 }, | ||
86 | { 39, 0x0050 }, | ||
87 | { 40, 0x0079 }, | ||
88 | { 41, 0x0079 }, | ||
89 | { 42, 0x0079 }, | ||
58 | }; | 90 | }; |
59 | 91 | ||
60 | #define wm8971_reset(c) snd_soc_write(c, WM8971_RESET, 0) | 92 | #define wm8971_reset(c) snd_soc_write(c, WM8971_RESET, 0) |
@@ -613,11 +645,10 @@ static int wm8971_resume(struct snd_soc_codec *codec) | |||
613 | 645 | ||
614 | static int wm8971_probe(struct snd_soc_codec *codec) | 646 | static int wm8971_probe(struct snd_soc_codec *codec) |
615 | { | 647 | { |
616 | struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec); | ||
617 | int ret = 0; | 648 | int ret = 0; |
618 | u16 reg; | 649 | u16 reg; |
619 | 650 | ||
620 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8971->control_type); | 651 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); |
621 | if (ret < 0) { | 652 | if (ret < 0) { |
622 | printk(KERN_ERR "wm8971: failed to set cache I/O: %d\n", ret); | 653 | printk(KERN_ERR "wm8971: failed to set cache I/O: %d\n", ret); |
623 | return ret; | 654 | return ret; |
@@ -667,9 +698,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8971 = { | |||
667 | .suspend = wm8971_suspend, | 698 | .suspend = wm8971_suspend, |
668 | .resume = wm8971_resume, | 699 | .resume = wm8971_resume, |
669 | .set_bias_level = wm8971_set_bias_level, | 700 | .set_bias_level = wm8971_set_bias_level, |
670 | .reg_cache_size = ARRAY_SIZE(wm8971_reg), | ||
671 | .reg_word_size = sizeof(u16), | ||
672 | .reg_cache_default = wm8971_reg, | ||
673 | 701 | ||
674 | .controls = wm8971_snd_controls, | 702 | .controls = wm8971_snd_controls, |
675 | .num_controls = ARRAY_SIZE(wm8971_snd_controls), | 703 | .num_controls = ARRAY_SIZE(wm8971_snd_controls), |
@@ -679,10 +707,21 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8971 = { | |||
679 | .num_dapm_routes = ARRAY_SIZE(wm8971_dapm_routes), | 707 | .num_dapm_routes = ARRAY_SIZE(wm8971_dapm_routes), |
680 | }; | 708 | }; |
681 | 709 | ||
710 | static const struct regmap_config wm8971_regmap = { | ||
711 | .reg_bits = 7, | ||
712 | .val_bits = 9, | ||
713 | .max_register = WM8971_MOUTV, | ||
714 | |||
715 | .reg_defaults = wm8971_reg_defaults, | ||
716 | .num_reg_defaults = ARRAY_SIZE(wm8971_reg_defaults), | ||
717 | .cache_type = REGCACHE_RBTREE, | ||
718 | }; | ||
719 | |||
682 | static __devinit int wm8971_i2c_probe(struct i2c_client *i2c, | 720 | static __devinit int wm8971_i2c_probe(struct i2c_client *i2c, |
683 | const struct i2c_device_id *id) | 721 | const struct i2c_device_id *id) |
684 | { | 722 | { |
685 | struct wm8971_priv *wm8971; | 723 | struct wm8971_priv *wm8971; |
724 | struct regmap *regmap; | ||
686 | int ret; | 725 | int ret; |
687 | 726 | ||
688 | wm8971 = devm_kzalloc(&i2c->dev, sizeof(struct wm8971_priv), | 727 | wm8971 = devm_kzalloc(&i2c->dev, sizeof(struct wm8971_priv), |
@@ -690,7 +729,10 @@ static __devinit int wm8971_i2c_probe(struct i2c_client *i2c, | |||
690 | if (wm8971 == NULL) | 729 | if (wm8971 == NULL) |
691 | return -ENOMEM; | 730 | return -ENOMEM; |
692 | 731 | ||
693 | wm8971->control_type = SND_SOC_I2C; | 732 | regmap = devm_regmap_init_i2c(i2c, &wm8971_regmap); |
733 | if (IS_ERR(regmap)) | ||
734 | return PTR_ERR(regmap); | ||
735 | |||
694 | i2c_set_clientdata(i2c, wm8971); | 736 | i2c_set_clientdata(i2c, wm8971); |
695 | 737 | ||
696 | ret = snd_soc_register_codec(&i2c->dev, | 738 | ret = snd_soc_register_codec(&i2c->dev, |
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index 4c0a8e496131..8c1dac946f62 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c | |||
@@ -527,9 +527,6 @@ static int wm8978_configure_pll(struct snd_soc_codec *codec) | |||
527 | return idx; | 527 | return idx; |
528 | 528 | ||
529 | wm8978->mclk_idx = idx; | 529 | wm8978->mclk_idx = idx; |
530 | |||
531 | /* GPIO1 into default mode as input - before configuring PLL */ | ||
532 | snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 7, 0); | ||
533 | } else { | 530 | } else { |
534 | return -EINVAL; | 531 | return -EINVAL; |
535 | } | 532 | } |
diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index 14f666398d0c..7b3f4097609b 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c | |||
@@ -1122,33 +1122,22 @@ static int __devinit wm8985_spi_probe(struct spi_device *spi) | |||
1122 | 1122 | ||
1123 | spi_set_drvdata(spi, wm8985); | 1123 | spi_set_drvdata(spi, wm8985); |
1124 | 1124 | ||
1125 | wm8985->regmap = regmap_init_spi(spi, &wm8985_regmap); | 1125 | wm8985->regmap = devm_regmap_init_spi(spi, &wm8985_regmap); |
1126 | if (IS_ERR(wm8985->regmap)) { | 1126 | if (IS_ERR(wm8985->regmap)) { |
1127 | ret = PTR_ERR(wm8985->regmap); | 1127 | ret = PTR_ERR(wm8985->regmap); |
1128 | dev_err(&spi->dev, "Failed to allocate register map: %d\n", | 1128 | dev_err(&spi->dev, "Failed to allocate register map: %d\n", |
1129 | ret); | 1129 | ret); |
1130 | goto err; | 1130 | return ret; |
1131 | } | 1131 | } |
1132 | 1132 | ||
1133 | ret = snd_soc_register_codec(&spi->dev, | 1133 | ret = snd_soc_register_codec(&spi->dev, |
1134 | &soc_codec_dev_wm8985, &wm8985_dai, 1); | 1134 | &soc_codec_dev_wm8985, &wm8985_dai, 1); |
1135 | if (ret != 0) | ||
1136 | goto err; | ||
1137 | |||
1138 | return 0; | ||
1139 | |||
1140 | err: | ||
1141 | regmap_exit(wm8985->regmap); | ||
1142 | return ret; | 1135 | return ret; |
1143 | } | 1136 | } |
1144 | 1137 | ||
1145 | static int __devexit wm8985_spi_remove(struct spi_device *spi) | 1138 | static int __devexit wm8985_spi_remove(struct spi_device *spi) |
1146 | { | 1139 | { |
1147 | struct wm8985_priv *wm8985 = spi_get_drvdata(spi); | ||
1148 | |||
1149 | snd_soc_unregister_codec(&spi->dev); | 1140 | snd_soc_unregister_codec(&spi->dev); |
1150 | regmap_exit(wm8985->regmap); | ||
1151 | |||
1152 | return 0; | 1141 | return 0; |
1153 | } | 1142 | } |
1154 | 1143 | ||
@@ -1175,33 +1164,22 @@ static __devinit int wm8985_i2c_probe(struct i2c_client *i2c, | |||
1175 | 1164 | ||
1176 | i2c_set_clientdata(i2c, wm8985); | 1165 | i2c_set_clientdata(i2c, wm8985); |
1177 | 1166 | ||
1178 | wm8985->regmap = regmap_init_i2c(i2c, &wm8985_regmap); | 1167 | wm8985->regmap = devm_regmap_init_i2c(i2c, &wm8985_regmap); |
1179 | if (IS_ERR(wm8985->regmap)) { | 1168 | if (IS_ERR(wm8985->regmap)) { |
1180 | ret = PTR_ERR(wm8985->regmap); | 1169 | ret = PTR_ERR(wm8985->regmap); |
1181 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | 1170 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", |
1182 | ret); | 1171 | ret); |
1183 | goto err; | 1172 | return ret; |
1184 | } | 1173 | } |
1185 | 1174 | ||
1186 | ret = snd_soc_register_codec(&i2c->dev, | 1175 | ret = snd_soc_register_codec(&i2c->dev, |
1187 | &soc_codec_dev_wm8985, &wm8985_dai, 1); | 1176 | &soc_codec_dev_wm8985, &wm8985_dai, 1); |
1188 | if (ret != 0) | ||
1189 | goto err; | ||
1190 | |||
1191 | return 0; | ||
1192 | |||
1193 | err: | ||
1194 | regmap_exit(wm8985->regmap); | ||
1195 | return ret; | 1177 | return ret; |
1196 | } | 1178 | } |
1197 | 1179 | ||
1198 | static __devexit int wm8985_i2c_remove(struct i2c_client *i2c) | 1180 | static __devexit int wm8985_i2c_remove(struct i2c_client *i2c) |
1199 | { | 1181 | { |
1200 | struct wm8985_priv *wm8985 = i2c_get_clientdata(i2c); | ||
1201 | |||
1202 | snd_soc_unregister_codec(&i2c->dev); | 1182 | snd_soc_unregister_codec(&i2c->dev); |
1203 | regmap_exit(wm8985->regmap); | ||
1204 | |||
1205 | return 0; | 1183 | return 0; |
1206 | } | 1184 | } |
1207 | 1185 | ||
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index 1d4c5cf47b06..715788de442e 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c | |||
@@ -882,7 +882,7 @@ static int __devinit wm8988_spi_probe(struct spi_device *spi) | |||
882 | if (wm8988 == NULL) | 882 | if (wm8988 == NULL) |
883 | return -ENOMEM; | 883 | return -ENOMEM; |
884 | 884 | ||
885 | wm8988->regmap = regmap_init_spi(spi, &wm8988_regmap); | 885 | wm8988->regmap = devm_regmap_init_spi(spi, &wm8988_regmap); |
886 | if (IS_ERR(wm8988->regmap)) { | 886 | if (IS_ERR(wm8988->regmap)) { |
887 | ret = PTR_ERR(wm8988->regmap); | 887 | ret = PTR_ERR(wm8988->regmap); |
888 | dev_err(&spi->dev, "Failed to init regmap: %d\n", ret); | 888 | dev_err(&spi->dev, "Failed to init regmap: %d\n", ret); |
@@ -893,17 +893,12 @@ static int __devinit wm8988_spi_probe(struct spi_device *spi) | |||
893 | 893 | ||
894 | ret = snd_soc_register_codec(&spi->dev, | 894 | ret = snd_soc_register_codec(&spi->dev, |
895 | &soc_codec_dev_wm8988, &wm8988_dai, 1); | 895 | &soc_codec_dev_wm8988, &wm8988_dai, 1); |
896 | if (ret != 0) | ||
897 | regmap_exit(wm8988->regmap); | ||
898 | |||
899 | return ret; | 896 | return ret; |
900 | } | 897 | } |
901 | 898 | ||
902 | static int __devexit wm8988_spi_remove(struct spi_device *spi) | 899 | static int __devexit wm8988_spi_remove(struct spi_device *spi) |
903 | { | 900 | { |
904 | struct wm8988_priv *wm8988 = spi_get_drvdata(spi); | ||
905 | snd_soc_unregister_codec(&spi->dev); | 901 | snd_soc_unregister_codec(&spi->dev); |
906 | regmap_exit(wm8988->regmap); | ||
907 | return 0; | 902 | return 0; |
908 | } | 903 | } |
909 | 904 | ||
@@ -931,7 +926,7 @@ static __devinit int wm8988_i2c_probe(struct i2c_client *i2c, | |||
931 | 926 | ||
932 | i2c_set_clientdata(i2c, wm8988); | 927 | i2c_set_clientdata(i2c, wm8988); |
933 | 928 | ||
934 | wm8988->regmap = regmap_init_i2c(i2c, &wm8988_regmap); | 929 | wm8988->regmap = devm_regmap_init_i2c(i2c, &wm8988_regmap); |
935 | if (IS_ERR(wm8988->regmap)) { | 930 | if (IS_ERR(wm8988->regmap)) { |
936 | ret = PTR_ERR(wm8988->regmap); | 931 | ret = PTR_ERR(wm8988->regmap); |
937 | dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret); | 932 | dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret); |
@@ -940,17 +935,12 @@ static __devinit int wm8988_i2c_probe(struct i2c_client *i2c, | |||
940 | 935 | ||
941 | ret = snd_soc_register_codec(&i2c->dev, | 936 | ret = snd_soc_register_codec(&i2c->dev, |
942 | &soc_codec_dev_wm8988, &wm8988_dai, 1); | 937 | &soc_codec_dev_wm8988, &wm8988_dai, 1); |
943 | if (ret != 0) | ||
944 | regmap_exit(wm8988->regmap); | ||
945 | |||
946 | return ret; | 938 | return ret; |
947 | } | 939 | } |
948 | 940 | ||
949 | static __devexit int wm8988_i2c_remove(struct i2c_client *client) | 941 | static __devexit int wm8988_i2c_remove(struct i2c_client *client) |
950 | { | 942 | { |
951 | struct wm8988_priv *wm8988 = i2c_get_clientdata(client); | ||
952 | snd_soc_unregister_codec(&client->dev); | 943 | snd_soc_unregister_codec(&client->dev); |
953 | regmap_exit(wm8988->regmap); | ||
954 | return 0; | 944 | return 0; |
955 | } | 945 | } |
956 | 946 | ||
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 94737a30716b..347a359a7c86 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c | |||
@@ -1660,7 +1660,7 @@ static __devinit int wm8993_i2c_probe(struct i2c_client *i2c, | |||
1660 | wm8993->dev = &i2c->dev; | 1660 | wm8993->dev = &i2c->dev; |
1661 | init_completion(&wm8993->fll_lock); | 1661 | init_completion(&wm8993->fll_lock); |
1662 | 1662 | ||
1663 | wm8993->regmap = regmap_init_i2c(i2c, &wm8993_regmap); | 1663 | wm8993->regmap = devm_regmap_init_i2c(i2c, &wm8993_regmap); |
1664 | if (IS_ERR(wm8993->regmap)) { | 1664 | if (IS_ERR(wm8993->regmap)) { |
1665 | ret = PTR_ERR(wm8993->regmap); | 1665 | ret = PTR_ERR(wm8993->regmap); |
1666 | dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret); | 1666 | dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret); |
@@ -1672,18 +1672,18 @@ static __devinit int wm8993_i2c_probe(struct i2c_client *i2c, | |||
1672 | for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++) | 1672 | for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++) |
1673 | wm8993->supplies[i].supply = wm8993_supply_names[i]; | 1673 | wm8993->supplies[i].supply = wm8993_supply_names[i]; |
1674 | 1674 | ||
1675 | ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8993->supplies), | 1675 | ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8993->supplies), |
1676 | wm8993->supplies); | 1676 | wm8993->supplies); |
1677 | if (ret != 0) { | 1677 | if (ret != 0) { |
1678 | dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); | 1678 | dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); |
1679 | goto err; | 1679 | return ret; |
1680 | } | 1680 | } |
1681 | 1681 | ||
1682 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies), | 1682 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies), |
1683 | wm8993->supplies); | 1683 | wm8993->supplies); |
1684 | if (ret != 0) { | 1684 | if (ret != 0) { |
1685 | dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); | 1685 | dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); |
1686 | goto err_get; | 1686 | return ret; |
1687 | } | 1687 | } |
1688 | 1688 | ||
1689 | ret = regmap_read(wm8993->regmap, WM8993_SOFTWARE_RESET, ®); | 1689 | ret = regmap_read(wm8993->regmap, WM8993_SOFTWARE_RESET, ®); |
@@ -1742,10 +1742,6 @@ err_irq: | |||
1742 | free_irq(i2c->irq, wm8993); | 1742 | free_irq(i2c->irq, wm8993); |
1743 | err_enable: | 1743 | err_enable: |
1744 | regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); | 1744 | regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); |
1745 | err_get: | ||
1746 | regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); | ||
1747 | err: | ||
1748 | regmap_exit(wm8993->regmap); | ||
1749 | return ret; | 1745 | return ret; |
1750 | } | 1746 | } |
1751 | 1747 | ||
@@ -1756,9 +1752,7 @@ static __devexit int wm8993_i2c_remove(struct i2c_client *i2c) | |||
1756 | snd_soc_unregister_codec(&i2c->dev); | 1752 | snd_soc_unregister_codec(&i2c->dev); |
1757 | if (i2c->irq) | 1753 | if (i2c->irq) |
1758 | free_irq(i2c->irq, wm8993); | 1754 | free_irq(i2c->irq, wm8993); |
1759 | regmap_exit(wm8993->regmap); | ||
1760 | regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); | 1755 | regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); |
1761 | regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); | ||
1762 | 1756 | ||
1763 | return 0; | 1757 | return 0; |
1764 | } | 1758 | } |
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index b2b2b37131bd..302f69a8ac22 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -110,13 +110,13 @@ static const struct wm8958_micd_rate jackdet_rates[] = { | |||
110 | static void wm8958_micd_set_rate(struct snd_soc_codec *codec) | 110 | static void wm8958_micd_set_rate(struct snd_soc_codec *codec) |
111 | { | 111 | { |
112 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 112 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
113 | struct wm8994 *control = wm8994->wm8994; | ||
113 | int best, i, sysclk, val; | 114 | int best, i, sysclk, val; |
114 | bool idle; | 115 | bool idle; |
115 | const struct wm8958_micd_rate *rates; | 116 | const struct wm8958_micd_rate *rates; |
116 | int num_rates; | 117 | int num_rates; |
117 | 118 | ||
118 | if (!(wm8994->pdata && wm8994->pdata->micd_rates) && | 119 | if (wm8994->jack_cb != wm8958_default_micdet) |
119 | wm8994->jack_cb != wm8958_default_micdet) | ||
120 | return; | 120 | return; |
121 | 121 | ||
122 | idle = !wm8994->jack_mic; | 122 | idle = !wm8994->jack_mic; |
@@ -127,9 +127,9 @@ static void wm8958_micd_set_rate(struct snd_soc_codec *codec) | |||
127 | else | 127 | else |
128 | sysclk = wm8994->aifclk[0]; | 128 | sysclk = wm8994->aifclk[0]; |
129 | 129 | ||
130 | if (wm8994->pdata && wm8994->pdata->micd_rates) { | 130 | if (control->pdata.micd_rates) { |
131 | rates = wm8994->pdata->micd_rates; | 131 | rates = control->pdata.micd_rates; |
132 | num_rates = wm8994->pdata->num_micd_rates; | 132 | num_rates = control->pdata.num_micd_rates; |
133 | } else if (wm8994->jackdet) { | 133 | } else if (wm8994->jackdet) { |
134 | rates = jackdet_rates; | 134 | rates = jackdet_rates; |
135 | num_rates = ARRAY_SIZE(jackdet_rates); | 135 | num_rates = ARRAY_SIZE(jackdet_rates); |
@@ -326,7 +326,8 @@ static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol, | |||
326 | static void wm8994_set_drc(struct snd_soc_codec *codec, int drc) | 326 | static void wm8994_set_drc(struct snd_soc_codec *codec, int drc) |
327 | { | 327 | { |
328 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 328 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
329 | struct wm8994_pdata *pdata = wm8994->pdata; | 329 | struct wm8994 *control = wm8994->wm8994; |
330 | struct wm8994_pdata *pdata = &control->pdata; | ||
330 | int base = wm8994_drc_base[drc]; | 331 | int base = wm8994_drc_base[drc]; |
331 | int cfg = wm8994->drc_cfg[drc]; | 332 | int cfg = wm8994->drc_cfg[drc]; |
332 | int save, i; | 333 | int save, i; |
@@ -362,7 +363,8 @@ static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol, | |||
362 | { | 363 | { |
363 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 364 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
364 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 365 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
365 | struct wm8994_pdata *pdata = wm8994->pdata; | 366 | struct wm8994 *control = wm8994->wm8994; |
367 | struct wm8994_pdata *pdata = &control->pdata; | ||
366 | int drc = wm8994_get_drc(kcontrol->id.name); | 368 | int drc = wm8994_get_drc(kcontrol->id.name); |
367 | int value = ucontrol->value.integer.value[0]; | 369 | int value = ucontrol->value.integer.value[0]; |
368 | 370 | ||
@@ -394,7 +396,8 @@ static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol, | |||
394 | static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block) | 396 | static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block) |
395 | { | 397 | { |
396 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 398 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
397 | struct wm8994_pdata *pdata = wm8994->pdata; | 399 | struct wm8994 *control = wm8994->wm8994; |
400 | struct wm8994_pdata *pdata = &control->pdata; | ||
398 | int base = wm8994_retune_mobile_base[block]; | 401 | int base = wm8994_retune_mobile_base[block]; |
399 | int iface, best, best_val, save, i, cfg; | 402 | int iface, best, best_val, save, i, cfg; |
400 | 403 | ||
@@ -465,7 +468,8 @@ static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, | |||
465 | { | 468 | { |
466 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 469 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
467 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 470 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
468 | struct wm8994_pdata *pdata = wm8994->pdata; | 471 | struct wm8994 *control = wm8994->wm8994; |
472 | struct wm8994_pdata *pdata = &control->pdata; | ||
469 | int block = wm8994_get_retune_mobile_block(kcontrol->id.name); | 473 | int block = wm8994_get_retune_mobile_block(kcontrol->id.name); |
470 | int value = ucontrol->value.integer.value[0]; | 474 | int value = ucontrol->value.integer.value[0]; |
471 | 475 | ||
@@ -862,7 +866,7 @@ static void vmid_reference(struct snd_soc_codec *codec) | |||
862 | WM8994_BIAS_SRC | | 866 | WM8994_BIAS_SRC | |
863 | WM8994_STARTUP_BIAS_ENA | | 867 | WM8994_STARTUP_BIAS_ENA | |
864 | WM8994_VMID_BUF_ENA | | 868 | WM8994_VMID_BUF_ENA | |
865 | (0x3 << WM8994_VMID_RAMP_SHIFT)); | 869 | (0x2 << WM8994_VMID_RAMP_SHIFT)); |
866 | 870 | ||
867 | /* Main bias enable, VMID=2x40k */ | 871 | /* Main bias enable, VMID=2x40k */ |
868 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, | 872 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, |
@@ -870,7 +874,7 @@ static void vmid_reference(struct snd_soc_codec *codec) | |||
870 | WM8994_VMID_SEL_MASK, | 874 | WM8994_VMID_SEL_MASK, |
871 | WM8994_BIAS_ENA | 0x2); | 875 | WM8994_BIAS_ENA | 0x2); |
872 | 876 | ||
873 | msleep(50); | 877 | msleep(300); |
874 | 878 | ||
875 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | 879 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, |
876 | WM8994_VMID_RAMP_MASK | | 880 | WM8994_VMID_RAMP_MASK | |
@@ -939,16 +943,10 @@ static void vmid_dereference(struct snd_soc_codec *codec) | |||
939 | WM8994_BIAS_SRC | | 943 | WM8994_BIAS_SRC | |
940 | WM8994_VMID_DISCH); | 944 | WM8994_VMID_DISCH); |
941 | 945 | ||
942 | switch (wm8994->vmid_mode) { | 946 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, |
943 | case WM8994_VMID_FORCE: | 947 | WM8994_VMID_SEL_MASK, 0); |
944 | msleep(350); | ||
945 | break; | ||
946 | default: | ||
947 | break; | ||
948 | } | ||
949 | 948 | ||
950 | snd_soc_update_bits(codec, WM8994_ADDITIONAL_CONTROL, | 949 | msleep(400); |
951 | WM8994_VROI, WM8994_VROI); | ||
952 | 950 | ||
953 | /* Active discharge */ | 951 | /* Active discharge */ |
954 | snd_soc_update_bits(codec, WM8994_ANTIPOP_1, | 952 | snd_soc_update_bits(codec, WM8994_ANTIPOP_1, |
@@ -957,17 +955,12 @@ static void vmid_dereference(struct snd_soc_codec *codec) | |||
957 | WM8994_LINEOUT1_DISCH | | 955 | WM8994_LINEOUT1_DISCH | |
958 | WM8994_LINEOUT2_DISCH); | 956 | WM8994_LINEOUT2_DISCH); |
959 | 957 | ||
960 | msleep(150); | ||
961 | |||
962 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_3, | 958 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_3, |
963 | WM8994_LINEOUT1N_ENA | | 959 | WM8994_LINEOUT1N_ENA | |
964 | WM8994_LINEOUT1P_ENA | | 960 | WM8994_LINEOUT1P_ENA | |
965 | WM8994_LINEOUT2N_ENA | | 961 | WM8994_LINEOUT2N_ENA | |
966 | WM8994_LINEOUT2P_ENA, 0); | 962 | WM8994_LINEOUT2P_ENA, 0); |
967 | 963 | ||
968 | snd_soc_update_bits(codec, WM8994_ADDITIONAL_CONTROL, | ||
969 | WM8994_VROI, 0); | ||
970 | |||
971 | /* Switch off startup biases */ | 964 | /* Switch off startup biases */ |
972 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | 965 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, |
973 | WM8994_BIAS_SRC | | 966 | WM8994_BIAS_SRC | |
@@ -976,10 +969,7 @@ static void vmid_dereference(struct snd_soc_codec *codec) | |||
976 | WM8994_VMID_RAMP_MASK, 0); | 969 | WM8994_VMID_RAMP_MASK, 0); |
977 | 970 | ||
978 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, | 971 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, |
979 | WM8994_BIAS_ENA | WM8994_VMID_SEL_MASK, 0); | 972 | WM8994_VMID_SEL_MASK, 0); |
980 | |||
981 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | ||
982 | WM8994_VMID_RAMP_MASK, 0); | ||
983 | } | 973 | } |
984 | 974 | ||
985 | pm_runtime_put(codec->dev); | 975 | pm_runtime_put(codec->dev); |
@@ -2277,6 +2267,18 @@ out: | |||
2277 | 2267 | ||
2278 | configure_clock(codec); | 2268 | configure_clock(codec); |
2279 | 2269 | ||
2270 | /* | ||
2271 | * If SYSCLK will be less than 50kHz adjust AIFnCLK dividers | ||
2272 | * for detection. | ||
2273 | */ | ||
2274 | if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) { | ||
2275 | dev_dbg(codec->dev, "Configuring AIFs for 128fs\n"); | ||
2276 | snd_soc_update_bits(codec, WM8994_AIF1_RATE, | ||
2277 | WM8994_AIF1CLK_RATE_MASK, 0x1); | ||
2278 | snd_soc_update_bits(codec, WM8994_AIF2_RATE, | ||
2279 | WM8994_AIF2CLK_RATE_MASK, 0x1); | ||
2280 | } | ||
2281 | |||
2280 | return 0; | 2282 | return 0; |
2281 | } | 2283 | } |
2282 | 2284 | ||
@@ -2365,6 +2367,18 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, | |||
2365 | 2367 | ||
2366 | configure_clock(codec); | 2368 | configure_clock(codec); |
2367 | 2369 | ||
2370 | /* | ||
2371 | * If SYSCLK will be less than 50kHz adjust AIFnCLK dividers | ||
2372 | * for detection. | ||
2373 | */ | ||
2374 | if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) { | ||
2375 | dev_dbg(codec->dev, "Configuring AIFs for 128fs\n"); | ||
2376 | snd_soc_update_bits(codec, WM8994_AIF1_RATE, | ||
2377 | WM8994_AIF1CLK_RATE_MASK, 0x1); | ||
2378 | snd_soc_update_bits(codec, WM8994_AIF2_RATE, | ||
2379 | WM8994_AIF2CLK_RATE_MASK, 0x1); | ||
2380 | } | ||
2381 | |||
2368 | return 0; | 2382 | return 0; |
2369 | } | 2383 | } |
2370 | 2384 | ||
@@ -3082,7 +3096,8 @@ static int wm8994_codec_resume(struct snd_soc_codec *codec) | |||
3082 | static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) | 3096 | static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) |
3083 | { | 3097 | { |
3084 | struct snd_soc_codec *codec = wm8994->hubs.codec; | 3098 | struct snd_soc_codec *codec = wm8994->hubs.codec; |
3085 | struct wm8994_pdata *pdata = wm8994->pdata; | 3099 | struct wm8994 *control = wm8994->wm8994; |
3100 | struct wm8994_pdata *pdata = &control->pdata; | ||
3086 | struct snd_kcontrol_new controls[] = { | 3101 | struct snd_kcontrol_new controls[] = { |
3087 | SOC_ENUM_EXT("AIF1.1 EQ Mode", | 3102 | SOC_ENUM_EXT("AIF1.1 EQ Mode", |
3088 | wm8994->retune_mobile_enum, | 3103 | wm8994->retune_mobile_enum, |
@@ -3149,7 +3164,8 @@ static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) | |||
3149 | static void wm8994_handle_pdata(struct wm8994_priv *wm8994) | 3164 | static void wm8994_handle_pdata(struct wm8994_priv *wm8994) |
3150 | { | 3165 | { |
3151 | struct snd_soc_codec *codec = wm8994->hubs.codec; | 3166 | struct snd_soc_codec *codec = wm8994->hubs.codec; |
3152 | struct wm8994_pdata *pdata = wm8994->pdata; | 3167 | struct wm8994 *control = wm8994->wm8994; |
3168 | struct wm8994_pdata *pdata = &control->pdata; | ||
3153 | int ret, i; | 3169 | int ret, i; |
3154 | 3170 | ||
3155 | if (!pdata) | 3171 | if (!pdata) |
@@ -3451,7 +3467,7 @@ static void wm8958_default_micdet(u16 status, void *data) | |||
3451 | 3467 | ||
3452 | mutex_unlock(&wm8994->accdet_lock); | 3468 | mutex_unlock(&wm8994->accdet_lock); |
3453 | 3469 | ||
3454 | if (wm8994->pdata->jd_ext_cap) | 3470 | if (wm8994->wm8994->pdata.jd_ext_cap) |
3455 | snd_soc_dapm_disable_pin(&codec->dapm, | 3471 | snd_soc_dapm_disable_pin(&codec->dapm, |
3456 | "MICBIAS2"); | 3472 | "MICBIAS2"); |
3457 | } | 3473 | } |
@@ -3486,11 +3502,48 @@ static void wm8958_default_micdet(u16 status, void *data) | |||
3486 | } | 3502 | } |
3487 | } | 3503 | } |
3488 | 3504 | ||
3505 | /* Deferred mic detection to allow for extra settling time */ | ||
3506 | static void wm1811_mic_work(struct work_struct *work) | ||
3507 | { | ||
3508 | struct wm8994_priv *wm8994 = container_of(work, struct wm8994_priv, | ||
3509 | mic_work.work); | ||
3510 | struct wm8994 *control = wm8994->wm8994; | ||
3511 | struct snd_soc_codec *codec = wm8994->hubs.codec; | ||
3512 | |||
3513 | pm_runtime_get_sync(codec->dev); | ||
3514 | |||
3515 | /* If required for an external cap force MICBIAS on */ | ||
3516 | if (control->pdata.jd_ext_cap) { | ||
3517 | snd_soc_dapm_force_enable_pin(&codec->dapm, | ||
3518 | "MICBIAS2"); | ||
3519 | snd_soc_dapm_sync(&codec->dapm); | ||
3520 | } | ||
3521 | |||
3522 | mutex_lock(&wm8994->accdet_lock); | ||
3523 | |||
3524 | dev_dbg(codec->dev, "Starting mic detection\n"); | ||
3525 | |||
3526 | /* | ||
3527 | * Start off measument of microphone impedence to find out | ||
3528 | * what's actually there. | ||
3529 | */ | ||
3530 | wm8994->mic_detecting = true; | ||
3531 | wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC); | ||
3532 | |||
3533 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, | ||
3534 | WM8958_MICD_ENA, WM8958_MICD_ENA); | ||
3535 | |||
3536 | mutex_unlock(&wm8994->accdet_lock); | ||
3537 | |||
3538 | pm_runtime_put(codec->dev); | ||
3539 | } | ||
3540 | |||
3489 | static irqreturn_t wm1811_jackdet_irq(int irq, void *data) | 3541 | static irqreturn_t wm1811_jackdet_irq(int irq, void *data) |
3490 | { | 3542 | { |
3491 | struct wm8994_priv *wm8994 = data; | 3543 | struct wm8994_priv *wm8994 = data; |
3544 | struct wm8994 *control = wm8994->wm8994; | ||
3492 | struct snd_soc_codec *codec = wm8994->hubs.codec; | 3545 | struct snd_soc_codec *codec = wm8994->hubs.codec; |
3493 | int reg; | 3546 | int reg, delay; |
3494 | bool present; | 3547 | bool present; |
3495 | 3548 | ||
3496 | pm_runtime_get_sync(codec->dev); | 3549 | pm_runtime_get_sync(codec->dev); |
@@ -3521,18 +3574,14 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) | |||
3521 | snd_soc_update_bits(codec, WM1811_JACKDET_CTRL, | 3574 | snd_soc_update_bits(codec, WM1811_JACKDET_CTRL, |
3522 | WM1811_JACKDET_DB, 0); | 3575 | WM1811_JACKDET_DB, 0); |
3523 | 3576 | ||
3524 | /* | 3577 | delay = control->pdata.micdet_delay; |
3525 | * Start off measument of microphone impedence to find | 3578 | schedule_delayed_work(&wm8994->mic_work, |
3526 | * out what's actually there. | 3579 | msecs_to_jiffies(delay)); |
3527 | */ | ||
3528 | wm8994->mic_detecting = true; | ||
3529 | wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC); | ||
3530 | |||
3531 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, | ||
3532 | WM8958_MICD_ENA, WM8958_MICD_ENA); | ||
3533 | } else { | 3580 | } else { |
3534 | dev_dbg(codec->dev, "Jack not detected\n"); | 3581 | dev_dbg(codec->dev, "Jack not detected\n"); |
3535 | 3582 | ||
3583 | cancel_delayed_work_sync(&wm8994->mic_work); | ||
3584 | |||
3536 | snd_soc_update_bits(codec, WM8958_MICBIAS2, | 3585 | snd_soc_update_bits(codec, WM8958_MICBIAS2, |
3537 | WM8958_MICB2_DISCH, WM8958_MICB2_DISCH); | 3586 | WM8958_MICB2_DISCH, WM8958_MICB2_DISCH); |
3538 | 3587 | ||
@@ -3549,14 +3598,9 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) | |||
3549 | 3598 | ||
3550 | mutex_unlock(&wm8994->accdet_lock); | 3599 | mutex_unlock(&wm8994->accdet_lock); |
3551 | 3600 | ||
3552 | /* If required for an external cap force MICBIAS on */ | 3601 | /* Turn off MICBIAS if it was on for an external cap */ |
3553 | if (wm8994->pdata->jd_ext_cap) { | 3602 | if (control->pdata.jd_ext_cap && !present) |
3554 | if (present) | 3603 | snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2"); |
3555 | snd_soc_dapm_force_enable_pin(&codec->dapm, | ||
3556 | "MICBIAS2"); | ||
3557 | else | ||
3558 | snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2"); | ||
3559 | } | ||
3560 | 3604 | ||
3561 | if (present) | 3605 | if (present) |
3562 | snd_soc_jack_report(wm8994->micdet[0].jack, | 3606 | snd_soc_jack_report(wm8994->micdet[0].jack, |
@@ -3633,8 +3677,8 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | |||
3633 | wm8958_micd_set_rate(codec); | 3677 | wm8958_micd_set_rate(codec); |
3634 | 3678 | ||
3635 | /* Detect microphones and short circuits by default */ | 3679 | /* Detect microphones and short circuits by default */ |
3636 | if (wm8994->pdata->micd_lvl_sel) | 3680 | if (control->pdata.micd_lvl_sel) |
3637 | micd_lvl_sel = wm8994->pdata->micd_lvl_sel; | 3681 | micd_lvl_sel = control->pdata.micd_lvl_sel; |
3638 | else | 3682 | else |
3639 | micd_lvl_sel = 0x41; | 3683 | micd_lvl_sel = 0x41; |
3640 | 3684 | ||
@@ -3779,15 +3823,24 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3779 | snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); | 3823 | snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); |
3780 | 3824 | ||
3781 | mutex_init(&wm8994->accdet_lock); | 3825 | mutex_init(&wm8994->accdet_lock); |
3782 | INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work); | ||
3783 | INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap, | 3826 | INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap, |
3784 | wm1811_jackdet_bootstrap); | 3827 | wm1811_jackdet_bootstrap); |
3785 | 3828 | ||
3829 | switch (control->type) { | ||
3830 | case WM8994: | ||
3831 | INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work); | ||
3832 | break; | ||
3833 | case WM1811: | ||
3834 | INIT_DELAYED_WORK(&wm8994->mic_work, wm1811_mic_work); | ||
3835 | break; | ||
3836 | default: | ||
3837 | break; | ||
3838 | } | ||
3839 | |||
3786 | for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) | 3840 | for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) |
3787 | init_completion(&wm8994->fll_locked[i]); | 3841 | init_completion(&wm8994->fll_locked[i]); |
3788 | 3842 | ||
3789 | if (wm8994->pdata && wm8994->pdata->micdet_irq) | 3843 | wm8994->micdet_irq = control->pdata.micdet_irq; |
3790 | wm8994->micdet_irq = wm8994->pdata->micdet_irq; | ||
3791 | 3844 | ||
3792 | pm_runtime_enable(codec->dev); | 3845 | pm_runtime_enable(codec->dev); |
3793 | pm_runtime_idle(codec->dev); | 3846 | pm_runtime_idle(codec->dev); |
@@ -3800,8 +3853,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3800 | switch (control->type) { | 3853 | switch (control->type) { |
3801 | case WM8994: | 3854 | case WM8994: |
3802 | /* Single ended line outputs should have VMID on. */ | 3855 | /* Single ended line outputs should have VMID on. */ |
3803 | if (!wm8994->pdata->lineout1_diff || | 3856 | if (!control->pdata.lineout1_diff || |
3804 | !wm8994->pdata->lineout2_diff) | 3857 | !control->pdata.lineout2_diff) |
3805 | codec->dapm.idle_bias_off = 0; | 3858 | codec->dapm.idle_bias_off = 0; |
3806 | 3859 | ||
3807 | switch (wm8994->revision) { | 3860 | switch (wm8994->revision) { |
@@ -3839,20 +3892,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3839 | wm8994->hubs.no_cache_dac_hp_direct = true; | 3892 | wm8994->hubs.no_cache_dac_hp_direct = true; |
3840 | wm8994->fll_byp = true; | 3893 | wm8994->fll_byp = true; |
3841 | 3894 | ||
3842 | switch (control->cust_id) { | 3895 | wm8994->hubs.dcs_codes_l = -9; |
3843 | case 0: | 3896 | wm8994->hubs.dcs_codes_r = -7; |
3844 | case 2: | ||
3845 | wm8994->hubs.dcs_codes_l = -9; | ||
3846 | wm8994->hubs.dcs_codes_r = -7; | ||
3847 | break; | ||
3848 | case 1: | ||
3849 | case 3: | ||
3850 | wm8994->hubs.dcs_codes_l = -8; | ||
3851 | wm8994->hubs.dcs_codes_r = -7; | ||
3852 | break; | ||
3853 | default: | ||
3854 | break; | ||
3855 | } | ||
3856 | 3897 | ||
3857 | snd_soc_update_bits(codec, WM8994_ANALOGUE_HP_1, | 3898 | snd_soc_update_bits(codec, WM8994_ANALOGUE_HP_1, |
3858 | WM1811_HPOUT1_ATTN, WM1811_HPOUT1_ATTN); | 3899 | WM1811_HPOUT1_ATTN, WM1811_HPOUT1_ATTN); |
@@ -4236,7 +4277,6 @@ static int __devinit wm8994_probe(struct platform_device *pdev) | |||
4236 | platform_set_drvdata(pdev, wm8994); | 4277 | platform_set_drvdata(pdev, wm8994); |
4237 | 4278 | ||
4238 | wm8994->wm8994 = dev_get_drvdata(pdev->dev.parent); | 4279 | wm8994->wm8994 = dev_get_drvdata(pdev->dev.parent); |
4239 | wm8994->pdata = dev_get_platdata(pdev->dev.parent); | ||
4240 | 4280 | ||
4241 | return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8994, | 4281 | return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8994, |
4242 | wm8994_dai, ARRAY_SIZE(wm8994_dai)); | 4282 | wm8994_dai, ARRAY_SIZE(wm8994_dai)); |
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index ccbce5791e95..3120c0f21d4d 100644 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h | |||
@@ -143,7 +143,6 @@ struct wm8994_priv { | |||
143 | int micdet_irq; | 143 | int micdet_irq; |
144 | 144 | ||
145 | int revision; | 145 | int revision; |
146 | struct wm8994_pdata *pdata; | ||
147 | 146 | ||
148 | unsigned int aif1clk_enable:1; | 147 | unsigned int aif1clk_enable:1; |
149 | unsigned int aif2clk_enable:1; | 148 | unsigned int aif2clk_enable:1; |
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c index 28c89b094c6e..f1a7cf147af0 100644 --- a/sound/soc/codecs/wm8995.c +++ b/sound/soc/codecs/wm8995.c | |||
@@ -2261,41 +2261,28 @@ static int __devinit wm8995_spi_probe(struct spi_device *spi) | |||
2261 | struct wm8995_priv *wm8995; | 2261 | struct wm8995_priv *wm8995; |
2262 | int ret; | 2262 | int ret; |
2263 | 2263 | ||
2264 | wm8995 = kzalloc(sizeof *wm8995, GFP_KERNEL); | 2264 | wm8995 = devm_kzalloc(&spi->dev, sizeof(*wm8995), GFP_KERNEL); |
2265 | if (!wm8995) | 2265 | if (!wm8995) |
2266 | return -ENOMEM; | 2266 | return -ENOMEM; |
2267 | 2267 | ||
2268 | spi_set_drvdata(spi, wm8995); | 2268 | spi_set_drvdata(spi, wm8995); |
2269 | 2269 | ||
2270 | wm8995->regmap = regmap_init_spi(spi, &wm8995_regmap); | 2270 | wm8995->regmap = devm_regmap_init_spi(spi, &wm8995_regmap); |
2271 | if (IS_ERR(wm8995->regmap)) { | 2271 | if (IS_ERR(wm8995->regmap)) { |
2272 | ret = PTR_ERR(wm8995->regmap); | 2272 | ret = PTR_ERR(wm8995->regmap); |
2273 | dev_err(&spi->dev, "Failed to register regmap: %d\n", ret); | 2273 | dev_err(&spi->dev, "Failed to register regmap: %d\n", ret); |
2274 | goto err_alloc; | 2274 | return ret; |
2275 | } | 2275 | } |
2276 | 2276 | ||
2277 | ret = snd_soc_register_codec(&spi->dev, | 2277 | ret = snd_soc_register_codec(&spi->dev, |
2278 | &soc_codec_dev_wm8995, wm8995_dai, | 2278 | &soc_codec_dev_wm8995, wm8995_dai, |
2279 | ARRAY_SIZE(wm8995_dai)); | 2279 | ARRAY_SIZE(wm8995_dai)); |
2280 | if (ret < 0) | ||
2281 | goto err_regmap; | ||
2282 | |||
2283 | return ret; | ||
2284 | |||
2285 | err_regmap: | ||
2286 | regmap_exit(wm8995->regmap); | ||
2287 | err_alloc: | ||
2288 | kfree(wm8995); | ||
2289 | |||
2290 | return ret; | 2280 | return ret; |
2291 | } | 2281 | } |
2292 | 2282 | ||
2293 | static int __devexit wm8995_spi_remove(struct spi_device *spi) | 2283 | static int __devexit wm8995_spi_remove(struct spi_device *spi) |
2294 | { | 2284 | { |
2295 | struct wm8995_priv *wm8995 = spi_get_drvdata(spi); | ||
2296 | snd_soc_unregister_codec(&spi->dev); | 2285 | snd_soc_unregister_codec(&spi->dev); |
2297 | regmap_exit(wm8995->regmap); | ||
2298 | kfree(wm8995); | ||
2299 | return 0; | 2286 | return 0; |
2300 | } | 2287 | } |
2301 | 2288 | ||
@@ -2316,44 +2303,31 @@ static __devinit int wm8995_i2c_probe(struct i2c_client *i2c, | |||
2316 | struct wm8995_priv *wm8995; | 2303 | struct wm8995_priv *wm8995; |
2317 | int ret; | 2304 | int ret; |
2318 | 2305 | ||
2319 | wm8995 = kzalloc(sizeof *wm8995, GFP_KERNEL); | 2306 | wm8995 = devm_kzalloc(&i2c->dev, sizeof(*wm8995), GFP_KERNEL); |
2320 | if (!wm8995) | 2307 | if (!wm8995) |
2321 | return -ENOMEM; | 2308 | return -ENOMEM; |
2322 | 2309 | ||
2323 | i2c_set_clientdata(i2c, wm8995); | 2310 | i2c_set_clientdata(i2c, wm8995); |
2324 | 2311 | ||
2325 | wm8995->regmap = regmap_init_i2c(i2c, &wm8995_regmap); | 2312 | wm8995->regmap = devm_regmap_init_i2c(i2c, &wm8995_regmap); |
2326 | if (IS_ERR(wm8995->regmap)) { | 2313 | if (IS_ERR(wm8995->regmap)) { |
2327 | ret = PTR_ERR(wm8995->regmap); | 2314 | ret = PTR_ERR(wm8995->regmap); |
2328 | dev_err(&i2c->dev, "Failed to register regmap: %d\n", ret); | 2315 | dev_err(&i2c->dev, "Failed to register regmap: %d\n", ret); |
2329 | goto err_alloc; | 2316 | return ret; |
2330 | } | 2317 | } |
2331 | 2318 | ||
2332 | ret = snd_soc_register_codec(&i2c->dev, | 2319 | ret = snd_soc_register_codec(&i2c->dev, |
2333 | &soc_codec_dev_wm8995, wm8995_dai, | 2320 | &soc_codec_dev_wm8995, wm8995_dai, |
2334 | ARRAY_SIZE(wm8995_dai)); | 2321 | ARRAY_SIZE(wm8995_dai)); |
2335 | if (ret < 0) { | 2322 | if (ret < 0) |
2336 | dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); | 2323 | dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); |
2337 | goto err_regmap; | ||
2338 | } | ||
2339 | |||
2340 | return ret; | ||
2341 | |||
2342 | err_regmap: | ||
2343 | regmap_exit(wm8995->regmap); | ||
2344 | err_alloc: | ||
2345 | kfree(wm8995); | ||
2346 | 2324 | ||
2347 | return ret; | 2325 | return ret; |
2348 | } | 2326 | } |
2349 | 2327 | ||
2350 | static __devexit int wm8995_i2c_remove(struct i2c_client *client) | 2328 | static __devexit int wm8995_i2c_remove(struct i2c_client *client) |
2351 | { | 2329 | { |
2352 | struct wm8995_priv *wm8995 = i2c_get_clientdata(client); | ||
2353 | |||
2354 | snd_soc_unregister_codec(&client->dev); | 2330 | snd_soc_unregister_codec(&client->dev); |
2355 | regmap_exit(wm8995->regmap); | ||
2356 | kfree(wm8995); | ||
2357 | return 0; | 2331 | return 0; |
2358 | } | 2332 | } |
2359 | 2333 | ||
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index 2de74e1ea225..860144e85e06 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c | |||
@@ -1341,28 +1341,27 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c, | |||
1341 | 1341 | ||
1342 | i2c_set_clientdata(i2c, wm9081); | 1342 | i2c_set_clientdata(i2c, wm9081); |
1343 | 1343 | ||
1344 | wm9081->regmap = regmap_init_i2c(i2c, &wm9081_regmap); | 1344 | wm9081->regmap = devm_regmap_init_i2c(i2c, &wm9081_regmap); |
1345 | if (IS_ERR(wm9081->regmap)) { | 1345 | if (IS_ERR(wm9081->regmap)) { |
1346 | ret = PTR_ERR(wm9081->regmap); | 1346 | ret = PTR_ERR(wm9081->regmap); |
1347 | dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); | 1347 | dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); |
1348 | goto err; | 1348 | return ret; |
1349 | } | 1349 | } |
1350 | 1350 | ||
1351 | ret = regmap_read(wm9081->regmap, WM9081_SOFTWARE_RESET, ®); | 1351 | ret = regmap_read(wm9081->regmap, WM9081_SOFTWARE_RESET, ®); |
1352 | if (ret != 0) { | 1352 | if (ret != 0) { |
1353 | dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret); | 1353 | dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret); |
1354 | goto err_regmap; | 1354 | return ret; |
1355 | } | 1355 | } |
1356 | if (reg != 0x9081) { | 1356 | if (reg != 0x9081) { |
1357 | dev_err(&i2c->dev, "Device is not a WM9081: ID=0x%x\n", reg); | 1357 | dev_err(&i2c->dev, "Device is not a WM9081: ID=0x%x\n", reg); |
1358 | ret = -EINVAL; | 1358 | return -EINVAL; |
1359 | goto err_regmap; | ||
1360 | } | 1359 | } |
1361 | 1360 | ||
1362 | ret = wm9081_reset(wm9081->regmap); | 1361 | ret = wm9081_reset(wm9081->regmap); |
1363 | if (ret < 0) { | 1362 | if (ret < 0) { |
1364 | dev_err(&i2c->dev, "Failed to issue reset\n"); | 1363 | dev_err(&i2c->dev, "Failed to issue reset\n"); |
1365 | goto err_regmap; | 1364 | return ret; |
1366 | } | 1365 | } |
1367 | 1366 | ||
1368 | if (dev_get_platdata(&i2c->dev)) | 1367 | if (dev_get_platdata(&i2c->dev)) |
@@ -1382,23 +1381,14 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c, | |||
1382 | ret = snd_soc_register_codec(&i2c->dev, | 1381 | ret = snd_soc_register_codec(&i2c->dev, |
1383 | &soc_codec_dev_wm9081, &wm9081_dai, 1); | 1382 | &soc_codec_dev_wm9081, &wm9081_dai, 1); |
1384 | if (ret < 0) | 1383 | if (ret < 0) |
1385 | goto err_regmap; | 1384 | return ret; |
1386 | 1385 | ||
1387 | return 0; | 1386 | return 0; |
1388 | |||
1389 | err_regmap: | ||
1390 | regmap_exit(wm9081->regmap); | ||
1391 | err: | ||
1392 | |||
1393 | return ret; | ||
1394 | } | 1387 | } |
1395 | 1388 | ||
1396 | static __devexit int wm9081_i2c_remove(struct i2c_client *client) | 1389 | static __devexit int wm9081_i2c_remove(struct i2c_client *client) |
1397 | { | 1390 | { |
1398 | struct wm9081_priv *wm9081 = i2c_get_clientdata(client); | ||
1399 | |||
1400 | snd_soc_unregister_codec(&client->dev); | 1391 | snd_soc_unregister_codec(&client->dev); |
1401 | regmap_exit(wm9081->regmap); | ||
1402 | return 0; | 1392 | return 0; |
1403 | } | 1393 | } |
1404 | 1394 | ||
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c index c7ddc56175d1..bb55a70a104a 100644 --- a/sound/soc/codecs/wm9090.c +++ b/sound/soc/codecs/wm9090.c | |||
@@ -628,7 +628,7 @@ static int wm9090_i2c_probe(struct i2c_client *i2c, | |||
628 | return -ENOMEM; | 628 | return -ENOMEM; |
629 | } | 629 | } |
630 | 630 | ||
631 | wm9090->regmap = regmap_init_i2c(i2c, &wm9090_regmap); | 631 | wm9090->regmap = devm_regmap_init_i2c(i2c, &wm9090_regmap); |
632 | if (IS_ERR(wm9090->regmap)) { | 632 | if (IS_ERR(wm9090->regmap)) { |
633 | ret = PTR_ERR(wm9090->regmap); | 633 | ret = PTR_ERR(wm9090->regmap); |
634 | dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret); | 634 | dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret); |
@@ -637,16 +637,16 @@ static int wm9090_i2c_probe(struct i2c_client *i2c, | |||
637 | 637 | ||
638 | ret = regmap_read(wm9090->regmap, WM9090_SOFTWARE_RESET, ®); | 638 | ret = regmap_read(wm9090->regmap, WM9090_SOFTWARE_RESET, ®); |
639 | if (ret < 0) | 639 | if (ret < 0) |
640 | goto err; | 640 | return ret; |
641 | |||
641 | if (reg != 0x9093) { | 642 | if (reg != 0x9093) { |
642 | dev_err(&i2c->dev, "Device is not a WM9090, ID=%x\n", reg); | 643 | dev_err(&i2c->dev, "Device is not a WM9090, ID=%x\n", reg); |
643 | ret = -ENODEV; | 644 | return -ENODEV; |
644 | goto err; | ||
645 | } | 645 | } |
646 | 646 | ||
647 | ret = regmap_write(wm9090->regmap, WM9090_SOFTWARE_RESET, 0); | 647 | ret = regmap_write(wm9090->regmap, WM9090_SOFTWARE_RESET, 0); |
648 | if (ret < 0) | 648 | if (ret < 0) |
649 | goto err; | 649 | return ret; |
650 | 650 | ||
651 | if (i2c->dev.platform_data) | 651 | if (i2c->dev.platform_data) |
652 | memcpy(&wm9090->pdata, i2c->dev.platform_data, | 652 | memcpy(&wm9090->pdata, i2c->dev.platform_data, |
@@ -658,23 +658,15 @@ static int wm9090_i2c_probe(struct i2c_client *i2c, | |||
658 | &soc_codec_dev_wm9090, NULL, 0); | 658 | &soc_codec_dev_wm9090, NULL, 0); |
659 | if (ret != 0) { | 659 | if (ret != 0) { |
660 | dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); | 660 | dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); |
661 | goto err; | 661 | return ret; |
662 | } | 662 | } |
663 | 663 | ||
664 | return 0; | 664 | return 0; |
665 | |||
666 | err: | ||
667 | regmap_exit(wm9090->regmap); | ||
668 | return ret; | ||
669 | } | 665 | } |
670 | 666 | ||
671 | static int __devexit wm9090_i2c_remove(struct i2c_client *i2c) | 667 | static int __devexit wm9090_i2c_remove(struct i2c_client *i2c) |
672 | { | 668 | { |
673 | struct wm9090_priv *wm9090 = i2c_get_clientdata(i2c); | ||
674 | |||
675 | snd_soc_unregister_codec(&i2c->dev); | 669 | snd_soc_unregister_codec(&i2c->dev); |
676 | regmap_exit(wm9090->regmap); | ||
677 | |||
678 | return 0; | 670 | return 0; |
679 | } | 671 | } |
680 | 672 | ||
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c new file mode 100644 index 000000000000..7fdb68ef384e --- /dev/null +++ b/sound/soc/codecs/wm_adsp.c | |||
@@ -0,0 +1,666 @@ | |||
1 | /* | ||
2 | * wm_adsp.c -- Wolfson ADSP support | ||
3 | * | ||
4 | * Copyright 2012 Wolfson Microelectronics plc | ||
5 | * | ||
6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/moduleparam.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/firmware.h> | ||
18 | #include <linux/pm.h> | ||
19 | #include <linux/pm_runtime.h> | ||
20 | #include <linux/regmap.h> | ||
21 | #include <linux/regulator/consumer.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <sound/core.h> | ||
24 | #include <sound/pcm.h> | ||
25 | #include <sound/pcm_params.h> | ||
26 | #include <sound/soc.h> | ||
27 | #include <sound/jack.h> | ||
28 | #include <sound/initval.h> | ||
29 | #include <sound/tlv.h> | ||
30 | |||
31 | #include <linux/mfd/arizona/registers.h> | ||
32 | |||
33 | #include "wm_adsp.h" | ||
34 | |||
35 | #define adsp_crit(_dsp, fmt, ...) \ | ||
36 | dev_crit(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) | ||
37 | #define adsp_err(_dsp, fmt, ...) \ | ||
38 | dev_err(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) | ||
39 | #define adsp_warn(_dsp, fmt, ...) \ | ||
40 | dev_warn(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) | ||
41 | #define adsp_info(_dsp, fmt, ...) \ | ||
42 | dev_info(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) | ||
43 | #define adsp_dbg(_dsp, fmt, ...) \ | ||
44 | dev_dbg(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) | ||
45 | |||
46 | #define ADSP1_CONTROL_1 0x00 | ||
47 | #define ADSP1_CONTROL_2 0x02 | ||
48 | #define ADSP1_CONTROL_3 0x03 | ||
49 | #define ADSP1_CONTROL_4 0x04 | ||
50 | #define ADSP1_CONTROL_5 0x06 | ||
51 | #define ADSP1_CONTROL_6 0x07 | ||
52 | #define ADSP1_CONTROL_7 0x08 | ||
53 | #define ADSP1_CONTROL_8 0x09 | ||
54 | #define ADSP1_CONTROL_9 0x0A | ||
55 | #define ADSP1_CONTROL_10 0x0B | ||
56 | #define ADSP1_CONTROL_11 0x0C | ||
57 | #define ADSP1_CONTROL_12 0x0D | ||
58 | #define ADSP1_CONTROL_13 0x0F | ||
59 | #define ADSP1_CONTROL_14 0x10 | ||
60 | #define ADSP1_CONTROL_15 0x11 | ||
61 | #define ADSP1_CONTROL_16 0x12 | ||
62 | #define ADSP1_CONTROL_17 0x13 | ||
63 | #define ADSP1_CONTROL_18 0x14 | ||
64 | #define ADSP1_CONTROL_19 0x16 | ||
65 | #define ADSP1_CONTROL_20 0x17 | ||
66 | #define ADSP1_CONTROL_21 0x18 | ||
67 | #define ADSP1_CONTROL_22 0x1A | ||
68 | #define ADSP1_CONTROL_23 0x1B | ||
69 | #define ADSP1_CONTROL_24 0x1C | ||
70 | #define ADSP1_CONTROL_25 0x1E | ||
71 | #define ADSP1_CONTROL_26 0x20 | ||
72 | #define ADSP1_CONTROL_27 0x21 | ||
73 | #define ADSP1_CONTROL_28 0x22 | ||
74 | #define ADSP1_CONTROL_29 0x23 | ||
75 | #define ADSP1_CONTROL_30 0x24 | ||
76 | #define ADSP1_CONTROL_31 0x26 | ||
77 | |||
78 | /* | ||
79 | * ADSP1 Control 19 | ||
80 | */ | ||
81 | #define ADSP1_WDMA_BUFFER_LENGTH_MASK 0x00FF /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ | ||
82 | #define ADSP1_WDMA_BUFFER_LENGTH_SHIFT 0 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ | ||
83 | #define ADSP1_WDMA_BUFFER_LENGTH_WIDTH 8 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ | ||
84 | |||
85 | |||
86 | /* | ||
87 | * ADSP1 Control 30 | ||
88 | */ | ||
89 | #define ADSP1_DBG_CLK_ENA 0x0008 /* DSP1_DBG_CLK_ENA */ | ||
90 | #define ADSP1_DBG_CLK_ENA_MASK 0x0008 /* DSP1_DBG_CLK_ENA */ | ||
91 | #define ADSP1_DBG_CLK_ENA_SHIFT 3 /* DSP1_DBG_CLK_ENA */ | ||
92 | #define ADSP1_DBG_CLK_ENA_WIDTH 1 /* DSP1_DBG_CLK_ENA */ | ||
93 | #define ADSP1_SYS_ENA 0x0004 /* DSP1_SYS_ENA */ | ||
94 | #define ADSP1_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */ | ||
95 | #define ADSP1_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */ | ||
96 | #define ADSP1_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */ | ||
97 | #define ADSP1_CORE_ENA 0x0002 /* DSP1_CORE_ENA */ | ||
98 | #define ADSP1_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */ | ||
99 | #define ADSP1_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */ | ||
100 | #define ADSP1_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */ | ||
101 | #define ADSP1_START 0x0001 /* DSP1_START */ | ||
102 | #define ADSP1_START_MASK 0x0001 /* DSP1_START */ | ||
103 | #define ADSP1_START_SHIFT 0 /* DSP1_START */ | ||
104 | #define ADSP1_START_WIDTH 1 /* DSP1_START */ | ||
105 | |||
106 | #define ADSP2_CONTROL 0 | ||
107 | #define ADSP2_CLOCKING 1 | ||
108 | #define ADSP2_STATUS1 4 | ||
109 | |||
110 | /* | ||
111 | * ADSP2 Control | ||
112 | */ | ||
113 | |||
114 | #define ADSP2_MEM_ENA 0x0010 /* DSP1_MEM_ENA */ | ||
115 | #define ADSP2_MEM_ENA_MASK 0x0010 /* DSP1_MEM_ENA */ | ||
116 | #define ADSP2_MEM_ENA_SHIFT 4 /* DSP1_MEM_ENA */ | ||
117 | #define ADSP2_MEM_ENA_WIDTH 1 /* DSP1_MEM_ENA */ | ||
118 | #define ADSP2_SYS_ENA 0x0004 /* DSP1_SYS_ENA */ | ||
119 | #define ADSP2_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */ | ||
120 | #define ADSP2_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */ | ||
121 | #define ADSP2_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */ | ||
122 | #define ADSP2_CORE_ENA 0x0002 /* DSP1_CORE_ENA */ | ||
123 | #define ADSP2_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */ | ||
124 | #define ADSP2_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */ | ||
125 | #define ADSP2_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */ | ||
126 | #define ADSP2_START 0x0001 /* DSP1_START */ | ||
127 | #define ADSP2_START_MASK 0x0001 /* DSP1_START */ | ||
128 | #define ADSP2_START_SHIFT 0 /* DSP1_START */ | ||
129 | #define ADSP2_START_WIDTH 1 /* DSP1_START */ | ||
130 | |||
131 | /* | ||
132 | * ADSP2 clocking | ||
133 | */ | ||
134 | #define ADSP2_CLK_SEL_MASK 0x0007 /* CLK_SEL_ENA */ | ||
135 | #define ADSP2_CLK_SEL_SHIFT 0 /* CLK_SEL_ENA */ | ||
136 | #define ADSP2_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ | ||
137 | |||
138 | /* | ||
139 | * ADSP2 Status 1 | ||
140 | */ | ||
141 | #define ADSP2_RAM_RDY 0x0001 | ||
142 | #define ADSP2_RAM_RDY_MASK 0x0001 | ||
143 | #define ADSP2_RAM_RDY_SHIFT 0 | ||
144 | #define ADSP2_RAM_RDY_WIDTH 1 | ||
145 | |||
146 | |||
147 | static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp, | ||
148 | int type) | ||
149 | { | ||
150 | int i; | ||
151 | |||
152 | for (i = 0; i < dsp->num_mems; i++) | ||
153 | if (dsp->mem[i].type == type) | ||
154 | return &dsp->mem[i]; | ||
155 | |||
156 | return NULL; | ||
157 | } | ||
158 | |||
159 | static int wm_adsp_load(struct wm_adsp *dsp) | ||
160 | { | ||
161 | const struct firmware *firmware; | ||
162 | struct regmap *regmap = dsp->regmap; | ||
163 | unsigned int pos = 0; | ||
164 | const struct wmfw_header *header; | ||
165 | const struct wmfw_adsp1_sizes *adsp1_sizes; | ||
166 | const struct wmfw_adsp2_sizes *adsp2_sizes; | ||
167 | const struct wmfw_footer *footer; | ||
168 | const struct wmfw_region *region; | ||
169 | const struct wm_adsp_region *mem; | ||
170 | const char *region_name; | ||
171 | char *file, *text; | ||
172 | unsigned int reg; | ||
173 | int regions = 0; | ||
174 | int ret, offset, type, sizes; | ||
175 | |||
176 | file = kzalloc(PAGE_SIZE, GFP_KERNEL); | ||
177 | if (file == NULL) | ||
178 | return -ENOMEM; | ||
179 | |||
180 | snprintf(file, PAGE_SIZE, "%s-dsp%d.wmfw", dsp->part, dsp->num); | ||
181 | file[PAGE_SIZE - 1] = '\0'; | ||
182 | |||
183 | ret = request_firmware(&firmware, file, dsp->dev); | ||
184 | if (ret != 0) { | ||
185 | adsp_err(dsp, "Failed to request '%s'\n", file); | ||
186 | goto out; | ||
187 | } | ||
188 | ret = -EINVAL; | ||
189 | |||
190 | pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer); | ||
191 | if (pos >= firmware->size) { | ||
192 | adsp_err(dsp, "%s: file too short, %zu bytes\n", | ||
193 | file, firmware->size); | ||
194 | goto out_fw; | ||
195 | } | ||
196 | |||
197 | header = (void*)&firmware->data[0]; | ||
198 | |||
199 | if (memcmp(&header->magic[0], "WMFW", 4) != 0) { | ||
200 | adsp_err(dsp, "%s: invalid magic\n", file); | ||
201 | goto out_fw; | ||
202 | } | ||
203 | |||
204 | if (header->ver != 0) { | ||
205 | adsp_err(dsp, "%s: unknown file format %d\n", | ||
206 | file, header->ver); | ||
207 | goto out_fw; | ||
208 | } | ||
209 | |||
210 | if (header->core != dsp->type) { | ||
211 | adsp_err(dsp, "%s: invalid core %d != %d\n", | ||
212 | file, header->core, dsp->type); | ||
213 | goto out_fw; | ||
214 | } | ||
215 | |||
216 | switch (dsp->type) { | ||
217 | case WMFW_ADSP1: | ||
218 | pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer); | ||
219 | adsp1_sizes = (void *)&(header[1]); | ||
220 | footer = (void *)&(adsp1_sizes[1]); | ||
221 | sizes = sizeof(*adsp1_sizes); | ||
222 | |||
223 | adsp_dbg(dsp, "%s: %d DM, %d PM, %d ZM\n", | ||
224 | file, le32_to_cpu(adsp1_sizes->dm), | ||
225 | le32_to_cpu(adsp1_sizes->pm), | ||
226 | le32_to_cpu(adsp1_sizes->zm)); | ||
227 | break; | ||
228 | |||
229 | case WMFW_ADSP2: | ||
230 | pos = sizeof(*header) + sizeof(*adsp2_sizes) + sizeof(*footer); | ||
231 | adsp2_sizes = (void *)&(header[1]); | ||
232 | footer = (void *)&(adsp2_sizes[1]); | ||
233 | sizes = sizeof(*adsp2_sizes); | ||
234 | |||
235 | adsp_dbg(dsp, "%s: %d XM, %d YM %d PM, %d ZM\n", | ||
236 | file, le32_to_cpu(adsp2_sizes->xm), | ||
237 | le32_to_cpu(adsp2_sizes->ym), | ||
238 | le32_to_cpu(adsp2_sizes->pm), | ||
239 | le32_to_cpu(adsp2_sizes->zm)); | ||
240 | break; | ||
241 | |||
242 | default: | ||
243 | BUG_ON(NULL == "Unknown DSP type"); | ||
244 | goto out_fw; | ||
245 | } | ||
246 | |||
247 | if (le32_to_cpu(header->len) != sizeof(*header) + | ||
248 | sizes + sizeof(*footer)) { | ||
249 | adsp_err(dsp, "%s: unexpected header length %d\n", | ||
250 | file, le32_to_cpu(header->len)); | ||
251 | goto out_fw; | ||
252 | } | ||
253 | |||
254 | adsp_dbg(dsp, "%s: timestamp %llu\n", file, | ||
255 | le64_to_cpu(footer->timestamp)); | ||
256 | |||
257 | while (pos < firmware->size && | ||
258 | pos - firmware->size > sizeof(*region)) { | ||
259 | region = (void *)&(firmware->data[pos]); | ||
260 | region_name = "Unknown"; | ||
261 | reg = 0; | ||
262 | text = NULL; | ||
263 | offset = le32_to_cpu(region->offset) & 0xffffff; | ||
264 | type = be32_to_cpu(region->type) & 0xff; | ||
265 | mem = wm_adsp_find_region(dsp, type); | ||
266 | |||
267 | switch (type) { | ||
268 | case WMFW_NAME_TEXT: | ||
269 | region_name = "Firmware name"; | ||
270 | text = kzalloc(le32_to_cpu(region->len) + 1, | ||
271 | GFP_KERNEL); | ||
272 | break; | ||
273 | case WMFW_INFO_TEXT: | ||
274 | region_name = "Information"; | ||
275 | text = kzalloc(le32_to_cpu(region->len) + 1, | ||
276 | GFP_KERNEL); | ||
277 | break; | ||
278 | case WMFW_ABSOLUTE: | ||
279 | region_name = "Absolute"; | ||
280 | reg = offset; | ||
281 | break; | ||
282 | case WMFW_ADSP1_PM: | ||
283 | BUG_ON(!mem); | ||
284 | region_name = "PM"; | ||
285 | reg = mem->base + (offset * 3); | ||
286 | break; | ||
287 | case WMFW_ADSP1_DM: | ||
288 | BUG_ON(!mem); | ||
289 | region_name = "DM"; | ||
290 | reg = mem->base + (offset * 2); | ||
291 | break; | ||
292 | case WMFW_ADSP2_XM: | ||
293 | BUG_ON(!mem); | ||
294 | region_name = "XM"; | ||
295 | reg = mem->base + (offset * 2); | ||
296 | break; | ||
297 | case WMFW_ADSP2_YM: | ||
298 | BUG_ON(!mem); | ||
299 | region_name = "YM"; | ||
300 | reg = mem->base + (offset * 2); | ||
301 | break; | ||
302 | case WMFW_ADSP1_ZM: | ||
303 | BUG_ON(!mem); | ||
304 | region_name = "ZM"; | ||
305 | reg = mem->base + (offset * 2); | ||
306 | break; | ||
307 | default: | ||
308 | adsp_warn(dsp, | ||
309 | "%s.%d: Unknown region type %x at %d(%x)\n", | ||
310 | file, regions, type, pos, pos); | ||
311 | break; | ||
312 | } | ||
313 | |||
314 | adsp_dbg(dsp, "%s.%d: %d bytes at %d in %s\n", file, | ||
315 | regions, le32_to_cpu(region->len), offset, | ||
316 | region_name); | ||
317 | |||
318 | if (text) { | ||
319 | memcpy(text, region->data, le32_to_cpu(region->len)); | ||
320 | adsp_info(dsp, "%s: %s\n", file, text); | ||
321 | kfree(text); | ||
322 | } | ||
323 | |||
324 | if (reg) { | ||
325 | ret = regmap_raw_write(regmap, reg, region->data, | ||
326 | le32_to_cpu(region->len)); | ||
327 | if (ret != 0) { | ||
328 | adsp_err(dsp, | ||
329 | "%s.%d: Failed to write %d bytes at %d in %s: %d\n", | ||
330 | file, regions, | ||
331 | le32_to_cpu(region->len), offset, | ||
332 | region_name, ret); | ||
333 | goto out_fw; | ||
334 | } | ||
335 | } | ||
336 | |||
337 | pos += le32_to_cpu(region->len) + sizeof(*region); | ||
338 | regions++; | ||
339 | } | ||
340 | |||
341 | if (pos > firmware->size) | ||
342 | adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", | ||
343 | file, regions, pos - firmware->size); | ||
344 | |||
345 | out_fw: | ||
346 | release_firmware(firmware); | ||
347 | out: | ||
348 | kfree(file); | ||
349 | |||
350 | return ret; | ||
351 | } | ||
352 | |||
353 | static int wm_adsp_load_coeff(struct wm_adsp *dsp) | ||
354 | { | ||
355 | struct regmap *regmap = dsp->regmap; | ||
356 | struct wmfw_coeff_hdr *hdr; | ||
357 | struct wmfw_coeff_item *blk; | ||
358 | const struct firmware *firmware; | ||
359 | const char *region_name; | ||
360 | int ret, pos, blocks, type, offset, reg; | ||
361 | char *file; | ||
362 | |||
363 | file = kzalloc(PAGE_SIZE, GFP_KERNEL); | ||
364 | if (file == NULL) | ||
365 | return -ENOMEM; | ||
366 | |||
367 | snprintf(file, PAGE_SIZE, "%s-dsp%d.bin", dsp->part, dsp->num); | ||
368 | file[PAGE_SIZE - 1] = '\0'; | ||
369 | |||
370 | ret = request_firmware(&firmware, file, dsp->dev); | ||
371 | if (ret != 0) { | ||
372 | adsp_warn(dsp, "Failed to request '%s'\n", file); | ||
373 | ret = 0; | ||
374 | goto out; | ||
375 | } | ||
376 | ret = -EINVAL; | ||
377 | |||
378 | if (sizeof(*hdr) >= firmware->size) { | ||
379 | adsp_err(dsp, "%s: file too short, %zu bytes\n", | ||
380 | file, firmware->size); | ||
381 | goto out_fw; | ||
382 | } | ||
383 | |||
384 | hdr = (void*)&firmware->data[0]; | ||
385 | if (memcmp(hdr->magic, "WMDR", 4) != 0) { | ||
386 | adsp_err(dsp, "%s: invalid magic\n", file); | ||
387 | return -EINVAL; | ||
388 | } | ||
389 | |||
390 | adsp_dbg(dsp, "%s: v%d.%d.%d\n", file, | ||
391 | (le32_to_cpu(hdr->ver) >> 16) & 0xff, | ||
392 | (le32_to_cpu(hdr->ver) >> 8) & 0xff, | ||
393 | le32_to_cpu(hdr->ver) & 0xff); | ||
394 | |||
395 | pos = le32_to_cpu(hdr->len); | ||
396 | |||
397 | blocks = 0; | ||
398 | while (pos < firmware->size && | ||
399 | pos - firmware->size > sizeof(*blk)) { | ||
400 | blk = (void*)(&firmware->data[pos]); | ||
401 | |||
402 | type = be32_to_cpu(blk->type) & 0xff; | ||
403 | offset = le32_to_cpu(blk->offset) & 0xffffff; | ||
404 | |||
405 | adsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n", | ||
406 | file, blocks, le32_to_cpu(blk->id), | ||
407 | (le32_to_cpu(blk->ver) >> 16) & 0xff, | ||
408 | (le32_to_cpu(blk->ver) >> 8) & 0xff, | ||
409 | le32_to_cpu(blk->ver) & 0xff); | ||
410 | adsp_dbg(dsp, "%s.%d: %d bytes at 0x%x in %x\n", | ||
411 | file, blocks, le32_to_cpu(blk->len), offset, type); | ||
412 | |||
413 | reg = 0; | ||
414 | region_name = "Unknown"; | ||
415 | switch (type) { | ||
416 | case WMFW_NAME_TEXT: | ||
417 | case WMFW_INFO_TEXT: | ||
418 | break; | ||
419 | case WMFW_ABSOLUTE: | ||
420 | region_name = "register"; | ||
421 | reg = offset; | ||
422 | break; | ||
423 | default: | ||
424 | adsp_err(dsp, "Unknown region type %x\n", type); | ||
425 | break; | ||
426 | } | ||
427 | |||
428 | if (reg) { | ||
429 | ret = regmap_raw_write(regmap, reg, blk->data, | ||
430 | le32_to_cpu(blk->len)); | ||
431 | if (ret != 0) { | ||
432 | adsp_err(dsp, | ||
433 | "%s.%d: Failed to write to %x in %s\n", | ||
434 | file, blocks, reg, region_name); | ||
435 | } | ||
436 | } | ||
437 | |||
438 | pos += le32_to_cpu(blk->len) + sizeof(*blk); | ||
439 | blocks++; | ||
440 | } | ||
441 | |||
442 | if (pos > firmware->size) | ||
443 | adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", | ||
444 | file, blocks, pos - firmware->size); | ||
445 | |||
446 | out_fw: | ||
447 | release_firmware(firmware); | ||
448 | out: | ||
449 | kfree(file); | ||
450 | return 0; | ||
451 | } | ||
452 | |||
453 | int wm_adsp1_event(struct snd_soc_dapm_widget *w, | ||
454 | struct snd_kcontrol *kcontrol, | ||
455 | int event) | ||
456 | { | ||
457 | struct snd_soc_codec *codec = w->codec; | ||
458 | struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); | ||
459 | struct wm_adsp *dsp = &dsps[w->shift]; | ||
460 | int ret; | ||
461 | |||
462 | switch (event) { | ||
463 | case SND_SOC_DAPM_POST_PMU: | ||
464 | regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, | ||
465 | ADSP1_SYS_ENA, ADSP1_SYS_ENA); | ||
466 | |||
467 | ret = wm_adsp_load(dsp); | ||
468 | if (ret != 0) | ||
469 | goto err; | ||
470 | |||
471 | ret = wm_adsp_load_coeff(dsp); | ||
472 | if (ret != 0) | ||
473 | goto err; | ||
474 | |||
475 | /* Start the core running */ | ||
476 | regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, | ||
477 | ADSP1_CORE_ENA | ADSP1_START, | ||
478 | ADSP1_CORE_ENA | ADSP1_START); | ||
479 | break; | ||
480 | |||
481 | case SND_SOC_DAPM_PRE_PMD: | ||
482 | /* Halt the core */ | ||
483 | regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, | ||
484 | ADSP1_CORE_ENA | ADSP1_START, 0); | ||
485 | |||
486 | regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_19, | ||
487 | ADSP1_WDMA_BUFFER_LENGTH_MASK, 0); | ||
488 | |||
489 | regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, | ||
490 | ADSP1_SYS_ENA, 0); | ||
491 | break; | ||
492 | |||
493 | default: | ||
494 | break; | ||
495 | } | ||
496 | |||
497 | return 0; | ||
498 | |||
499 | err: | ||
500 | regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, | ||
501 | ADSP1_SYS_ENA, 0); | ||
502 | return ret; | ||
503 | } | ||
504 | EXPORT_SYMBOL_GPL(wm_adsp1_event); | ||
505 | |||
506 | static int wm_adsp2_ena(struct wm_adsp *dsp) | ||
507 | { | ||
508 | unsigned int val; | ||
509 | int ret, count; | ||
510 | |||
511 | ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, | ||
512 | ADSP2_SYS_ENA, ADSP2_SYS_ENA); | ||
513 | if (ret != 0) | ||
514 | return ret; | ||
515 | |||
516 | /* Wait for the RAM to start, should be near instantaneous */ | ||
517 | count = 0; | ||
518 | do { | ||
519 | ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1, | ||
520 | &val); | ||
521 | if (ret != 0) | ||
522 | return ret; | ||
523 | } while (!(val & ADSP2_RAM_RDY) && ++count < 10); | ||
524 | |||
525 | if (!(val & ADSP2_RAM_RDY)) { | ||
526 | adsp_err(dsp, "Failed to start DSP RAM\n"); | ||
527 | return -EBUSY; | ||
528 | } | ||
529 | |||
530 | adsp_dbg(dsp, "RAM ready after %d polls\n", count); | ||
531 | adsp_info(dsp, "RAM ready after %d polls\n", count); | ||
532 | |||
533 | return 0; | ||
534 | } | ||
535 | |||
536 | int wm_adsp2_event(struct snd_soc_dapm_widget *w, | ||
537 | struct snd_kcontrol *kcontrol, int event) | ||
538 | { | ||
539 | struct snd_soc_codec *codec = w->codec; | ||
540 | struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); | ||
541 | struct wm_adsp *dsp = &dsps[w->shift]; | ||
542 | unsigned int val; | ||
543 | int ret; | ||
544 | |||
545 | switch (event) { | ||
546 | case SND_SOC_DAPM_POST_PMU: | ||
547 | if (dsp->dvfs) { | ||
548 | ret = regmap_read(dsp->regmap, | ||
549 | dsp->base + ADSP2_CLOCKING, &val); | ||
550 | if (ret != 0) { | ||
551 | dev_err(dsp->dev, | ||
552 | "Failed to read clocking: %d\n", ret); | ||
553 | return ret; | ||
554 | } | ||
555 | |||
556 | if ((val & ADSP2_CLK_SEL_MASK) >= 3) { | ||
557 | ret = regulator_enable(dsp->dvfs); | ||
558 | if (ret != 0) { | ||
559 | dev_err(dsp->dev, | ||
560 | "Failed to enable supply: %d\n", | ||
561 | ret); | ||
562 | return ret; | ||
563 | } | ||
564 | |||
565 | ret = regulator_set_voltage(dsp->dvfs, | ||
566 | 1800000, | ||
567 | 1800000); | ||
568 | if (ret != 0) { | ||
569 | dev_err(dsp->dev, | ||
570 | "Failed to raise supply: %d\n", | ||
571 | ret); | ||
572 | return ret; | ||
573 | } | ||
574 | } | ||
575 | } | ||
576 | |||
577 | ret = wm_adsp2_ena(dsp); | ||
578 | if (ret != 0) | ||
579 | return ret; | ||
580 | |||
581 | ret = wm_adsp_load(dsp); | ||
582 | if (ret != 0) | ||
583 | goto err; | ||
584 | |||
585 | ret = wm_adsp_load_coeff(dsp); | ||
586 | if (ret != 0) | ||
587 | goto err; | ||
588 | |||
589 | ret = regmap_update_bits(dsp->regmap, | ||
590 | dsp->base + ADSP2_CONTROL, | ||
591 | ADSP2_CORE_ENA | ADSP2_START, | ||
592 | ADSP2_CORE_ENA | ADSP2_START); | ||
593 | if (ret != 0) | ||
594 | goto err; | ||
595 | break; | ||
596 | |||
597 | case SND_SOC_DAPM_PRE_PMD: | ||
598 | regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, | ||
599 | ADSP2_SYS_ENA | ADSP2_CORE_ENA | | ||
600 | ADSP2_START, 0); | ||
601 | |||
602 | if (dsp->dvfs) { | ||
603 | ret = regulator_set_voltage(dsp->dvfs, 1200000, | ||
604 | 1800000); | ||
605 | if (ret != 0) | ||
606 | dev_warn(dsp->dev, | ||
607 | "Failed to lower supply: %d\n", | ||
608 | ret); | ||
609 | |||
610 | ret = regulator_disable(dsp->dvfs); | ||
611 | if (ret != 0) | ||
612 | dev_err(dsp->dev, | ||
613 | "Failed to enable supply: %d\n", | ||
614 | ret); | ||
615 | } | ||
616 | break; | ||
617 | |||
618 | default: | ||
619 | break; | ||
620 | } | ||
621 | |||
622 | return 0; | ||
623 | err: | ||
624 | regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, | ||
625 | ADSP2_SYS_ENA | ADSP2_CORE_ENA | ADSP2_START, 0); | ||
626 | return ret; | ||
627 | } | ||
628 | EXPORT_SYMBOL_GPL(wm_adsp2_event); | ||
629 | |||
630 | int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs) | ||
631 | { | ||
632 | int ret; | ||
633 | |||
634 | if (dvfs) { | ||
635 | adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD"); | ||
636 | if (IS_ERR(adsp->dvfs)) { | ||
637 | ret = PTR_ERR(adsp->dvfs); | ||
638 | dev_err(adsp->dev, "Failed to get DCVDD: %d\n", ret); | ||
639 | return ret; | ||
640 | } | ||
641 | |||
642 | ret = regulator_enable(adsp->dvfs); | ||
643 | if (ret != 0) { | ||
644 | dev_err(adsp->dev, "Failed to enable DCVDD: %d\n", | ||
645 | ret); | ||
646 | return ret; | ||
647 | } | ||
648 | |||
649 | ret = regulator_set_voltage(adsp->dvfs, 1200000, 1800000); | ||
650 | if (ret != 0) { | ||
651 | dev_err(adsp->dev, "Failed to initialise DVFS: %d\n", | ||
652 | ret); | ||
653 | return ret; | ||
654 | } | ||
655 | |||
656 | ret = regulator_disable(adsp->dvfs); | ||
657 | if (ret != 0) { | ||
658 | dev_err(adsp->dev, "Failed to disable DCVDD: %d\n", | ||
659 | ret); | ||
660 | return ret; | ||
661 | } | ||
662 | } | ||
663 | |||
664 | return 0; | ||
665 | } | ||
666 | EXPORT_SYMBOL_GPL(wm_adsp2_init); | ||
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h new file mode 100644 index 000000000000..ffd29a4609e2 --- /dev/null +++ b/sound/soc/codecs/wm_adsp.h | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | * wm_adsp.h -- Wolfson ADSP support | ||
3 | * | ||
4 | * Copyright 2012 Wolfson Microelectronics plc | ||
5 | * | ||
6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef __WM_ADSP_H | ||
14 | #define __WM_ADSP_H | ||
15 | |||
16 | #include <sound/soc.h> | ||
17 | #include <sound/soc-dapm.h> | ||
18 | |||
19 | #include "wmfw.h" | ||
20 | |||
21 | struct regulator; | ||
22 | |||
23 | struct wm_adsp_region { | ||
24 | int type; | ||
25 | unsigned int base; | ||
26 | }; | ||
27 | |||
28 | struct wm_adsp { | ||
29 | const char *part; | ||
30 | int num; | ||
31 | int type; | ||
32 | struct device *dev; | ||
33 | struct regmap *regmap; | ||
34 | |||
35 | int base; | ||
36 | |||
37 | const struct wm_adsp_region *mem; | ||
38 | int num_mems; | ||
39 | |||
40 | struct regulator *dvfs; | ||
41 | }; | ||
42 | |||
43 | #define WM_ADSP1(wname, num) \ | ||
44 | { .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, \ | ||
45 | .shift = num, .event = wm_adsp1_event, \ | ||
46 | .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD } | ||
47 | |||
48 | #define WM_ADSP2(wname, num) \ | ||
49 | { .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, \ | ||
50 | .shift = num, .event = wm_adsp2_event, \ | ||
51 | .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD } | ||
52 | |||
53 | int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs); | ||
54 | int wm_adsp1_event(struct snd_soc_dapm_widget *w, | ||
55 | struct snd_kcontrol *kcontrol, int event); | ||
56 | int wm_adsp2_event(struct snd_soc_dapm_widget *w, | ||
57 | struct snd_kcontrol *kcontrol, int event); | ||
58 | |||
59 | #endif | ||
diff --git a/sound/soc/codecs/wmfw.h b/sound/soc/codecs/wmfw.h new file mode 100644 index 000000000000..5632ded67fdd --- /dev/null +++ b/sound/soc/codecs/wmfw.h | |||
@@ -0,0 +1,128 @@ | |||
1 | /* | ||
2 | * wmfw.h - Wolfson firmware format information | ||
3 | * | ||
4 | * Copyright 2012 Wolfson Microelectronics plc | ||
5 | * | ||
6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef __WMFW_H | ||
14 | #define __WMFW_H | ||
15 | |||
16 | #include <linux/types.h> | ||
17 | |||
18 | struct wmfw_header { | ||
19 | char magic[4]; | ||
20 | __le32 len; | ||
21 | __le16 rev; | ||
22 | u8 core; | ||
23 | u8 ver; | ||
24 | } __packed; | ||
25 | |||
26 | struct wmfw_footer { | ||
27 | __le64 timestamp; | ||
28 | __le32 checksum; | ||
29 | } __packed; | ||
30 | |||
31 | struct wmfw_adsp1_sizes { | ||
32 | __le32 dm; | ||
33 | __le32 pm; | ||
34 | __le32 zm; | ||
35 | } __packed; | ||
36 | |||
37 | struct wmfw_adsp2_sizes { | ||
38 | __le32 xm; | ||
39 | __le32 ym; | ||
40 | __le32 pm; | ||
41 | __le32 zm; | ||
42 | } __packed; | ||
43 | |||
44 | struct wmfw_region { | ||
45 | union { | ||
46 | __be32 type; | ||
47 | __le32 offset; | ||
48 | }; | ||
49 | __le32 len; | ||
50 | u8 data[]; | ||
51 | } __packed; | ||
52 | |||
53 | struct wmfw_id_hdr { | ||
54 | __be32 core_id; | ||
55 | __be32 core_rev; | ||
56 | __be32 id; | ||
57 | __be32 ver; | ||
58 | } __packed; | ||
59 | |||
60 | struct wmfw_adsp1_id_hdr { | ||
61 | struct wmfw_id_hdr fw; | ||
62 | __be32 zm; | ||
63 | __be32 dm; | ||
64 | __be32 algs; | ||
65 | } __packed; | ||
66 | |||
67 | struct wmfw_adsp2_id_hdr { | ||
68 | struct wmfw_id_hdr fw; | ||
69 | __be32 zm; | ||
70 | __be32 xm; | ||
71 | __be32 ym; | ||
72 | __be32 algs; | ||
73 | } __packed; | ||
74 | |||
75 | struct wmfw_alg_hdr { | ||
76 | __be32 id; | ||
77 | __be32 ver; | ||
78 | } __packed; | ||
79 | |||
80 | struct wmfw_adsp1_alg_hdr { | ||
81 | struct wmfw_alg_hdr alg; | ||
82 | __be32 zm; | ||
83 | __be32 dm; | ||
84 | } __packed; | ||
85 | |||
86 | struct wmfw_adsp2_alg_hdr { | ||
87 | struct wmfw_alg_hdr alg; | ||
88 | __be32 zm; | ||
89 | __be32 xm; | ||
90 | __be32 ym; | ||
91 | } __packed; | ||
92 | |||
93 | struct wmfw_coeff_hdr { | ||
94 | u8 magic[4]; | ||
95 | __le32 len; | ||
96 | __le32 ver; | ||
97 | u8 data[]; | ||
98 | } __packed; | ||
99 | |||
100 | struct wmfw_coeff_item { | ||
101 | union { | ||
102 | __be32 type; | ||
103 | __le32 offset; | ||
104 | }; | ||
105 | __le32 id; | ||
106 | __le32 ver; | ||
107 | __le32 sr; | ||
108 | __le32 len; | ||
109 | u8 data[]; | ||
110 | } __packed; | ||
111 | |||
112 | #define WMFW_ADSP1 1 | ||
113 | #define WMFW_ADSP2 2 | ||
114 | |||
115 | #define WMFW_ABSOLUTE 0xf0 | ||
116 | #define WMFW_NAME_TEXT 0xfe | ||
117 | #define WMFW_INFO_TEXT 0xff | ||
118 | |||
119 | #define WMFW_ADSP1_PM 2 | ||
120 | #define WMFW_ADSP1_DM 3 | ||
121 | #define WMFW_ADSP1_ZM 4 | ||
122 | |||
123 | #define WMFW_ADSP2_PM 2 | ||
124 | #define WMFW_ADSP2_ZM 4 | ||
125 | #define WMFW_ADSP2_XM 5 | ||
126 | #define WMFW_ADSP2_YM 6 | ||
127 | |||
128 | #endif | ||
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index 6fac5af13298..d55e6477bff0 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c | |||
@@ -71,6 +71,11 @@ static int evm_hw_params(struct snd_pcm_substream *substream, | |||
71 | if (ret < 0) | 71 | if (ret < 0) |
72 | return ret; | 72 | return ret; |
73 | 73 | ||
74 | /* set the CPU system clock */ | ||
75 | ret = snd_soc_dai_set_sysclk(cpu_dai, 0, sysclk, SND_SOC_CLOCK_OUT); | ||
76 | if (ret < 0) | ||
77 | return ret; | ||
78 | |||
74 | return 0; | 79 | return 0; |
75 | } | 80 | } |
76 | 81 | ||
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 714e51e5be5b..571559501b0b 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -199,6 +199,7 @@ | |||
199 | #define ACLKXE BIT(5) | 199 | #define ACLKXE BIT(5) |
200 | #define TX_ASYNC BIT(6) | 200 | #define TX_ASYNC BIT(6) |
201 | #define ACLKXPOL BIT(7) | 201 | #define ACLKXPOL BIT(7) |
202 | #define ACLKXDIV_MASK 0x1f | ||
202 | 203 | ||
203 | /* | 204 | /* |
204 | * DAVINCI_MCASP_ACLKRCTL_REG Receive Clock Control Register Bits | 205 | * DAVINCI_MCASP_ACLKRCTL_REG Receive Clock Control Register Bits |
@@ -207,6 +208,7 @@ | |||
207 | #define ACLKRE BIT(5) | 208 | #define ACLKRE BIT(5) |
208 | #define RX_ASYNC BIT(6) | 209 | #define RX_ASYNC BIT(6) |
209 | #define ACLKRPOL BIT(7) | 210 | #define ACLKRPOL BIT(7) |
211 | #define ACLKRDIV_MASK 0x1f | ||
210 | 212 | ||
211 | /* | 213 | /* |
212 | * DAVINCI_MCASP_AHCLKXCTL_REG - High Frequency Transmit Clock Control | 214 | * DAVINCI_MCASP_AHCLKXCTL_REG - High Frequency Transmit Clock Control |
@@ -215,6 +217,7 @@ | |||
215 | #define AHCLKXDIV(val) (val) | 217 | #define AHCLKXDIV(val) (val) |
216 | #define AHCLKXPOL BIT(14) | 218 | #define AHCLKXPOL BIT(14) |
217 | #define AHCLKXE BIT(15) | 219 | #define AHCLKXE BIT(15) |
220 | #define AHCLKXDIV_MASK 0xfff | ||
218 | 221 | ||
219 | /* | 222 | /* |
220 | * DAVINCI_MCASP_AHCLKRCTL_REG - High Frequency Receive Clock Control | 223 | * DAVINCI_MCASP_AHCLKRCTL_REG - High Frequency Receive Clock Control |
@@ -223,6 +226,7 @@ | |||
223 | #define AHCLKRDIV(val) (val) | 226 | #define AHCLKRDIV(val) (val) |
224 | #define AHCLKRPOL BIT(14) | 227 | #define AHCLKRPOL BIT(14) |
225 | #define AHCLKRE BIT(15) | 228 | #define AHCLKRE BIT(15) |
229 | #define AHCLKRDIV_MASK 0xfff | ||
226 | 230 | ||
227 | /* | 231 | /* |
228 | * DAVINCI_MCASP_XRSRCTL_BASE_REG - Serializer Control Register Bits | 232 | * DAVINCI_MCASP_XRSRCTL_BASE_REG - Serializer Control Register Bits |
@@ -473,6 +477,23 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
473 | struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(cpu_dai); | 477 | struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(cpu_dai); |
474 | void __iomem *base = dev->base; | 478 | void __iomem *base = dev->base; |
475 | 479 | ||
480 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
481 | case SND_SOC_DAIFMT_DSP_B: | ||
482 | case SND_SOC_DAIFMT_AC97: | ||
483 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); | ||
484 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); | ||
485 | break; | ||
486 | default: | ||
487 | /* configure a full-word SYNC pulse (LRCLK) */ | ||
488 | mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); | ||
489 | mcasp_set_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); | ||
490 | |||
491 | /* make 1st data bit occur one ACLK cycle after the frame sync */ | ||
492 | mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, FSXDLY(1)); | ||
493 | mcasp_set_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, FSRDLY(1)); | ||
494 | break; | ||
495 | } | ||
496 | |||
476 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 497 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
477 | case SND_SOC_DAIFMT_CBS_CFS: | 498 | case SND_SOC_DAIFMT_CBS_CFS: |
478 | /* codec is clock and frame slave */ | 499 | /* codec is clock and frame slave */ |
@@ -482,8 +503,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
482 | mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE); | 503 | mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE); |
483 | mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE); | 504 | mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE); |
484 | 505 | ||
485 | mcasp_set_bits(base + DAVINCI_MCASP_PDIR_REG, | 506 | mcasp_set_bits(base + DAVINCI_MCASP_PDIR_REG, ACLKX | AFSX); |
486 | ACLKX | AHCLKX | AFSX); | ||
487 | break; | 507 | break; |
488 | case SND_SOC_DAIFMT_CBM_CFS: | 508 | case SND_SOC_DAIFMT_CBM_CFS: |
489 | /* codec is clock master and frame slave */ | 509 | /* codec is clock master and frame slave */ |
@@ -554,6 +574,50 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
554 | return 0; | 574 | return 0; |
555 | } | 575 | } |
556 | 576 | ||
577 | static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) | ||
578 | { | ||
579 | struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(dai); | ||
580 | |||
581 | switch (div_id) { | ||
582 | case 0: /* MCLK divider */ | ||
583 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, | ||
584 | AHCLKXDIV(div - 1), AHCLKXDIV_MASK); | ||
585 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG, | ||
586 | AHCLKRDIV(div - 1), AHCLKRDIV_MASK); | ||
587 | break; | ||
588 | |||
589 | case 1: /* BCLK divider */ | ||
590 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_ACLKXCTL_REG, | ||
591 | ACLKXDIV(div - 1), ACLKXDIV_MASK); | ||
592 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_ACLKRCTL_REG, | ||
593 | ACLKRDIV(div - 1), ACLKRDIV_MASK); | ||
594 | break; | ||
595 | |||
596 | default: | ||
597 | return -EINVAL; | ||
598 | } | ||
599 | |||
600 | return 0; | ||
601 | } | ||
602 | |||
603 | static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id, | ||
604 | unsigned int freq, int dir) | ||
605 | { | ||
606 | struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(dai); | ||
607 | |||
608 | if (dir == SND_SOC_CLOCK_OUT) { | ||
609 | mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE); | ||
610 | mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE); | ||
611 | mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG, AHCLKX); | ||
612 | } else { | ||
613 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE); | ||
614 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE); | ||
615 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_PDIR_REG, AHCLKX); | ||
616 | } | ||
617 | |||
618 | return 0; | ||
619 | } | ||
620 | |||
557 | static int davinci_config_channel_size(struct davinci_audio_dev *dev, | 621 | static int davinci_config_channel_size(struct davinci_audio_dev *dev, |
558 | int channel_size) | 622 | int channel_size) |
559 | { | 623 | { |
@@ -709,8 +773,6 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) | |||
709 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { | 773 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { |
710 | /* bit stream is MSB first with no delay */ | 774 | /* bit stream is MSB first with no delay */ |
711 | /* DSP_B mode */ | 775 | /* DSP_B mode */ |
712 | mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, | ||
713 | AHCLKXE); | ||
714 | mcasp_set_reg(dev->base + DAVINCI_MCASP_TXTDM_REG, mask); | 776 | mcasp_set_reg(dev->base + DAVINCI_MCASP_TXTDM_REG, mask); |
715 | mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXORD); | 777 | mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXORD); |
716 | 778 | ||
@@ -720,14 +782,10 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) | |||
720 | else | 782 | else |
721 | printk(KERN_ERR "playback tdm slot %d not supported\n", | 783 | printk(KERN_ERR "playback tdm slot %d not supported\n", |
722 | dev->tdm_slots); | 784 | dev->tdm_slots); |
723 | |||
724 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); | ||
725 | } else { | 785 | } else { |
726 | /* bit stream is MSB first with no delay */ | 786 | /* bit stream is MSB first with no delay */ |
727 | /* DSP_B mode */ | 787 | /* DSP_B mode */ |
728 | mcasp_set_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, RXORD); | 788 | mcasp_set_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, RXORD); |
729 | mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG, | ||
730 | AHCLKRE); | ||
731 | mcasp_set_reg(dev->base + DAVINCI_MCASP_RXTDM_REG, mask); | 789 | mcasp_set_reg(dev->base + DAVINCI_MCASP_RXTDM_REG, mask); |
732 | 790 | ||
733 | if ((dev->tdm_slots >= 2) && (dev->tdm_slots <= 32)) | 791 | if ((dev->tdm_slots >= 2) && (dev->tdm_slots <= 32)) |
@@ -736,8 +794,6 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) | |||
736 | else | 794 | else |
737 | printk(KERN_ERR "capture tdm slot %d not supported\n", | 795 | printk(KERN_ERR "capture tdm slot %d not supported\n", |
738 | dev->tdm_slots); | 796 | dev->tdm_slots); |
739 | |||
740 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); | ||
741 | } | 797 | } |
742 | } | 798 | } |
743 | 799 | ||
@@ -809,6 +865,14 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | |||
809 | word_length = DAVINCI_AUDIO_WORD_16; | 865 | word_length = DAVINCI_AUDIO_WORD_16; |
810 | break; | 866 | break; |
811 | 867 | ||
868 | case SNDRV_PCM_FORMAT_U24_3LE: | ||
869 | case SNDRV_PCM_FORMAT_S24_3LE: | ||
870 | dma_params->data_type = 3; | ||
871 | word_length = DAVINCI_AUDIO_WORD_24; | ||
872 | break; | ||
873 | |||
874 | case SNDRV_PCM_FORMAT_U24_LE: | ||
875 | case SNDRV_PCM_FORMAT_S24_LE: | ||
812 | case SNDRV_PCM_FORMAT_U32_LE: | 876 | case SNDRV_PCM_FORMAT_U32_LE: |
813 | case SNDRV_PCM_FORMAT_S32_LE: | 877 | case SNDRV_PCM_FORMAT_S32_LE: |
814 | dma_params->data_type = 4; | 878 | dma_params->data_type = 4; |
@@ -880,13 +944,18 @@ static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = { | |||
880 | .trigger = davinci_mcasp_trigger, | 944 | .trigger = davinci_mcasp_trigger, |
881 | .hw_params = davinci_mcasp_hw_params, | 945 | .hw_params = davinci_mcasp_hw_params, |
882 | .set_fmt = davinci_mcasp_set_dai_fmt, | 946 | .set_fmt = davinci_mcasp_set_dai_fmt, |
883 | 947 | .set_clkdiv = davinci_mcasp_set_clkdiv, | |
948 | .set_sysclk = davinci_mcasp_set_sysclk, | ||
884 | }; | 949 | }; |
885 | 950 | ||
886 | #define DAVINCI_MCASP_PCM_FMTS (SNDRV_PCM_FMTBIT_S8 | \ | 951 | #define DAVINCI_MCASP_PCM_FMTS (SNDRV_PCM_FMTBIT_S8 | \ |
887 | SNDRV_PCM_FMTBIT_U8 | \ | 952 | SNDRV_PCM_FMTBIT_U8 | \ |
888 | SNDRV_PCM_FMTBIT_S16_LE | \ | 953 | SNDRV_PCM_FMTBIT_S16_LE | \ |
889 | SNDRV_PCM_FMTBIT_U16_LE | \ | 954 | SNDRV_PCM_FMTBIT_U16_LE | \ |
955 | SNDRV_PCM_FMTBIT_S24_LE | \ | ||
956 | SNDRV_PCM_FMTBIT_U24_LE | \ | ||
957 | SNDRV_PCM_FMTBIT_S24_3LE | \ | ||
958 | SNDRV_PCM_FMTBIT_U24_3LE | \ | ||
890 | SNDRV_PCM_FMTBIT_S32_LE | \ | 959 | SNDRV_PCM_FMTBIT_S32_LE | \ |
891 | SNDRV_PCM_FMTBIT_U32_LE) | 960 | SNDRV_PCM_FMTBIT_U32_LE) |
892 | 961 | ||
@@ -1098,6 +1167,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
1098 | dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; | 1167 | dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; |
1099 | dma_data->asp_chan_q = pdata->asp_chan_q; | 1168 | dma_data->asp_chan_q = pdata->asp_chan_q; |
1100 | dma_data->ram_chan_q = pdata->ram_chan_q; | 1169 | dma_data->ram_chan_q = pdata->ram_chan_q; |
1170 | dma_data->sram_pool = pdata->sram_pool; | ||
1101 | dma_data->sram_size = pdata->sram_size_playback; | 1171 | dma_data->sram_size = pdata->sram_size_playback; |
1102 | dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset + | 1172 | dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset + |
1103 | mem->start); | 1173 | mem->start); |
@@ -1115,6 +1185,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
1115 | dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]; | 1185 | dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]; |
1116 | dma_data->asp_chan_q = pdata->asp_chan_q; | 1186 | dma_data->asp_chan_q = pdata->asp_chan_q; |
1117 | dma_data->ram_chan_q = pdata->ram_chan_q; | 1187 | dma_data->ram_chan_q = pdata->ram_chan_q; |
1188 | dma_data->sram_pool = pdata->sram_pool; | ||
1118 | dma_data->sram_size = pdata->sram_size_capture; | 1189 | dma_data->sram_size = pdata->sram_size_capture; |
1119 | dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset + | 1190 | dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset + |
1120 | mem->start); | 1191 | mem->start); |
diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h index 0de9ed6ce038..156f15f55744 100644 --- a/sound/soc/davinci/davinci-mcasp.h +++ b/sound/soc/davinci/davinci-mcasp.h | |||
@@ -23,7 +23,7 @@ | |||
23 | 23 | ||
24 | #include "davinci-pcm.h" | 24 | #include "davinci-pcm.h" |
25 | 25 | ||
26 | #define DAVINCI_MCASP_RATES SNDRV_PCM_RATE_8000_96000 | 26 | #define DAVINCI_MCASP_RATES SNDRV_PCM_RATE_8000_192000 |
27 | #define DAVINCI_MCASP_I2S_DAI 0 | 27 | #define DAVINCI_MCASP_I2S_DAI 0 |
28 | #define DAVINCI_MCASP_DIT_DAI 1 | 28 | #define DAVINCI_MCASP_DIT_DAI 1 |
29 | 29 | ||
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c index 93ea3bf567e1..afab81f844ae 100644 --- a/sound/soc/davinci/davinci-pcm.c +++ b/sound/soc/davinci/davinci-pcm.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/dma-mapping.h> | 17 | #include <linux/dma-mapping.h> |
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | #include <linux/genalloc.h> | ||
19 | 20 | ||
20 | #include <sound/core.h> | 21 | #include <sound/core.h> |
21 | #include <sound/pcm.h> | 22 | #include <sound/pcm.h> |
@@ -23,7 +24,6 @@ | |||
23 | #include <sound/soc.h> | 24 | #include <sound/soc.h> |
24 | 25 | ||
25 | #include <asm/dma.h> | 26 | #include <asm/dma.h> |
26 | #include <mach/sram.h> | ||
27 | 27 | ||
28 | #include "davinci-pcm.h" | 28 | #include "davinci-pcm.h" |
29 | 29 | ||
@@ -67,13 +67,9 @@ static struct snd_pcm_hardware pcm_hardware_playback = { | |||
67 | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME| | 67 | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME| |
68 | SNDRV_PCM_INFO_BATCH), | 68 | SNDRV_PCM_INFO_BATCH), |
69 | .formats = DAVINCI_PCM_FMTBITS, | 69 | .formats = DAVINCI_PCM_FMTBITS, |
70 | .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | | 70 | .rates = SNDRV_PCM_RATE_8000_192000 | SNDRV_PCM_RATE_KNOT, |
71 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | | ||
72 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | | ||
73 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | | ||
74 | SNDRV_PCM_RATE_KNOT), | ||
75 | .rate_min = 8000, | 71 | .rate_min = 8000, |
76 | .rate_max = 96000, | 72 | .rate_max = 192000, |
77 | .channels_min = 2, | 73 | .channels_min = 2, |
78 | .channels_max = 384, | 74 | .channels_max = 384, |
79 | .buffer_bytes_max = 128 * 1024, | 75 | .buffer_bytes_max = 128 * 1024, |
@@ -90,13 +86,9 @@ static struct snd_pcm_hardware pcm_hardware_capture = { | |||
90 | SNDRV_PCM_INFO_PAUSE | | 86 | SNDRV_PCM_INFO_PAUSE | |
91 | SNDRV_PCM_INFO_BATCH), | 87 | SNDRV_PCM_INFO_BATCH), |
92 | .formats = DAVINCI_PCM_FMTBITS, | 88 | .formats = DAVINCI_PCM_FMTBITS, |
93 | .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | | 89 | .rates = SNDRV_PCM_RATE_8000_192000 | SNDRV_PCM_RATE_KNOT, |
94 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | | ||
95 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | | ||
96 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | | ||
97 | SNDRV_PCM_RATE_KNOT), | ||
98 | .rate_min = 8000, | 90 | .rate_min = 8000, |
99 | .rate_max = 96000, | 91 | .rate_max = 192000, |
100 | .channels_min = 2, | 92 | .channels_min = 2, |
101 | .channels_max = 384, | 93 | .channels_max = 384, |
102 | .buffer_bytes_max = 128 * 1024, | 94 | .buffer_bytes_max = 128 * 1024, |
@@ -259,7 +251,9 @@ static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data) | |||
259 | } | 251 | } |
260 | } | 252 | } |
261 | 253 | ||
262 | static int allocate_sram(struct snd_pcm_substream *substream, unsigned size, | 254 | #ifdef CONFIG_GENERIC_ALLOCATOR |
255 | static int allocate_sram(struct snd_pcm_substream *substream, | ||
256 | struct gen_pool *sram_pool, unsigned size, | ||
263 | struct snd_pcm_hardware *ppcm) | 257 | struct snd_pcm_hardware *ppcm) |
264 | { | 258 | { |
265 | struct snd_dma_buffer *buf = &substream->dma_buffer; | 259 | struct snd_dma_buffer *buf = &substream->dma_buffer; |
@@ -271,9 +265,10 @@ static int allocate_sram(struct snd_pcm_substream *substream, unsigned size, | |||
271 | return 0; | 265 | return 0; |
272 | 266 | ||
273 | ppcm->period_bytes_max = size; | 267 | ppcm->period_bytes_max = size; |
274 | iram_virt = sram_alloc(size, &iram_phys); | 268 | iram_virt = (void *)gen_pool_alloc(sram_pool, size); |
275 | if (!iram_virt) | 269 | if (!iram_virt) |
276 | goto exit1; | 270 | goto exit1; |
271 | iram_phys = gen_pool_virt_to_phys(sram_pool, (unsigned)iram_virt); | ||
277 | iram_dma = kzalloc(sizeof(*iram_dma), GFP_KERNEL); | 272 | iram_dma = kzalloc(sizeof(*iram_dma), GFP_KERNEL); |
278 | if (!iram_dma) | 273 | if (!iram_dma) |
279 | goto exit2; | 274 | goto exit2; |
@@ -285,11 +280,33 @@ static int allocate_sram(struct snd_pcm_substream *substream, unsigned size, | |||
285 | return 0; | 280 | return 0; |
286 | exit2: | 281 | exit2: |
287 | if (iram_virt) | 282 | if (iram_virt) |
288 | sram_free(iram_virt, size); | 283 | gen_pool_free(sram_pool, (unsigned)iram_virt, size); |
289 | exit1: | 284 | exit1: |
290 | return -ENOMEM; | 285 | return -ENOMEM; |
291 | } | 286 | } |
292 | 287 | ||
288 | static void davinci_free_sram(struct snd_pcm_substream *substream, | ||
289 | struct snd_dma_buffer *iram_dma) | ||
290 | { | ||
291 | struct davinci_runtime_data *prtd = substream->runtime->private_data; | ||
292 | struct gen_pool *sram_pool = prtd->params->sram_pool; | ||
293 | |||
294 | gen_pool_free(sram_pool, (unsigned) iram_dma->area, iram_dma->bytes); | ||
295 | } | ||
296 | #else | ||
297 | static int allocate_sram(struct snd_pcm_substream *substream, | ||
298 | struct gen_pool *sram_pool, unsigned size, | ||
299 | struct snd_pcm_hardware *ppcm) | ||
300 | { | ||
301 | return 0; | ||
302 | } | ||
303 | |||
304 | static void davinci_free_sram(struct snd_pcm_substream *substream, | ||
305 | struct snd_dma_buffer *iram_dma) | ||
306 | { | ||
307 | } | ||
308 | #endif | ||
309 | |||
293 | /* | 310 | /* |
294 | * Only used with ping/pong. | 311 | * Only used with ping/pong. |
295 | * This is called after runtime->dma_addr, period_bytes and data_type are valid | 312 | * This is called after runtime->dma_addr, period_bytes and data_type are valid |
@@ -676,7 +693,7 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream) | |||
676 | 693 | ||
677 | ppcm = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? | 694 | ppcm = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? |
678 | &pcm_hardware_playback : &pcm_hardware_capture; | 695 | &pcm_hardware_playback : &pcm_hardware_capture; |
679 | allocate_sram(substream, params->sram_size, ppcm); | 696 | allocate_sram(substream, params->sram_pool, params->sram_size, ppcm); |
680 | snd_soc_set_runtime_hwparams(substream, ppcm); | 697 | snd_soc_set_runtime_hwparams(substream, ppcm); |
681 | /* ensure that buffer size is a multiple of period size */ | 698 | /* ensure that buffer size is a multiple of period size */ |
682 | ret = snd_pcm_hw_constraint_integer(runtime, | 699 | ret = snd_pcm_hw_constraint_integer(runtime, |
@@ -819,7 +836,7 @@ static void davinci_pcm_free(struct snd_pcm *pcm) | |||
819 | buf->area = NULL; | 836 | buf->area = NULL; |
820 | iram_dma = buf->private_data; | 837 | iram_dma = buf->private_data; |
821 | if (iram_dma) { | 838 | if (iram_dma) { |
822 | sram_free(iram_dma->area, iram_dma->bytes); | 839 | davinci_free_sram(substream, iram_dma); |
823 | kfree(iram_dma); | 840 | kfree(iram_dma); |
824 | } | 841 | } |
825 | } | 842 | } |
diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h index fc4d01cdd8c9..b6ef7039dd09 100644 --- a/sound/soc/davinci/davinci-pcm.h +++ b/sound/soc/davinci/davinci-pcm.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #ifndef _DAVINCI_PCM_H | 12 | #ifndef _DAVINCI_PCM_H |
13 | #define _DAVINCI_PCM_H | 13 | #define _DAVINCI_PCM_H |
14 | 14 | ||
15 | #include <linux/genalloc.h> | ||
15 | #include <linux/platform_data/davinci_asp.h> | 16 | #include <linux/platform_data/davinci_asp.h> |
16 | #include <mach/edma.h> | 17 | #include <mach/edma.h> |
17 | 18 | ||
@@ -20,6 +21,7 @@ struct davinci_pcm_dma_params { | |||
20 | unsigned short acnt; | 21 | unsigned short acnt; |
21 | dma_addr_t dma_addr; /* device physical address for DMA */ | 22 | dma_addr_t dma_addr; /* device physical address for DMA */ |
22 | unsigned sram_size; | 23 | unsigned sram_size; |
24 | struct gen_pool *sram_pool; /* SRAM gen_pool for ping pong */ | ||
23 | enum dma_event_q asp_chan_q; /* event queue number for ASP channel */ | 25 | enum dma_event_q asp_chan_q; /* event queue number for ASP channel */ |
24 | enum dma_event_q ram_chan_q; /* event queue number for RAM channel */ | 26 | enum dma_event_q ram_chan_q; /* event queue number for RAM channel */ |
25 | unsigned char data_type; /* xfer data type */ | 27 | unsigned char data_type; /* xfer data type */ |
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 4563b28bd625..3b98159d9645 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig | |||
@@ -46,6 +46,20 @@ config SND_SOC_P1022_DS | |||
46 | This will also include the Wolfson Microelectronics WM8776 codec | 46 | This will also include the Wolfson Microelectronics WM8776 codec |
47 | driver. | 47 | driver. |
48 | 48 | ||
49 | config SND_SOC_P1022_RDK | ||
50 | tristate "ALSA SoC support for the Freescale / iVeia P1022 RDK board" | ||
51 | # I2C is necessary for the WM8960 driver | ||
52 | depends on P1022_RDK && I2C | ||
53 | select SND_SOC_FSL_SSI | ||
54 | select SND_SOC_FSL_UTILS | ||
55 | select SND_SOC_POWERPC_DMA | ||
56 | select SND_SOC_WM8960 | ||
57 | default y if P1022_RDK | ||
58 | help | ||
59 | Say Y if you want to enable audio on the Freescale / iVeia | ||
60 | P1022 RDK board. This will also include the Wolfson | ||
61 | Microelectronics WM8960 codec driver. | ||
62 | |||
49 | config SND_SOC_MPC5200_I2S | 63 | config SND_SOC_MPC5200_I2S |
50 | tristate "Freescale MPC5200 PSC in I2S mode driver" | 64 | tristate "Freescale MPC5200 PSC in I2S mode driver" |
51 | depends on PPC_MPC52xx && PPC_BESTCOMM | 65 | depends on PPC_MPC52xx && PPC_BESTCOMM |
@@ -98,12 +112,12 @@ config SND_SOC_IMX_PCM | |||
98 | tristate | 112 | tristate |
99 | 113 | ||
100 | config SND_SOC_IMX_PCM_FIQ | 114 | config SND_SOC_IMX_PCM_FIQ |
101 | tristate | 115 | bool |
102 | select FIQ | 116 | select FIQ |
103 | select SND_SOC_IMX_PCM | 117 | select SND_SOC_IMX_PCM |
104 | 118 | ||
105 | config SND_SOC_IMX_PCM_DMA | 119 | config SND_SOC_IMX_PCM_DMA |
106 | tristate | 120 | bool |
107 | select SND_SOC_DMAENGINE_PCM | 121 | select SND_SOC_DMAENGINE_PCM |
108 | select SND_SOC_IMX_PCM | 122 | select SND_SOC_IMX_PCM |
109 | 123 | ||
@@ -112,7 +126,7 @@ config SND_SOC_IMX_AUDMUX | |||
112 | 126 | ||
113 | config SND_MXC_SOC_WM1133_EV1 | 127 | config SND_MXC_SOC_WM1133_EV1 |
114 | tristate "Audio on the i.MX31ADS with WM1133-EV1 fitted" | 128 | tristate "Audio on the i.MX31ADS with WM1133-EV1 fitted" |
115 | depends on MACH_MX31ADS_WM1133_EV1 && EXPERIMENTAL | 129 | depends on MACH_MX31ADS_WM1133_EV1 |
116 | select SND_SOC_WM8350 | 130 | select SND_SOC_WM8350 |
117 | select SND_SOC_IMX_PCM_FIQ | 131 | select SND_SOC_IMX_PCM_FIQ |
118 | select SND_SOC_IMX_AUDMUX | 132 | select SND_SOC_IMX_AUDMUX |
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile index 5f3cf3f52ea0..afd34794db53 100644 --- a/sound/soc/fsl/Makefile +++ b/sound/soc/fsl/Makefile | |||
@@ -6,6 +6,10 @@ obj-$(CONFIG_SND_SOC_MPC8610_HPCD) += snd-soc-mpc8610-hpcd.o | |||
6 | snd-soc-p1022-ds-objs := p1022_ds.o | 6 | snd-soc-p1022-ds-objs := p1022_ds.o |
7 | obj-$(CONFIG_SND_SOC_P1022_DS) += snd-soc-p1022-ds.o | 7 | obj-$(CONFIG_SND_SOC_P1022_DS) += snd-soc-p1022-ds.o |
8 | 8 | ||
9 | # P1022 RDK Machine Support | ||
10 | snd-soc-p1022-rdk-objs := p1022_rdk.o | ||
11 | obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o | ||
12 | |||
9 | # Freescale PowerPC SSI/DMA Platform Support | 13 | # Freescale PowerPC SSI/DMA Platform Support |
10 | snd-soc-fsl-ssi-objs := fsl_ssi.o | 14 | snd-soc-fsl-ssi-objs := fsl_ssi.o |
11 | snd-soc-fsl-utils-objs := fsl_utils.o | 15 | snd-soc-fsl-utils-objs := fsl_utils.o |
@@ -26,14 +30,18 @@ obj-$(CONFIG_SND_MPC52xx_SOC_EFIKA) += efika-audio-fabric.o | |||
26 | # i.MX Platform Support | 30 | # i.MX Platform Support |
27 | snd-soc-imx-ssi-objs := imx-ssi.o | 31 | snd-soc-imx-ssi-objs := imx-ssi.o |
28 | snd-soc-imx-audmux-objs := imx-audmux.o | 32 | snd-soc-imx-audmux-objs := imx-audmux.o |
33 | snd-soc-imx-pcm-objs := imx-pcm.o | ||
34 | ifneq ($(CONFIG_SND_SOC_IMX_PCM_FIQ),) | ||
35 | snd-soc-imx-pcm-objs += imx-pcm-fiq.o | ||
36 | endif | ||
37 | ifneq ($(CONFIG_SND_SOC_IMX_PCM_DMA),) | ||
38 | snd-soc-imx-pcm-objs += imx-pcm-dma.o | ||
39 | endif | ||
29 | 40 | ||
30 | obj-$(CONFIG_SND_SOC_IMX_SSI) += snd-soc-imx-ssi.o | 41 | obj-$(CONFIG_SND_SOC_IMX_SSI) += snd-soc-imx-ssi.o |
31 | obj-$(CONFIG_SND_SOC_IMX_AUDMUX) += snd-soc-imx-audmux.o | 42 | obj-$(CONFIG_SND_SOC_IMX_AUDMUX) += snd-soc-imx-audmux.o |
32 | 43 | ||
33 | obj-$(CONFIG_SND_SOC_IMX_PCM) += snd-soc-imx-pcm.o | 44 | obj-$(CONFIG_SND_SOC_IMX_PCM) += snd-soc-imx-pcm.o |
34 | snd-soc-imx-pcm-y := imx-pcm.o | ||
35 | snd-soc-imx-pcm-$(CONFIG_SND_SOC_IMX_PCM_FIQ) += imx-pcm-fiq.o | ||
36 | snd-soc-imx-pcm-$(CONFIG_SND_SOC_IMX_PCM_DMA) += imx-pcm-dma.o | ||
37 | 45 | ||
38 | # i.MX Machine Support | 46 | # i.MX Machine Support |
39 | snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o | 47 | snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o |
diff --git a/sound/soc/fsl/imx-pcm.c b/sound/soc/fsl/imx-pcm.c index 93dc360b1777..d5cd9eff3b48 100644 --- a/sound/soc/fsl/imx-pcm.c +++ b/sound/soc/fsl/imx-pcm.c | |||
@@ -103,3 +103,7 @@ void imx_pcm_free(struct snd_pcm *pcm) | |||
103 | } | 103 | } |
104 | } | 104 | } |
105 | EXPORT_SYMBOL_GPL(imx_pcm_free); | 105 | EXPORT_SYMBOL_GPL(imx_pcm_free); |
106 | |||
107 | MODULE_DESCRIPTION("Freescale i.MX PCM driver"); | ||
108 | MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); | ||
109 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c index 199408ec4261..3d9b1c427ce9 100644 --- a/sound/soc/fsl/imx-sgtl5000.c +++ b/sound/soc/fsl/imx-sgtl5000.c | |||
@@ -162,6 +162,7 @@ static int __devinit imx_sgtl5000_probe(struct platform_device *pdev) | |||
162 | if (ret) | 162 | if (ret) |
163 | goto clk_fail; | 163 | goto clk_fail; |
164 | data->card.num_links = 1; | 164 | data->card.num_links = 1; |
165 | data->card.owner = THIS_MODULE; | ||
165 | data->card.dai_link = &data->dai; | 166 | data->card.dai_link = &data->dai; |
166 | data->card.dapm_widgets = imx_sgtl5000_dapm_widgets; | 167 | data->card.dapm_widgets = imx_sgtl5000_dapm_widgets; |
167 | data->card.num_dapm_widgets = ARRAY_SIZE(imx_sgtl5000_dapm_widgets); | 168 | data->card.num_dapm_widgets = ARRAY_SIZE(imx_sgtl5000_dapm_widgets); |
diff --git a/sound/soc/fsl/p1022_rdk.c b/sound/soc/fsl/p1022_rdk.c new file mode 100644 index 000000000000..897e32ffdc42 --- /dev/null +++ b/sound/soc/fsl/p1022_rdk.c | |||
@@ -0,0 +1,392 @@ | |||
1 | /** | ||
2 | * Freescale P1022RDK ALSA SoC Machine driver | ||
3 | * | ||
4 | * Author: Timur Tabi <timur@freescale.com> | ||
5 | * | ||
6 | * Copyright 2012 Freescale Semiconductor, Inc. | ||
7 | * | ||
8 | * This file is licensed under the terms of the GNU General Public License | ||
9 | * version 2. This program is licensed "as is" without any warranty of any | ||
10 | * kind, whether express or implied. | ||
11 | * | ||
12 | * Note: in order for audio to work correctly, the output controls need | ||
13 | * to be enabled, because they control the clock. So for playback, for | ||
14 | * example: | ||
15 | * | ||
16 | * amixer sset 'Left Output Mixer PCM' on | ||
17 | * amixer sset 'Right Output Mixer PCM' on | ||
18 | */ | ||
19 | |||
20 | #include <linux/module.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/of_device.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <sound/soc.h> | ||
25 | #include <asm/fsl_guts.h> | ||
26 | |||
27 | #include "fsl_dma.h" | ||
28 | #include "fsl_ssi.h" | ||
29 | #include "fsl_utils.h" | ||
30 | |||
31 | /* P1022-specific PMUXCR and DMUXCR bit definitions */ | ||
32 | |||
33 | #define CCSR_GUTS_PMUXCR_UART0_I2C1_MASK 0x0001c000 | ||
34 | #define CCSR_GUTS_PMUXCR_UART0_I2C1_UART0_SSI 0x00010000 | ||
35 | #define CCSR_GUTS_PMUXCR_UART0_I2C1_SSI 0x00018000 | ||
36 | |||
37 | #define CCSR_GUTS_PMUXCR_SSI_DMA_TDM_MASK 0x00000c00 | ||
38 | #define CCSR_GUTS_PMUXCR_SSI_DMA_TDM_SSI 0x00000000 | ||
39 | |||
40 | #define CCSR_GUTS_DMUXCR_PAD 1 /* DMA controller/channel set to pad */ | ||
41 | #define CCSR_GUTS_DMUXCR_SSI 2 /* DMA controller/channel set to SSI */ | ||
42 | |||
43 | /* | ||
44 | * Set the DMACR register in the GUTS | ||
45 | * | ||
46 | * The DMACR register determines the source of initiated transfers for each | ||
47 | * channel on each DMA controller. Rather than have a bunch of repetitive | ||
48 | * macros for the bit patterns, we just have a function that calculates | ||
49 | * them. | ||
50 | * | ||
51 | * guts: Pointer to GUTS structure | ||
52 | * co: The DMA controller (0 or 1) | ||
53 | * ch: The channel on the DMA controller (0, 1, 2, or 3) | ||
54 | * device: The device to set as the target (CCSR_GUTS_DMUXCR_xxx) | ||
55 | */ | ||
56 | static inline void guts_set_dmuxcr(struct ccsr_guts __iomem *guts, | ||
57 | unsigned int co, unsigned int ch, unsigned int device) | ||
58 | { | ||
59 | unsigned int shift = 16 + (8 * (1 - co) + 2 * (3 - ch)); | ||
60 | |||
61 | clrsetbits_be32(&guts->dmuxcr, 3 << shift, device << shift); | ||
62 | } | ||
63 | |||
64 | /* There's only one global utilities register */ | ||
65 | static phys_addr_t guts_phys; | ||
66 | |||
67 | /** | ||
68 | * machine_data: machine-specific ASoC device data | ||
69 | * | ||
70 | * This structure contains data for a single sound platform device on an | ||
71 | * P1022 RDK. Some of the data is taken from the device tree. | ||
72 | */ | ||
73 | struct machine_data { | ||
74 | struct snd_soc_dai_link dai[2]; | ||
75 | struct snd_soc_card card; | ||
76 | unsigned int dai_format; | ||
77 | unsigned int codec_clk_direction; | ||
78 | unsigned int cpu_clk_direction; | ||
79 | unsigned int clk_frequency; | ||
80 | unsigned int dma_id[2]; /* 0 = DMA1, 1 = DMA2, etc */ | ||
81 | unsigned int dma_channel_id[2]; /* 0 = ch 0, 1 = ch 1, etc*/ | ||
82 | char platform_name[2][DAI_NAME_SIZE]; /* One for each DMA channel */ | ||
83 | }; | ||
84 | |||
85 | /** | ||
86 | * p1022_rdk_machine_probe: initialize the board | ||
87 | * | ||
88 | * This function is used to initialize the board-specific hardware. | ||
89 | * | ||
90 | * Here we program the DMACR and PMUXCR registers. | ||
91 | */ | ||
92 | static int p1022_rdk_machine_probe(struct snd_soc_card *card) | ||
93 | { | ||
94 | struct machine_data *mdata = | ||
95 | container_of(card, struct machine_data, card); | ||
96 | struct ccsr_guts __iomem *guts; | ||
97 | |||
98 | guts = ioremap(guts_phys, sizeof(struct ccsr_guts)); | ||
99 | if (!guts) { | ||
100 | dev_err(card->dev, "could not map global utilities\n"); | ||
101 | return -ENOMEM; | ||
102 | } | ||
103 | |||
104 | /* Enable SSI Tx signal */ | ||
105 | clrsetbits_be32(&guts->pmuxcr, CCSR_GUTS_PMUXCR_UART0_I2C1_MASK, | ||
106 | CCSR_GUTS_PMUXCR_UART0_I2C1_UART0_SSI); | ||
107 | |||
108 | /* Enable SSI Rx signal */ | ||
109 | clrsetbits_be32(&guts->pmuxcr, CCSR_GUTS_PMUXCR_SSI_DMA_TDM_MASK, | ||
110 | CCSR_GUTS_PMUXCR_SSI_DMA_TDM_SSI); | ||
111 | |||
112 | /* Enable DMA Channel for SSI */ | ||
113 | guts_set_dmuxcr(guts, mdata->dma_id[0], mdata->dma_channel_id[0], | ||
114 | CCSR_GUTS_DMUXCR_SSI); | ||
115 | |||
116 | guts_set_dmuxcr(guts, mdata->dma_id[1], mdata->dma_channel_id[1], | ||
117 | CCSR_GUTS_DMUXCR_SSI); | ||
118 | |||
119 | iounmap(guts); | ||
120 | |||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | /** | ||
125 | * p1022_rdk_startup: program the board with various hardware parameters | ||
126 | * | ||
127 | * This function takes board-specific information, like clock frequencies | ||
128 | * and serial data formats, and passes that information to the codec and | ||
129 | * transport drivers. | ||
130 | */ | ||
131 | static int p1022_rdk_startup(struct snd_pcm_substream *substream) | ||
132 | { | ||
133 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
134 | struct machine_data *mdata = | ||
135 | container_of(rtd->card, struct machine_data, card); | ||
136 | struct device *dev = rtd->card->dev; | ||
137 | int ret = 0; | ||
138 | |||
139 | /* Tell the codec driver what the serial protocol is. */ | ||
140 | ret = snd_soc_dai_set_fmt(rtd->codec_dai, mdata->dai_format); | ||
141 | if (ret < 0) { | ||
142 | dev_err(dev, "could not set codec driver audio format (ret=%i)\n", | ||
143 | ret); | ||
144 | return ret; | ||
145 | } | ||
146 | |||
147 | ret = snd_soc_dai_set_pll(rtd->codec_dai, 0, 0, mdata->clk_frequency, | ||
148 | mdata->clk_frequency); | ||
149 | if (ret < 0) { | ||
150 | dev_err(dev, "could not set codec PLL frequency (ret=%i)\n", | ||
151 | ret); | ||
152 | return ret; | ||
153 | } | ||
154 | |||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | /** | ||
159 | * p1022_rdk_machine_remove: Remove the sound device | ||
160 | * | ||
161 | * This function is called to remove the sound device for one SSI. We | ||
162 | * de-program the DMACR and PMUXCR register. | ||
163 | */ | ||
164 | static int p1022_rdk_machine_remove(struct snd_soc_card *card) | ||
165 | { | ||
166 | struct machine_data *mdata = | ||
167 | container_of(card, struct machine_data, card); | ||
168 | struct ccsr_guts __iomem *guts; | ||
169 | |||
170 | guts = ioremap(guts_phys, sizeof(struct ccsr_guts)); | ||
171 | if (!guts) { | ||
172 | dev_err(card->dev, "could not map global utilities\n"); | ||
173 | return -ENOMEM; | ||
174 | } | ||
175 | |||
176 | /* Restore the signal routing */ | ||
177 | clrbits32(&guts->pmuxcr, CCSR_GUTS_PMUXCR_UART0_I2C1_MASK); | ||
178 | clrbits32(&guts->pmuxcr, CCSR_GUTS_PMUXCR_SSI_DMA_TDM_MASK); | ||
179 | guts_set_dmuxcr(guts, mdata->dma_id[0], mdata->dma_channel_id[0], 0); | ||
180 | guts_set_dmuxcr(guts, mdata->dma_id[1], mdata->dma_channel_id[1], 0); | ||
181 | |||
182 | iounmap(guts); | ||
183 | |||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | /** | ||
188 | * p1022_rdk_ops: ASoC machine driver operations | ||
189 | */ | ||
190 | static struct snd_soc_ops p1022_rdk_ops = { | ||
191 | .startup = p1022_rdk_startup, | ||
192 | }; | ||
193 | |||
194 | /** | ||
195 | * p1022_rdk_probe: platform probe function for the machine driver | ||
196 | * | ||
197 | * Although this is a machine driver, the SSI node is the "master" node with | ||
198 | * respect to audio hardware connections. Therefore, we create a new ASoC | ||
199 | * device for each new SSI node that has a codec attached. | ||
200 | */ | ||
201 | static int p1022_rdk_probe(struct platform_device *pdev) | ||
202 | { | ||
203 | struct device *dev = pdev->dev.parent; | ||
204 | /* ssi_pdev is the platform device for the SSI node that probed us */ | ||
205 | struct platform_device *ssi_pdev = | ||
206 | container_of(dev, struct platform_device, dev); | ||
207 | struct device_node *np = ssi_pdev->dev.of_node; | ||
208 | struct device_node *codec_np = NULL; | ||
209 | struct machine_data *mdata; | ||
210 | const u32 *iprop; | ||
211 | int ret; | ||
212 | |||
213 | /* Find the codec node for this SSI. */ | ||
214 | codec_np = of_parse_phandle(np, "codec-handle", 0); | ||
215 | if (!codec_np) { | ||
216 | dev_err(dev, "could not find codec node\n"); | ||
217 | return -EINVAL; | ||
218 | } | ||
219 | |||
220 | mdata = kzalloc(sizeof(struct machine_data), GFP_KERNEL); | ||
221 | if (!mdata) { | ||
222 | ret = -ENOMEM; | ||
223 | goto error_put; | ||
224 | } | ||
225 | |||
226 | mdata->dai[0].cpu_dai_name = dev_name(&ssi_pdev->dev); | ||
227 | mdata->dai[0].ops = &p1022_rdk_ops; | ||
228 | |||
229 | /* ASoC core can match codec with device node */ | ||
230 | mdata->dai[0].codec_of_node = codec_np; | ||
231 | |||
232 | /* | ||
233 | * We register two DAIs per SSI, one for playback and the other for | ||
234 | * capture. We support codecs that have separate DAIs for both playback | ||
235 | * and capture. | ||
236 | */ | ||
237 | memcpy(&mdata->dai[1], &mdata->dai[0], sizeof(struct snd_soc_dai_link)); | ||
238 | |||
239 | /* The DAI names from the codec (snd_soc_dai_driver.name) */ | ||
240 | mdata->dai[0].codec_dai_name = "wm8960-hifi"; | ||
241 | mdata->dai[1].codec_dai_name = mdata->dai[0].codec_dai_name; | ||
242 | |||
243 | /* | ||
244 | * Configure the SSI for I2S slave mode. Older device trees have | ||
245 | * an fsl,mode property, but we ignore that since there's really | ||
246 | * only one way to configure the SSI. | ||
247 | */ | ||
248 | mdata->dai_format = SND_SOC_DAIFMT_NB_NF | | ||
249 | SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM; | ||
250 | mdata->codec_clk_direction = SND_SOC_CLOCK_OUT; | ||
251 | mdata->cpu_clk_direction = SND_SOC_CLOCK_IN; | ||
252 | |||
253 | /* | ||
254 | * In i2s-slave mode, the codec has its own clock source, so we | ||
255 | * need to get the frequency from the device tree and pass it to | ||
256 | * the codec driver. | ||
257 | */ | ||
258 | iprop = of_get_property(codec_np, "clock-frequency", NULL); | ||
259 | if (!iprop || !*iprop) { | ||
260 | dev_err(&pdev->dev, "codec bus-frequency property is missing or invalid\n"); | ||
261 | ret = -EINVAL; | ||
262 | goto error; | ||
263 | } | ||
264 | mdata->clk_frequency = be32_to_cpup(iprop); | ||
265 | |||
266 | if (!mdata->clk_frequency) { | ||
267 | dev_err(&pdev->dev, "unknown clock frequency\n"); | ||
268 | ret = -EINVAL; | ||
269 | goto error; | ||
270 | } | ||
271 | |||
272 | /* Find the playback DMA channel to use. */ | ||
273 | mdata->dai[0].platform_name = mdata->platform_name[0]; | ||
274 | ret = fsl_asoc_get_dma_channel(np, "fsl,playback-dma", &mdata->dai[0], | ||
275 | &mdata->dma_channel_id[0], | ||
276 | &mdata->dma_id[0]); | ||
277 | if (ret) { | ||
278 | dev_err(&pdev->dev, "missing/invalid playback DMA phandle (ret=%i)\n", | ||
279 | ret); | ||
280 | goto error; | ||
281 | } | ||
282 | |||
283 | /* Find the capture DMA channel to use. */ | ||
284 | mdata->dai[1].platform_name = mdata->platform_name[1]; | ||
285 | ret = fsl_asoc_get_dma_channel(np, "fsl,capture-dma", &mdata->dai[1], | ||
286 | &mdata->dma_channel_id[1], | ||
287 | &mdata->dma_id[1]); | ||
288 | if (ret) { | ||
289 | dev_err(&pdev->dev, "missing/invalid capture DMA phandle (ret=%i)\n", | ||
290 | ret); | ||
291 | goto error; | ||
292 | } | ||
293 | |||
294 | /* Initialize our DAI data structure. */ | ||
295 | mdata->dai[0].stream_name = "playback"; | ||
296 | mdata->dai[1].stream_name = "capture"; | ||
297 | mdata->dai[0].name = mdata->dai[0].stream_name; | ||
298 | mdata->dai[1].name = mdata->dai[1].stream_name; | ||
299 | |||
300 | mdata->card.probe = p1022_rdk_machine_probe; | ||
301 | mdata->card.remove = p1022_rdk_machine_remove; | ||
302 | mdata->card.name = pdev->name; /* The platform driver name */ | ||
303 | mdata->card.owner = THIS_MODULE; | ||
304 | mdata->card.dev = &pdev->dev; | ||
305 | mdata->card.num_links = 2; | ||
306 | mdata->card.dai_link = mdata->dai; | ||
307 | |||
308 | /* Register with ASoC */ | ||
309 | ret = snd_soc_register_card(&mdata->card); | ||
310 | if (ret) { | ||
311 | dev_err(&pdev->dev, "could not register card (ret=%i)\n", ret); | ||
312 | goto error; | ||
313 | } | ||
314 | |||
315 | return 0; | ||
316 | |||
317 | error: | ||
318 | kfree(mdata); | ||
319 | error_put: | ||
320 | of_node_put(codec_np); | ||
321 | return ret; | ||
322 | } | ||
323 | |||
324 | /** | ||
325 | * p1022_rdk_remove: remove the platform device | ||
326 | * | ||
327 | * This function is called when the platform device is removed. | ||
328 | */ | ||
329 | static int __devexit p1022_rdk_remove(struct platform_device *pdev) | ||
330 | { | ||
331 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
332 | struct machine_data *mdata = | ||
333 | container_of(card, struct machine_data, card); | ||
334 | |||
335 | snd_soc_unregister_card(card); | ||
336 | kfree(mdata); | ||
337 | |||
338 | return 0; | ||
339 | } | ||
340 | |||
341 | static struct platform_driver p1022_rdk_driver = { | ||
342 | .probe = p1022_rdk_probe, | ||
343 | .remove = __devexit_p(p1022_rdk_remove), | ||
344 | .driver = { | ||
345 | /* | ||
346 | * The name must match 'compatible' property in the device tree, | ||
347 | * in lowercase letters. | ||
348 | */ | ||
349 | .name = "snd-soc-p1022rdk", | ||
350 | .owner = THIS_MODULE, | ||
351 | }, | ||
352 | }; | ||
353 | |||
354 | /** | ||
355 | * p1022_rdk_init: machine driver initialization. | ||
356 | * | ||
357 | * This function is called when this module is loaded. | ||
358 | */ | ||
359 | static int __init p1022_rdk_init(void) | ||
360 | { | ||
361 | struct device_node *guts_np; | ||
362 | struct resource res; | ||
363 | |||
364 | /* Get the physical address of the global utilities registers */ | ||
365 | guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts"); | ||
366 | if (of_address_to_resource(guts_np, 0, &res)) { | ||
367 | pr_err("snd-soc-p1022rdk: missing/invalid global utils node\n"); | ||
368 | of_node_put(guts_np); | ||
369 | return -EINVAL; | ||
370 | } | ||
371 | guts_phys = res.start; | ||
372 | of_node_put(guts_np); | ||
373 | |||
374 | return platform_driver_register(&p1022_rdk_driver); | ||
375 | } | ||
376 | |||
377 | /** | ||
378 | * p1022_rdk_exit: machine driver exit | ||
379 | * | ||
380 | * This function is called when this driver is unloaded. | ||
381 | */ | ||
382 | static void __exit p1022_rdk_exit(void) | ||
383 | { | ||
384 | platform_driver_unregister(&p1022_rdk_driver); | ||
385 | } | ||
386 | |||
387 | late_initcall(p1022_rdk_init); | ||
388 | module_exit(p1022_rdk_exit); | ||
389 | |||
390 | MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); | ||
391 | MODULE_DESCRIPTION("Freescale / iVeia P1022 RDK ALSA SoC machine driver"); | ||
392 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/fsl/pcm030-audio-fabric.c b/sound/soc/fsl/pcm030-audio-fabric.c index 4b63ec8eb372..4d261927662f 100644 --- a/sound/soc/fsl/pcm030-audio-fabric.c +++ b/sound/soc/fsl/pcm030-audio-fabric.c | |||
@@ -29,14 +29,14 @@ struct pcm030_audio_data { | |||
29 | 29 | ||
30 | static struct snd_soc_dai_link pcm030_fabric_dai[] = { | 30 | static struct snd_soc_dai_link pcm030_fabric_dai[] = { |
31 | { | 31 | { |
32 | .name = "AC97", | 32 | .name = "AC97.0", |
33 | .stream_name = "AC97 Analog", | 33 | .stream_name = "AC97 Analog", |
34 | .codec_dai_name = "wm9712-hifi", | 34 | .codec_dai_name = "wm9712-hifi", |
35 | .cpu_dai_name = "mpc5200-psc-ac97.0", | 35 | .cpu_dai_name = "mpc5200-psc-ac97.0", |
36 | .codec_name = "wm9712-codec", | 36 | .codec_name = "wm9712-codec", |
37 | }, | 37 | }, |
38 | { | 38 | { |
39 | .name = "AC97", | 39 | .name = "AC97.1", |
40 | .stream_name = "AC97 IEC958", | 40 | .stream_name = "AC97 IEC958", |
41 | .codec_dai_name = "wm9712-aux", | 41 | .codec_dai_name = "wm9712-aux", |
42 | .cpu_dai_name = "mpc5200-psc-ac97.1", | 42 | .cpu_dai_name = "mpc5200-psc-ac97.1", |
diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c index 2ba08148655f..58d5a96b366f 100644 --- a/sound/soc/kirkwood/kirkwood-dma.c +++ b/sound/soc/kirkwood/kirkwood-dma.c | |||
@@ -22,12 +22,16 @@ | |||
22 | #include "kirkwood.h" | 22 | #include "kirkwood.h" |
23 | 23 | ||
24 | #define KIRKWOOD_RATES \ | 24 | #define KIRKWOOD_RATES \ |
25 | (SNDRV_PCM_RATE_44100 | \ | 25 | (SNDRV_PCM_RATE_8000_192000 | \ |
26 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000) | 26 | SNDRV_PCM_RATE_CONTINUOUS | \ |
27 | SNDRV_PCM_RATE_KNOT) | ||
28 | |||
27 | #define KIRKWOOD_FORMATS \ | 29 | #define KIRKWOOD_FORMATS \ |
28 | (SNDRV_PCM_FMTBIT_S16_LE | \ | 30 | (SNDRV_PCM_FMTBIT_S16_LE | \ |
29 | SNDRV_PCM_FMTBIT_S24_LE | \ | 31 | SNDRV_PCM_FMTBIT_S24_LE | \ |
30 | SNDRV_PCM_FMTBIT_S32_LE) | 32 | SNDRV_PCM_FMTBIT_S32_LE | \ |
33 | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE | \ | ||
34 | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE) | ||
31 | 35 | ||
32 | struct kirkwood_dma_priv { | 36 | struct kirkwood_dma_priv { |
33 | struct snd_pcm_substream *play_stream; | 37 | struct snd_pcm_substream *play_stream; |
@@ -43,10 +47,10 @@ static struct snd_pcm_hardware kirkwood_dma_snd_hw = { | |||
43 | SNDRV_PCM_INFO_PAUSE), | 47 | SNDRV_PCM_INFO_PAUSE), |
44 | .formats = KIRKWOOD_FORMATS, | 48 | .formats = KIRKWOOD_FORMATS, |
45 | .rates = KIRKWOOD_RATES, | 49 | .rates = KIRKWOOD_RATES, |
46 | .rate_min = 44100, | 50 | .rate_min = 8000, |
47 | .rate_max = 96000, | 51 | .rate_max = 384000, |
48 | .channels_min = 1, | 52 | .channels_min = 1, |
49 | .channels_max = 2, | 53 | .channels_max = 8, |
50 | .buffer_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES * KIRKWOOD_SND_MAX_PERIODS, | 54 | .buffer_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES * KIRKWOOD_SND_MAX_PERIODS, |
51 | .period_bytes_min = KIRKWOOD_SND_MIN_PERIOD_BYTES, | 55 | .period_bytes_min = KIRKWOOD_SND_MIN_PERIOD_BYTES, |
52 | .period_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES, | 56 | .period_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES, |
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c index 1d5db484d2df..d3629d5927e9 100644 --- a/sound/soc/kirkwood/kirkwood-i2s.c +++ b/sound/soc/kirkwood/kirkwood-i2s.c | |||
@@ -99,6 +99,29 @@ static inline void kirkwood_set_dco(void __iomem *io, unsigned long rate) | |||
99 | } while (value == 0); | 99 | } while (value == 0); |
100 | } | 100 | } |
101 | 101 | ||
102 | static void kirkwood_set_rate(struct snd_soc_dai *dai, | ||
103 | struct kirkwood_dma_data *priv, unsigned long rate) | ||
104 | { | ||
105 | uint32_t clks_ctrl; | ||
106 | |||
107 | if (rate == 44100 || rate == 48000 || rate == 96000) { | ||
108 | /* use internal dco for supported rates */ | ||
109 | dev_dbg(dai->dev, "%s: dco set rate = %lu\n", | ||
110 | __func__, rate); | ||
111 | kirkwood_set_dco(priv->io, rate); | ||
112 | |||
113 | clks_ctrl = KIRKWOOD_MCLK_SOURCE_DCO; | ||
114 | } else if (!IS_ERR(priv->extclk)) { | ||
115 | /* use optional external clk for other rates */ | ||
116 | dev_dbg(dai->dev, "%s: extclk set rate = %lu -> %lu\n", | ||
117 | __func__, rate, 256 * rate); | ||
118 | clk_set_rate(priv->extclk, 256 * rate); | ||
119 | |||
120 | clks_ctrl = KIRKWOOD_MCLK_SOURCE_EXTCLK; | ||
121 | } | ||
122 | writel(clks_ctrl, priv->io + KIRKWOOD_CLOCKS_CTRL); | ||
123 | } | ||
124 | |||
102 | static int kirkwood_i2s_startup(struct snd_pcm_substream *substream, | 125 | static int kirkwood_i2s_startup(struct snd_pcm_substream *substream, |
103 | struct snd_soc_dai *dai) | 126 | struct snd_soc_dai *dai) |
104 | { | 127 | { |
@@ -113,26 +136,21 @@ static int kirkwood_i2s_hw_params(struct snd_pcm_substream *substream, | |||
113 | struct snd_soc_dai *dai) | 136 | struct snd_soc_dai *dai) |
114 | { | 137 | { |
115 | struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); | 138 | struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); |
116 | unsigned int i2s_reg, reg; | 139 | uint32_t ctl_play, ctl_rec; |
117 | unsigned long i2s_value, value; | 140 | unsigned int i2s_reg; |
141 | unsigned long i2s_value; | ||
118 | 142 | ||
119 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 143 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
120 | i2s_reg = KIRKWOOD_I2S_PLAYCTL; | 144 | i2s_reg = KIRKWOOD_I2S_PLAYCTL; |
121 | reg = KIRKWOOD_PLAYCTL; | ||
122 | } else { | 145 | } else { |
123 | i2s_reg = KIRKWOOD_I2S_RECCTL; | 146 | i2s_reg = KIRKWOOD_I2S_RECCTL; |
124 | reg = KIRKWOOD_RECCTL; | ||
125 | } | 147 | } |
126 | 148 | ||
127 | /* set dco conf */ | 149 | kirkwood_set_rate(dai, priv, params_rate(params)); |
128 | kirkwood_set_dco(priv->io, params_rate(params)); | ||
129 | 150 | ||
130 | i2s_value = readl(priv->io+i2s_reg); | 151 | i2s_value = readl(priv->io+i2s_reg); |
131 | i2s_value &= ~KIRKWOOD_I2S_CTL_SIZE_MASK; | 152 | i2s_value &= ~KIRKWOOD_I2S_CTL_SIZE_MASK; |
132 | 153 | ||
133 | value = readl(priv->io+reg); | ||
134 | value &= ~KIRKWOOD_PLAYCTL_SIZE_MASK; | ||
135 | |||
136 | /* | 154 | /* |
137 | * Size settings in play/rec i2s control regs and play/rec control | 155 | * Size settings in play/rec i2s control regs and play/rec control |
138 | * regs must be the same. | 156 | * regs must be the same. |
@@ -140,38 +158,57 @@ static int kirkwood_i2s_hw_params(struct snd_pcm_substream *substream, | |||
140 | switch (params_format(params)) { | 158 | switch (params_format(params)) { |
141 | case SNDRV_PCM_FORMAT_S16_LE: | 159 | case SNDRV_PCM_FORMAT_S16_LE: |
142 | i2s_value |= KIRKWOOD_I2S_CTL_SIZE_16; | 160 | i2s_value |= KIRKWOOD_I2S_CTL_SIZE_16; |
143 | value |= KIRKWOOD_PLAYCTL_SIZE_16_C; | 161 | ctl_play = KIRKWOOD_PLAYCTL_SIZE_16_C | |
162 | KIRKWOOD_PLAYCTL_I2S_EN; | ||
163 | ctl_rec = KIRKWOOD_RECCTL_SIZE_16_C | | ||
164 | KIRKWOOD_RECCTL_I2S_EN; | ||
144 | break; | 165 | break; |
145 | /* | 166 | /* |
146 | * doesn't work... S20_3LE != kirkwood 20bit format ? | 167 | * doesn't work... S20_3LE != kirkwood 20bit format ? |
147 | * | 168 | * |
148 | case SNDRV_PCM_FORMAT_S20_3LE: | 169 | case SNDRV_PCM_FORMAT_S20_3LE: |
149 | i2s_value |= KIRKWOOD_I2S_CTL_SIZE_20; | 170 | i2s_value |= KIRKWOOD_I2S_CTL_SIZE_20; |
150 | value |= KIRKWOOD_PLAYCTL_SIZE_20; | 171 | ctl_play = KIRKWOOD_PLAYCTL_SIZE_20 | |
172 | KIRKWOOD_PLAYCTL_I2S_EN; | ||
173 | ctl_rec = KIRKWOOD_RECCTL_SIZE_20 | | ||
174 | KIRKWOOD_RECCTL_I2S_EN; | ||
151 | break; | 175 | break; |
152 | */ | 176 | */ |
153 | case SNDRV_PCM_FORMAT_S24_LE: | 177 | case SNDRV_PCM_FORMAT_S24_LE: |
154 | i2s_value |= KIRKWOOD_I2S_CTL_SIZE_24; | 178 | i2s_value |= KIRKWOOD_I2S_CTL_SIZE_24; |
155 | value |= KIRKWOOD_PLAYCTL_SIZE_24; | 179 | ctl_play = KIRKWOOD_PLAYCTL_SIZE_24 | |
180 | KIRKWOOD_PLAYCTL_I2S_EN; | ||
181 | ctl_rec = KIRKWOOD_RECCTL_SIZE_24 | | ||
182 | KIRKWOOD_RECCTL_I2S_EN; | ||
156 | break; | 183 | break; |
157 | case SNDRV_PCM_FORMAT_S32_LE: | 184 | case SNDRV_PCM_FORMAT_S32_LE: |
158 | i2s_value |= KIRKWOOD_I2S_CTL_SIZE_32; | 185 | i2s_value |= KIRKWOOD_I2S_CTL_SIZE_32; |
159 | value |= KIRKWOOD_PLAYCTL_SIZE_32; | 186 | ctl_play = KIRKWOOD_PLAYCTL_SIZE_32 | |
187 | KIRKWOOD_PLAYCTL_I2S_EN; | ||
188 | ctl_rec = KIRKWOOD_RECCTL_SIZE_32 | | ||
189 | KIRKWOOD_RECCTL_I2S_EN; | ||
160 | break; | 190 | break; |
161 | default: | 191 | default: |
162 | return -EINVAL; | 192 | return -EINVAL; |
163 | } | 193 | } |
164 | 194 | ||
165 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 195 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
166 | value &= ~KIRKWOOD_PLAYCTL_MONO_MASK; | ||
167 | if (params_channels(params) == 1) | 196 | if (params_channels(params) == 1) |
168 | value |= KIRKWOOD_PLAYCTL_MONO_BOTH; | 197 | ctl_play |= KIRKWOOD_PLAYCTL_MONO_BOTH; |
169 | else | 198 | else |
170 | value |= KIRKWOOD_PLAYCTL_MONO_OFF; | 199 | ctl_play |= KIRKWOOD_PLAYCTL_MONO_OFF; |
200 | |||
201 | priv->ctl_play &= ~(KIRKWOOD_PLAYCTL_MONO_MASK | | ||
202 | KIRKWOOD_PLAYCTL_I2S_EN | | ||
203 | KIRKWOOD_PLAYCTL_SPDIF_EN | | ||
204 | KIRKWOOD_PLAYCTL_SIZE_MASK); | ||
205 | priv->ctl_play |= ctl_play; | ||
206 | } else { | ||
207 | priv->ctl_rec &= ~KIRKWOOD_RECCTL_SIZE_MASK; | ||
208 | priv->ctl_rec |= ctl_rec; | ||
171 | } | 209 | } |
172 | 210 | ||
173 | writel(i2s_value, priv->io+i2s_reg); | 211 | writel(i2s_value, priv->io+i2s_reg); |
174 | writel(value, priv->io+reg); | ||
175 | 212 | ||
176 | return 0; | 213 | return 0; |
177 | } | 214 | } |
@@ -205,20 +242,18 @@ static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream, | |||
205 | 242 | ||
206 | switch (cmd) { | 243 | switch (cmd) { |
207 | case SNDRV_PCM_TRIGGER_START: | 244 | case SNDRV_PCM_TRIGGER_START: |
245 | /* configure */ | ||
246 | ctl = priv->ctl_play; | ||
247 | value = ctl & ~(KIRKWOOD_PLAYCTL_I2S_EN | | ||
248 | KIRKWOOD_PLAYCTL_SPDIF_EN); | ||
249 | writel(value, priv->io + KIRKWOOD_PLAYCTL); | ||
250 | |||
251 | /* enable interrupts */ | ||
208 | value = readl(priv->io + KIRKWOOD_INT_MASK); | 252 | value = readl(priv->io + KIRKWOOD_INT_MASK); |
209 | value |= KIRKWOOD_INT_CAUSE_PLAY_BYTES; | 253 | value |= KIRKWOOD_INT_CAUSE_PLAY_BYTES; |
210 | writel(value, priv->io + KIRKWOOD_INT_MASK); | 254 | writel(value, priv->io + KIRKWOOD_INT_MASK); |
211 | 255 | ||
212 | /* configure audio & enable i2s playback */ | 256 | /* enable playback */ |
213 | ctl &= ~KIRKWOOD_PLAYCTL_BURST_MASK; | ||
214 | ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE | ||
215 | | KIRKWOOD_PLAYCTL_SPDIF_EN); | ||
216 | |||
217 | if (priv->burst == 32) | ||
218 | ctl |= KIRKWOOD_PLAYCTL_BURST_32; | ||
219 | else | ||
220 | ctl |= KIRKWOOD_PLAYCTL_BURST_128; | ||
221 | ctl |= KIRKWOOD_PLAYCTL_I2S_EN; | ||
222 | writel(ctl, priv->io + KIRKWOOD_PLAYCTL); | 257 | writel(ctl, priv->io + KIRKWOOD_PLAYCTL); |
223 | break; | 258 | break; |
224 | 259 | ||
@@ -259,30 +294,24 @@ static int kirkwood_i2s_rec_trigger(struct snd_pcm_substream *substream, | |||
259 | int cmd, struct snd_soc_dai *dai) | 294 | int cmd, struct snd_soc_dai *dai) |
260 | { | 295 | { |
261 | struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); | 296 | struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); |
262 | unsigned long value; | 297 | uint32_t ctl, value; |
263 | 298 | ||
264 | value = readl(priv->io + KIRKWOOD_RECCTL); | 299 | value = readl(priv->io + KIRKWOOD_RECCTL); |
265 | 300 | ||
266 | switch (cmd) { | 301 | switch (cmd) { |
267 | case SNDRV_PCM_TRIGGER_START: | 302 | case SNDRV_PCM_TRIGGER_START: |
303 | /* configure */ | ||
304 | ctl = priv->ctl_rec; | ||
305 | value = ctl & ~KIRKWOOD_RECCTL_I2S_EN; | ||
306 | writel(value, priv->io + KIRKWOOD_RECCTL); | ||
307 | |||
308 | /* enable interrupts */ | ||
268 | value = readl(priv->io + KIRKWOOD_INT_MASK); | 309 | value = readl(priv->io + KIRKWOOD_INT_MASK); |
269 | value |= KIRKWOOD_INT_CAUSE_REC_BYTES; | 310 | value |= KIRKWOOD_INT_CAUSE_REC_BYTES; |
270 | writel(value, priv->io + KIRKWOOD_INT_MASK); | 311 | writel(value, priv->io + KIRKWOOD_INT_MASK); |
271 | 312 | ||
272 | /* configure audio & enable i2s record */ | 313 | /* enable record */ |
273 | value = readl(priv->io + KIRKWOOD_RECCTL); | 314 | writel(ctl, priv->io + KIRKWOOD_RECCTL); |
274 | value &= ~KIRKWOOD_RECCTL_BURST_MASK; | ||
275 | value &= ~KIRKWOOD_RECCTL_MONO; | ||
276 | value &= ~(KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE | ||
277 | | KIRKWOOD_RECCTL_SPDIF_EN); | ||
278 | |||
279 | if (priv->burst == 32) | ||
280 | value |= KIRKWOOD_RECCTL_BURST_32; | ||
281 | else | ||
282 | value |= KIRKWOOD_RECCTL_BURST_128; | ||
283 | value |= KIRKWOOD_RECCTL_I2S_EN; | ||
284 | |||
285 | writel(value, priv->io + KIRKWOOD_RECCTL); | ||
286 | break; | 315 | break; |
287 | 316 | ||
288 | case SNDRV_PCM_TRIGGER_STOP: | 317 | case SNDRV_PCM_TRIGGER_STOP: |
@@ -389,90 +418,125 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai = { | |||
389 | .channels_min = 1, | 418 | .channels_min = 1, |
390 | .channels_max = 2, | 419 | .channels_max = 2, |
391 | .rates = KIRKWOOD_I2S_RATES, | 420 | .rates = KIRKWOOD_I2S_RATES, |
392 | .formats = KIRKWOOD_I2S_FORMATS,}, | 421 | .formats = KIRKWOOD_I2S_FORMATS, |
422 | }, | ||
393 | .capture = { | 423 | .capture = { |
394 | .channels_min = 1, | 424 | .channels_min = 1, |
395 | .channels_max = 2, | 425 | .channels_max = 2, |
396 | .rates = KIRKWOOD_I2S_RATES, | 426 | .rates = KIRKWOOD_I2S_RATES, |
397 | .formats = KIRKWOOD_I2S_FORMATS,}, | 427 | .formats = KIRKWOOD_I2S_FORMATS, |
428 | }, | ||
429 | .ops = &kirkwood_i2s_dai_ops, | ||
430 | }; | ||
431 | |||
432 | static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk = { | ||
433 | .probe = kirkwood_i2s_probe, | ||
434 | .remove = kirkwood_i2s_remove, | ||
435 | .playback = { | ||
436 | .channels_min = 1, | ||
437 | .channels_max = 2, | ||
438 | .rates = SNDRV_PCM_RATE_8000_192000 | | ||
439 | SNDRV_PCM_RATE_CONTINUOUS | | ||
440 | SNDRV_PCM_RATE_KNOT, | ||
441 | .formats = KIRKWOOD_I2S_FORMATS, | ||
442 | }, | ||
443 | .capture = { | ||
444 | .channels_min = 1, | ||
445 | .channels_max = 2, | ||
446 | .rates = SNDRV_PCM_RATE_8000_192000 | | ||
447 | SNDRV_PCM_RATE_CONTINUOUS | | ||
448 | SNDRV_PCM_RATE_KNOT, | ||
449 | .formats = KIRKWOOD_I2S_FORMATS, | ||
450 | }, | ||
398 | .ops = &kirkwood_i2s_dai_ops, | 451 | .ops = &kirkwood_i2s_dai_ops, |
399 | }; | 452 | }; |
400 | 453 | ||
401 | static __devinit int kirkwood_i2s_dev_probe(struct platform_device *pdev) | 454 | static __devinit int kirkwood_i2s_dev_probe(struct platform_device *pdev) |
402 | { | 455 | { |
403 | struct resource *mem; | 456 | struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data; |
404 | struct kirkwood_asoc_platform_data *data = | 457 | struct snd_soc_dai_driver *soc_dai = &kirkwood_i2s_dai; |
405 | pdev->dev.platform_data; | ||
406 | struct kirkwood_dma_data *priv; | 458 | struct kirkwood_dma_data *priv; |
459 | struct resource *mem; | ||
407 | int err; | 460 | int err; |
408 | 461 | ||
409 | priv = kzalloc(sizeof(struct kirkwood_dma_data), GFP_KERNEL); | 462 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); |
410 | if (!priv) { | 463 | if (!priv) { |
411 | dev_err(&pdev->dev, "allocation failed\n"); | 464 | dev_err(&pdev->dev, "allocation failed\n"); |
412 | err = -ENOMEM; | 465 | return -ENOMEM; |
413 | goto error; | ||
414 | } | 466 | } |
415 | dev_set_drvdata(&pdev->dev, priv); | 467 | dev_set_drvdata(&pdev->dev, priv); |
416 | 468 | ||
417 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 469 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
418 | if (!mem) { | 470 | if (!mem) { |
419 | dev_err(&pdev->dev, "platform_get_resource failed\n"); | 471 | dev_err(&pdev->dev, "platform_get_resource failed\n"); |
420 | err = -ENXIO; | 472 | return -ENXIO; |
421 | goto err_alloc; | ||
422 | } | ||
423 | |||
424 | priv->mem = request_mem_region(mem->start, SZ_16K, DRV_NAME); | ||
425 | if (!priv->mem) { | ||
426 | dev_err(&pdev->dev, "request_mem_region failed\n"); | ||
427 | err = -EBUSY; | ||
428 | goto err_alloc; | ||
429 | } | 473 | } |
430 | 474 | ||
431 | priv->io = ioremap(priv->mem->start, SZ_16K); | 475 | priv->io = devm_request_and_ioremap(&pdev->dev, mem); |
432 | if (!priv->io) { | 476 | if (!priv->io) { |
433 | dev_err(&pdev->dev, "ioremap failed\n"); | 477 | dev_err(&pdev->dev, "devm_request_and_ioremap failed\n"); |
434 | err = -ENOMEM; | 478 | return -ENOMEM; |
435 | goto err_iomem; | ||
436 | } | 479 | } |
437 | 480 | ||
438 | priv->irq = platform_get_irq(pdev, 0); | 481 | priv->irq = platform_get_irq(pdev, 0); |
439 | if (priv->irq <= 0) { | 482 | if (priv->irq <= 0) { |
440 | dev_err(&pdev->dev, "platform_get_irq failed\n"); | 483 | dev_err(&pdev->dev, "platform_get_irq failed\n"); |
441 | err = -ENXIO; | 484 | return -ENXIO; |
442 | goto err_ioremap; | ||
443 | } | 485 | } |
444 | 486 | ||
445 | if (!data) { | 487 | if (!data) { |
446 | dev_err(&pdev->dev, "no platform data ?!\n"); | 488 | dev_err(&pdev->dev, "no platform data ?!\n"); |
447 | err = -EINVAL; | 489 | return -EINVAL; |
448 | goto err_ioremap; | ||
449 | } | 490 | } |
450 | 491 | ||
451 | priv->burst = data->burst; | 492 | priv->burst = data->burst; |
452 | 493 | ||
453 | priv->clk = clk_get(&pdev->dev, NULL); | 494 | priv->clk = devm_clk_get(&pdev->dev, NULL); |
454 | if (IS_ERR(priv->clk)) { | 495 | if (IS_ERR(priv->clk)) { |
455 | dev_err(&pdev->dev, "no clock\n"); | 496 | dev_err(&pdev->dev, "no clock\n"); |
456 | err = PTR_ERR(priv->clk); | 497 | return PTR_ERR(priv->clk); |
457 | goto err_ioremap; | 498 | } |
499 | |||
500 | err = clk_prepare_enable(priv->clk); | ||
501 | if (err < 0) | ||
502 | return err; | ||
503 | |||
504 | priv->extclk = clk_get(&pdev->dev, "extclk"); | ||
505 | if (!IS_ERR(priv->extclk)) { | ||
506 | if (priv->extclk == priv->clk) { | ||
507 | clk_put(priv->extclk); | ||
508 | priv->extclk = ERR_PTR(-EINVAL); | ||
509 | } else { | ||
510 | dev_info(&pdev->dev, "found external clock\n"); | ||
511 | clk_prepare_enable(priv->extclk); | ||
512 | soc_dai = &kirkwood_i2s_dai_extclk; | ||
513 | } | ||
514 | } | ||
515 | |||
516 | /* Some sensible defaults - this reflects the powerup values */ | ||
517 | priv->ctl_play = KIRKWOOD_PLAYCTL_SIZE_24; | ||
518 | priv->ctl_rec = KIRKWOOD_RECCTL_SIZE_24; | ||
519 | |||
520 | /* Select the burst size */ | ||
521 | if (data->burst == 32) { | ||
522 | priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_32; | ||
523 | priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_32; | ||
524 | } else { | ||
525 | priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_128; | ||
526 | priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_128; | ||
458 | } | 527 | } |
459 | clk_prepare_enable(priv->clk); | ||
460 | 528 | ||
461 | err = snd_soc_register_dai(&pdev->dev, &kirkwood_i2s_dai); | 529 | err = snd_soc_register_dai(&pdev->dev, soc_dai); |
462 | if (!err) | 530 | if (!err) |
463 | return 0; | 531 | return 0; |
464 | dev_err(&pdev->dev, "snd_soc_register_dai failed\n"); | 532 | dev_err(&pdev->dev, "snd_soc_register_dai failed\n"); |
465 | 533 | ||
534 | if (!IS_ERR(priv->extclk)) { | ||
535 | clk_disable_unprepare(priv->extclk); | ||
536 | clk_put(priv->extclk); | ||
537 | } | ||
466 | clk_disable_unprepare(priv->clk); | 538 | clk_disable_unprepare(priv->clk); |
467 | clk_put(priv->clk); | 539 | |
468 | |||
469 | err_ioremap: | ||
470 | iounmap(priv->io); | ||
471 | err_iomem: | ||
472 | release_mem_region(priv->mem->start, SZ_16K); | ||
473 | err_alloc: | ||
474 | kfree(priv); | ||
475 | error: | ||
476 | return err; | 540 | return err; |
477 | } | 541 | } |
478 | 542 | ||
@@ -482,12 +546,11 @@ static __devexit int kirkwood_i2s_dev_remove(struct platform_device *pdev) | |||
482 | 546 | ||
483 | snd_soc_unregister_dai(&pdev->dev); | 547 | snd_soc_unregister_dai(&pdev->dev); |
484 | 548 | ||
549 | if (!IS_ERR(priv->extclk)) { | ||
550 | clk_disable_unprepare(priv->extclk); | ||
551 | clk_put(priv->extclk); | ||
552 | } | ||
485 | clk_disable_unprepare(priv->clk); | 553 | clk_disable_unprepare(priv->clk); |
486 | clk_put(priv->clk); | ||
487 | |||
488 | iounmap(priv->io); | ||
489 | release_mem_region(priv->mem->start, SZ_16K); | ||
490 | kfree(priv); | ||
491 | 554 | ||
492 | return 0; | 555 | return 0; |
493 | } | 556 | } |
diff --git a/sound/soc/kirkwood/kirkwood.h b/sound/soc/kirkwood/kirkwood.h index f9084d83e6bd..4d92637ddb3f 100644 --- a/sound/soc/kirkwood/kirkwood.h +++ b/sound/soc/kirkwood/kirkwood.h | |||
@@ -77,6 +77,11 @@ | |||
77 | #define KIRKWOOD_DCO_SPCR_STATUS 0x120c | 77 | #define KIRKWOOD_DCO_SPCR_STATUS 0x120c |
78 | #define KIRKWOOD_DCO_SPCR_STATUS_DCO_LOCK (1<<16) | 78 | #define KIRKWOOD_DCO_SPCR_STATUS_DCO_LOCK (1<<16) |
79 | 79 | ||
80 | #define KIRKWOOD_CLOCKS_CTRL 0x1230 | ||
81 | #define KIRKWOOD_MCLK_SOURCE_MASK (3<<0) | ||
82 | #define KIRKWOOD_MCLK_SOURCE_DCO (0<<0) | ||
83 | #define KIRKWOOD_MCLK_SOURCE_EXTCLK (3<<0) | ||
84 | |||
80 | #define KIRKWOOD_ERR_CAUSE 0x1300 | 85 | #define KIRKWOOD_ERR_CAUSE 0x1300 |
81 | #define KIRKWOOD_ERR_MASK 0x1304 | 86 | #define KIRKWOOD_ERR_MASK 0x1304 |
82 | 87 | ||
@@ -119,11 +124,13 @@ | |||
119 | #define KIRKWOOD_SND_MAX_PERIOD_BYTES 0x4000 | 124 | #define KIRKWOOD_SND_MAX_PERIOD_BYTES 0x4000 |
120 | 125 | ||
121 | struct kirkwood_dma_data { | 126 | struct kirkwood_dma_data { |
122 | struct resource *mem; | ||
123 | void __iomem *io; | 127 | void __iomem *io; |
128 | struct clk *clk; | ||
129 | struct clk *extclk; | ||
130 | uint32_t ctl_play; | ||
131 | uint32_t ctl_rec; | ||
124 | int irq; | 132 | int irq; |
125 | int burst; | 133 | int burst; |
126 | struct clk *clk; | ||
127 | }; | 134 | }; |
128 | 135 | ||
129 | #endif | 136 | #endif |
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index c294fbb523fc..b304e375568a 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c | |||
@@ -229,6 +229,7 @@ int mxs_saif_put_mclk(unsigned int saif_id) | |||
229 | saif->mclk_in_use = 0; | 229 | saif->mclk_in_use = 0; |
230 | return 0; | 230 | return 0; |
231 | } | 231 | } |
232 | EXPORT_SYMBOL_GPL(mxs_saif_put_mclk); | ||
232 | 233 | ||
233 | /* | 234 | /* |
234 | * Get MCLK and set clock rate, then enable it | 235 | * Get MCLK and set clock rate, then enable it |
@@ -282,6 +283,7 @@ int mxs_saif_get_mclk(unsigned int saif_id, unsigned int mclk, | |||
282 | 283 | ||
283 | return 0; | 284 | return 0; |
284 | } | 285 | } |
286 | EXPORT_SYMBOL_GPL(mxs_saif_get_mclk); | ||
285 | 287 | ||
286 | /* | 288 | /* |
287 | * SAIF DAI format configuration. | 289 | * SAIF DAI format configuration. |
diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c index afb8d4f1bedf..a9a243860428 100644 --- a/sound/soc/omap/mcbsp.c +++ b/sound/soc/omap/mcbsp.c | |||
@@ -28,8 +28,6 @@ | |||
28 | 28 | ||
29 | #include <linux/platform_data/asoc-ti-mcbsp.h> | 29 | #include <linux/platform_data/asoc-ti-mcbsp.h> |
30 | 30 | ||
31 | #include <plat/cpu.h> | ||
32 | |||
33 | #include "mcbsp.h" | 31 | #include "mcbsp.h" |
34 | 32 | ||
35 | static void omap_mcbsp_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val) | 33 | static void omap_mcbsp_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val) |
@@ -612,7 +610,7 @@ void omap_mcbsp_free(struct omap_mcbsp *mcbsp) | |||
612 | * system will refuse to enter idle if the CLKS pin source is not reset | 610 | * system will refuse to enter idle if the CLKS pin source is not reset |
613 | * back to internal source. | 611 | * back to internal source. |
614 | */ | 612 | */ |
615 | if (!cpu_class_is_omap1()) | 613 | if (!mcbsp_omap1()) |
616 | omap2_mcbsp_set_clks_src(mcbsp, MCBSP_CLKS_PRCM_SRC); | 614 | omap2_mcbsp_set_clks_src(mcbsp, MCBSP_CLKS_PRCM_SRC); |
617 | 615 | ||
618 | spin_lock(&mcbsp->lock); | 616 | spin_lock(&mcbsp->lock); |
diff --git a/sound/soc/omap/mcbsp.h b/sound/soc/omap/mcbsp.h index 49a67259ce5a..a89791c239a5 100644 --- a/sound/soc/omap/mcbsp.h +++ b/sound/soc/omap/mcbsp.h | |||
@@ -26,6 +26,12 @@ | |||
26 | 26 | ||
27 | #include "omap-pcm.h" | 27 | #include "omap-pcm.h" |
28 | 28 | ||
29 | #ifdef CONFIG_ARCH_OMAP1 | ||
30 | #define mcbsp_omap1() 1 | ||
31 | #else | ||
32 | #define mcbsp_omap1() 0 | ||
33 | #endif | ||
34 | |||
29 | /* McBSP register numbers. Register address offset = num * reg_step */ | 35 | /* McBSP register numbers. Register address offset = num * reg_step */ |
30 | enum { | 36 | enum { |
31 | /* Common registers */ | 37 | /* Common registers */ |
diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c index a57a4e68dcc6..1d6ea8609d28 100644 --- a/sound/soc/omap/omap-abe-twl6040.c +++ b/sound/soc/omap/omap-abe-twl6040.c | |||
@@ -331,8 +331,8 @@ static __devinit int omap_abe_probe(struct platform_device *pdev) | |||
331 | num_links = 1; | 331 | num_links = 1; |
332 | } | 332 | } |
333 | 333 | ||
334 | of_property_read_u32(node, "ti,jack-detection", | 334 | priv->jack_detection = of_property_read_bool(node, |
335 | &priv->jack_detection); | 335 | "ti,jack-detection"); |
336 | of_property_read_u32(node, "ti,mclk-freq", | 336 | of_property_read_u32(node, "ti,mclk-freq", |
337 | &priv->mclk_freq); | 337 | &priv->mclk_freq); |
338 | if (!priv->mclk_freq) { | 338 | if (!priv->mclk_freq) { |
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index a6ee15747859..09167609c93e 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <sound/initval.h> | 34 | #include <sound/initval.h> |
35 | #include <sound/soc.h> | 35 | #include <sound/soc.h> |
36 | 36 | ||
37 | #include <plat/cpu.h> | ||
38 | #include <linux/platform_data/asoc-ti-mcbsp.h> | 37 | #include <linux/platform_data/asoc-ti-mcbsp.h> |
39 | #include "mcbsp.h" | 38 | #include "mcbsp.h" |
40 | #include "omap-mcbsp.h" | 39 | #include "omap-mcbsp.h" |
@@ -512,7 +511,7 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, | |||
512 | regs->srgr2 |= CLKSM; | 511 | regs->srgr2 |= CLKSM; |
513 | break; | 512 | break; |
514 | case OMAP_MCBSP_SYSCLK_CLKS_FCLK: | 513 | case OMAP_MCBSP_SYSCLK_CLKS_FCLK: |
515 | if (cpu_class_is_omap1()) { | 514 | if (mcbsp_omap1()) { |
516 | err = -EINVAL; | 515 | err = -EINVAL; |
517 | break; | 516 | break; |
518 | } | 517 | } |
@@ -520,7 +519,7 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, | |||
520 | MCBSP_CLKS_PRCM_SRC); | 519 | MCBSP_CLKS_PRCM_SRC); |
521 | break; | 520 | break; |
522 | case OMAP_MCBSP_SYSCLK_CLKS_EXT: | 521 | case OMAP_MCBSP_SYSCLK_CLKS_EXT: |
523 | if (cpu_class_is_omap1()) { | 522 | if (mcbsp_omap1()) { |
524 | err = 0; | 523 | err = 0; |
525 | break; | 524 | break; |
526 | } | 525 | } |
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c index 14fbcd30cae5..386bab1f99ab 100644 --- a/sound/soc/samsung/ac97.c +++ b/sound/soc/samsung/ac97.c | |||
@@ -442,7 +442,7 @@ static __devinit int s3c_ac97_probe(struct platform_device *pdev) | |||
442 | ret = -ENODEV; | 442 | ret = -ENODEV; |
443 | goto err2; | 443 | goto err2; |
444 | } | 444 | } |
445 | clk_enable(s3c_ac97.ac97_clk); | 445 | clk_prepare_enable(s3c_ac97.ac97_clk); |
446 | 446 | ||
447 | if (ac97_pdata->cfg_gpio(pdev)) { | 447 | if (ac97_pdata->cfg_gpio(pdev)) { |
448 | dev_err(&pdev->dev, "Unable to configure gpio\n"); | 448 | dev_err(&pdev->dev, "Unable to configure gpio\n"); |
@@ -468,7 +468,7 @@ err5: | |||
468 | free_irq(irq_res->start, NULL); | 468 | free_irq(irq_res->start, NULL); |
469 | err4: | 469 | err4: |
470 | err3: | 470 | err3: |
471 | clk_disable(s3c_ac97.ac97_clk); | 471 | clk_disable_unprepare(s3c_ac97.ac97_clk); |
472 | clk_put(s3c_ac97.ac97_clk); | 472 | clk_put(s3c_ac97.ac97_clk); |
473 | err2: | 473 | err2: |
474 | iounmap(s3c_ac97.regs); | 474 | iounmap(s3c_ac97.regs); |
@@ -488,7 +488,7 @@ static __devexit int s3c_ac97_remove(struct platform_device *pdev) | |||
488 | if (irq_res) | 488 | if (irq_res) |
489 | free_irq(irq_res->start, NULL); | 489 | free_irq(irq_res->start, NULL); |
490 | 490 | ||
491 | clk_disable(s3c_ac97.ac97_clk); | 491 | clk_disable_unprepare(s3c_ac97.ac97_clk); |
492 | clk_put(s3c_ac97.ac97_clk); | 492 | clk_put(s3c_ac97.ac97_clk); |
493 | 493 | ||
494 | iounmap(s3c_ac97.regs); | 494 | iounmap(s3c_ac97.regs); |
diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c index a2ca1567b9e4..59ffd6c7ee30 100644 --- a/sound/soc/samsung/bells.c +++ b/sound/soc/samsung/bells.c | |||
@@ -18,15 +18,6 @@ | |||
18 | #include "../codecs/wm5102.h" | 18 | #include "../codecs/wm5102.h" |
19 | #include "../codecs/wm9081.h" | 19 | #include "../codecs/wm9081.h" |
20 | 20 | ||
21 | /* | ||
22 | * 44.1kHz based clocks for the SYSCLK domain, use a very high clock | ||
23 | * to allow all the DSP functionality to be enabled if desired. | ||
24 | */ | ||
25 | #define SYSCLK_RATE (44100 * 1024) | ||
26 | |||
27 | /* 48kHz based clocks for the ASYNC domain */ | ||
28 | #define ASYNCCLK_RATE (48000 * 512) | ||
29 | |||
30 | /* BCLK2 is fixed at this currently */ | 21 | /* BCLK2 is fixed at this currently */ |
31 | #define BCLK2_RATE (64 * 8000) | 22 | #define BCLK2_RATE (64 * 8000) |
32 | 23 | ||
@@ -36,15 +27,40 @@ | |||
36 | */ | 27 | */ |
37 | #define MCLK_RATE 24576000 | 28 | #define MCLK_RATE 24576000 |
38 | 29 | ||
39 | #define WM9081_AUDIO_RATE 44100 | 30 | #define SYS_AUDIO_RATE 44100 |
40 | #define WM9081_MCLK_RATE (WM9081_AUDIO_RATE * 256) | 31 | #define SYS_MCLK_RATE (SYS_AUDIO_RATE * 512) |
32 | |||
33 | #define DAI_AP_DSP 0 | ||
34 | #define DAI_DSP_CODEC 1 | ||
35 | #define DAI_CODEC_CP 2 | ||
36 | #define DAI_CODEC_SUB 3 | ||
37 | |||
38 | struct bells_drvdata { | ||
39 | int sysclk_rate; | ||
40 | int asyncclk_rate; | ||
41 | }; | ||
42 | |||
43 | static struct bells_drvdata wm2200_drvdata = { | ||
44 | .sysclk_rate = 22579200, | ||
45 | }; | ||
46 | |||
47 | static struct bells_drvdata wm5102_drvdata = { | ||
48 | .sysclk_rate = 45158400, | ||
49 | .asyncclk_rate = 49152000, | ||
50 | }; | ||
51 | |||
52 | static struct bells_drvdata wm5110_drvdata = { | ||
53 | .sysclk_rate = 135475200, | ||
54 | .asyncclk_rate = 147456000, | ||
55 | }; | ||
41 | 56 | ||
42 | static int bells_set_bias_level(struct snd_soc_card *card, | 57 | static int bells_set_bias_level(struct snd_soc_card *card, |
43 | struct snd_soc_dapm_context *dapm, | 58 | struct snd_soc_dapm_context *dapm, |
44 | enum snd_soc_bias_level level) | 59 | enum snd_soc_bias_level level) |
45 | { | 60 | { |
46 | struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; | 61 | struct snd_soc_dai *codec_dai = card->rtd[DAI_DSP_CODEC].codec_dai; |
47 | struct snd_soc_codec *codec = codec_dai->codec; | 62 | struct snd_soc_codec *codec = codec_dai->codec; |
63 | struct bells_drvdata *bells = card->drvdata; | ||
48 | int ret; | 64 | int ret; |
49 | 65 | ||
50 | if (dapm->dev != codec_dai->dev) | 66 | if (dapm->dev != codec_dai->dev) |
@@ -52,18 +68,21 @@ static int bells_set_bias_level(struct snd_soc_card *card, | |||
52 | 68 | ||
53 | switch (level) { | 69 | switch (level) { |
54 | case SND_SOC_BIAS_PREPARE: | 70 | case SND_SOC_BIAS_PREPARE: |
55 | if (dapm->bias_level == SND_SOC_BIAS_STANDBY) { | 71 | if (dapm->bias_level != SND_SOC_BIAS_STANDBY) |
56 | ret = snd_soc_codec_set_pll(codec, WM5102_FLL1, | 72 | break; |
57 | ARIZONA_FLL_SRC_MCLK1, | 73 | |
58 | MCLK_RATE, | 74 | ret = snd_soc_codec_set_pll(codec, WM5102_FLL1, |
59 | SYSCLK_RATE); | 75 | ARIZONA_FLL_SRC_MCLK1, |
60 | if (ret < 0) | 76 | MCLK_RATE, |
61 | pr_err("Failed to start FLL: %d\n", ret); | 77 | bells->sysclk_rate); |
78 | if (ret < 0) | ||
79 | pr_err("Failed to start FLL: %d\n", ret); | ||
62 | 80 | ||
81 | if (bells->asyncclk_rate) { | ||
63 | ret = snd_soc_codec_set_pll(codec, WM5102_FLL2, | 82 | ret = snd_soc_codec_set_pll(codec, WM5102_FLL2, |
64 | ARIZONA_FLL_SRC_AIF2BCLK, | 83 | ARIZONA_FLL_SRC_AIF2BCLK, |
65 | BCLK2_RATE, | 84 | BCLK2_RATE, |
66 | ASYNCCLK_RATE); | 85 | bells->asyncclk_rate); |
67 | if (ret < 0) | 86 | if (ret < 0) |
68 | pr_err("Failed to start FLL: %d\n", ret); | 87 | pr_err("Failed to start FLL: %d\n", ret); |
69 | } | 88 | } |
@@ -80,8 +99,9 @@ static int bells_set_bias_level_post(struct snd_soc_card *card, | |||
80 | struct snd_soc_dapm_context *dapm, | 99 | struct snd_soc_dapm_context *dapm, |
81 | enum snd_soc_bias_level level) | 100 | enum snd_soc_bias_level level) |
82 | { | 101 | { |
83 | struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; | 102 | struct snd_soc_dai *codec_dai = card->rtd[DAI_DSP_CODEC].codec_dai; |
84 | struct snd_soc_codec *codec = codec_dai->codec; | 103 | struct snd_soc_codec *codec = codec_dai->codec; |
104 | struct bells_drvdata *bells = card->drvdata; | ||
85 | int ret; | 105 | int ret; |
86 | 106 | ||
87 | if (dapm->dev != codec_dai->dev) | 107 | if (dapm->dev != codec_dai->dev) |
@@ -95,10 +115,13 @@ static int bells_set_bias_level_post(struct snd_soc_card *card, | |||
95 | return ret; | 115 | return ret; |
96 | } | 116 | } |
97 | 117 | ||
98 | ret = snd_soc_codec_set_pll(codec, WM5102_FLL2, 0, 0, 0); | 118 | if (bells->asyncclk_rate) { |
99 | if (ret < 0) { | 119 | ret = snd_soc_codec_set_pll(codec, WM5102_FLL2, |
100 | pr_err("Failed to stop FLL: %d\n", ret); | 120 | 0, 0, 0); |
101 | return ret; | 121 | if (ret < 0) { |
122 | pr_err("Failed to stop FLL: %d\n", ret); | ||
123 | return ret; | ||
124 | } | ||
102 | } | 125 | } |
103 | break; | 126 | break; |
104 | 127 | ||
@@ -113,56 +136,73 @@ static int bells_set_bias_level_post(struct snd_soc_card *card, | |||
113 | 136 | ||
114 | static int bells_late_probe(struct snd_soc_card *card) | 137 | static int bells_late_probe(struct snd_soc_card *card) |
115 | { | 138 | { |
116 | struct snd_soc_codec *codec = card->rtd[0].codec; | 139 | struct bells_drvdata *bells = card->drvdata; |
117 | struct snd_soc_dai *aif1_dai = card->rtd[0].codec_dai; | 140 | struct snd_soc_codec *wm0010 = card->rtd[DAI_AP_DSP].codec; |
118 | struct snd_soc_dai *aif2_dai = card->rtd[1].cpu_dai; | 141 | struct snd_soc_codec *codec = card->rtd[DAI_DSP_CODEC].codec; |
119 | struct snd_soc_dai *aif3_dai = card->rtd[2].cpu_dai; | 142 | struct snd_soc_dai *aif1_dai = card->rtd[DAI_DSP_CODEC].codec_dai; |
120 | struct snd_soc_dai *wm9081_dai = card->rtd[2].codec_dai; | 143 | struct snd_soc_dai *aif2_dai; |
144 | struct snd_soc_dai *aif3_dai; | ||
145 | struct snd_soc_dai *wm9081_dai; | ||
121 | int ret; | 146 | int ret; |
122 | 147 | ||
123 | ret = snd_soc_dai_set_sysclk(aif1_dai, ARIZONA_CLK_SYSCLK, 0, 0); | 148 | ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK, |
149 | ARIZONA_CLK_SRC_FLL1, | ||
150 | bells->sysclk_rate, | ||
151 | SND_SOC_CLOCK_IN); | ||
124 | if (ret != 0) { | 152 | if (ret != 0) { |
125 | dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret); | 153 | dev_err(codec->dev, "Failed to set SYSCLK: %d\n", ret); |
126 | return ret; | 154 | return ret; |
127 | } | 155 | } |
128 | 156 | ||
129 | ret = snd_soc_dai_set_sysclk(aif2_dai, ARIZONA_CLK_ASYNCCLK, 0, 0); | 157 | ret = snd_soc_codec_set_sysclk(wm0010, 0, 0, SYS_MCLK_RATE, 0); |
130 | if (ret != 0) { | 158 | if (ret != 0) { |
131 | dev_err(aif2_dai->dev, "Failed to set AIF2 clock: %d\n", ret); | 159 | dev_err(wm0010->dev, "Failed to set WM0010 clock: %d\n", ret); |
132 | return ret; | 160 | return ret; |
133 | } | 161 | } |
134 | 162 | ||
135 | ret = snd_soc_dai_set_sysclk(aif3_dai, ARIZONA_CLK_SYSCLK, 0, 0); | 163 | ret = snd_soc_dai_set_sysclk(aif1_dai, ARIZONA_CLK_SYSCLK, 0, 0); |
136 | if (ret != 0) { | 164 | if (ret != 0) |
137 | dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret); | 165 | dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret); |
138 | return ret; | ||
139 | } | ||
140 | 166 | ||
141 | ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK, | 167 | ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_OPCLK, 0, |
142 | ARIZONA_CLK_SRC_FLL1, SYSCLK_RATE, | 168 | SYS_MCLK_RATE, SND_SOC_CLOCK_OUT); |
169 | if (ret != 0) | ||
170 | dev_err(codec->dev, "Failed to set OPCLK: %d\n", ret); | ||
171 | |||
172 | if (card->num_rtd == DAI_CODEC_CP) | ||
173 | return 0; | ||
174 | |||
175 | ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_ASYNCCLK, | ||
176 | ARIZONA_CLK_SRC_FLL2, | ||
177 | bells->asyncclk_rate, | ||
143 | SND_SOC_CLOCK_IN); | 178 | SND_SOC_CLOCK_IN); |
144 | if (ret != 0) { | 179 | if (ret != 0) { |
145 | dev_err(codec->dev, "Failed to set SYSCLK: %d\n", ret); | 180 | dev_err(codec->dev, "Failed to set ASYNCCLK: %d\n", ret); |
146 | return ret; | 181 | return ret; |
147 | } | 182 | } |
148 | 183 | ||
149 | ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_OPCLK, 0, | 184 | aif2_dai = card->rtd[DAI_CODEC_CP].cpu_dai; |
150 | WM9081_MCLK_RATE, SND_SOC_CLOCK_OUT); | 185 | |
186 | ret = snd_soc_dai_set_sysclk(aif2_dai, ARIZONA_CLK_ASYNCCLK, 0, 0); | ||
151 | if (ret != 0) { | 187 | if (ret != 0) { |
152 | dev_err(codec->dev, "Failed to set OPCLK: %d\n", ret); | 188 | dev_err(aif2_dai->dev, "Failed to set AIF2 clock: %d\n", ret); |
153 | return ret; | 189 | return ret; |
154 | } | 190 | } |
155 | 191 | ||
156 | ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_ASYNCCLK, | 192 | if (card->num_rtd == DAI_CODEC_SUB) |
157 | ARIZONA_CLK_SRC_FLL2, ASYNCCLK_RATE, | 193 | return 0; |
158 | SND_SOC_CLOCK_IN); | 194 | |
195 | aif3_dai = card->rtd[DAI_CODEC_SUB].cpu_dai; | ||
196 | wm9081_dai = card->rtd[DAI_CODEC_SUB].codec_dai; | ||
197 | |||
198 | ret = snd_soc_dai_set_sysclk(aif3_dai, ARIZONA_CLK_SYSCLK, 0, 0); | ||
159 | if (ret != 0) { | 199 | if (ret != 0) { |
160 | dev_err(codec->dev, "Failed to set SYSCLK: %d\n", ret); | 200 | dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret); |
161 | return ret; | 201 | return ret; |
162 | } | 202 | } |
163 | 203 | ||
164 | ret = snd_soc_codec_set_sysclk(wm9081_dai->codec, WM9081_SYSCLK_MCLK, | 204 | ret = snd_soc_codec_set_sysclk(wm9081_dai->codec, WM9081_SYSCLK_MCLK, |
165 | 0, WM9081_MCLK_RATE, 0); | 205 | 0, SYS_MCLK_RATE, 0); |
166 | if (ret != 0) { | 206 | if (ret != 0) { |
167 | dev_err(wm9081_dai->dev, "Failed to set MCLK: %d\n", ret); | 207 | dev_err(wm9081_dai->dev, "Failed to set MCLK: %d\n", ret); |
168 | return ret; | 208 | return ret; |
@@ -181,22 +221,57 @@ static const struct snd_soc_pcm_stream baseband_params = { | |||
181 | 221 | ||
182 | static const struct snd_soc_pcm_stream sub_params = { | 222 | static const struct snd_soc_pcm_stream sub_params = { |
183 | .formats = SNDRV_PCM_FMTBIT_S32_LE, | 223 | .formats = SNDRV_PCM_FMTBIT_S32_LE, |
184 | .rate_min = WM9081_AUDIO_RATE, | 224 | .rate_min = SYS_AUDIO_RATE, |
185 | .rate_max = WM9081_AUDIO_RATE, | 225 | .rate_max = SYS_AUDIO_RATE, |
186 | .channels_min = 2, | 226 | .channels_min = 2, |
187 | .channels_max = 2, | 227 | .channels_max = 2, |
188 | }; | 228 | }; |
189 | 229 | ||
230 | static struct snd_soc_dai_link bells_dai_wm2200[] = { | ||
231 | { | ||
232 | .name = "CPU-DSP", | ||
233 | .stream_name = "CPU-DSP", | ||
234 | .cpu_dai_name = "samsung-i2s.0", | ||
235 | .codec_dai_name = "wm0010-sdi1", | ||
236 | .platform_name = "samsung-audio", | ||
237 | .codec_name = "spi0.0", | ||
238 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ||
239 | | SND_SOC_DAIFMT_CBM_CFM, | ||
240 | }, | ||
241 | { | ||
242 | .name = "DSP-CODEC", | ||
243 | .stream_name = "DSP-CODEC", | ||
244 | .cpu_dai_name = "wm0010-sdi2", | ||
245 | .codec_dai_name = "wm2200", | ||
246 | .codec_name = "wm2200.1-003a", | ||
247 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ||
248 | | SND_SOC_DAIFMT_CBM_CFM, | ||
249 | .params = &sub_params, | ||
250 | .ignore_suspend = 1, | ||
251 | }, | ||
252 | }; | ||
253 | |||
190 | static struct snd_soc_dai_link bells_dai_wm5102[] = { | 254 | static struct snd_soc_dai_link bells_dai_wm5102[] = { |
191 | { | 255 | { |
192 | .name = "CPU", | 256 | .name = "CPU-DSP", |
193 | .stream_name = "CPU", | 257 | .stream_name = "CPU-DSP", |
194 | .cpu_dai_name = "samsung-i2s.0", | 258 | .cpu_dai_name = "samsung-i2s.0", |
195 | .codec_dai_name = "wm5102-aif1", | 259 | .codec_dai_name = "wm0010-sdi1", |
196 | .platform_name = "samsung-audio", | 260 | .platform_name = "samsung-audio", |
261 | .codec_name = "spi0.0", | ||
262 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ||
263 | | SND_SOC_DAIFMT_CBM_CFM, | ||
264 | }, | ||
265 | { | ||
266 | .name = "DSP-CODEC", | ||
267 | .stream_name = "DSP-CODEC", | ||
268 | .cpu_dai_name = "wm0010-sdi2", | ||
269 | .codec_dai_name = "wm5102-aif1", | ||
197 | .codec_name = "wm5102-codec", | 270 | .codec_name = "wm5102-codec", |
198 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 271 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
199 | | SND_SOC_DAIFMT_CBM_CFM, | 272 | | SND_SOC_DAIFMT_CBM_CFM, |
273 | .params = &sub_params, | ||
274 | .ignore_suspend = 1, | ||
200 | }, | 275 | }, |
201 | { | 276 | { |
202 | .name = "Baseband", | 277 | .name = "Baseband", |
@@ -224,14 +299,25 @@ static struct snd_soc_dai_link bells_dai_wm5102[] = { | |||
224 | 299 | ||
225 | static struct snd_soc_dai_link bells_dai_wm5110[] = { | 300 | static struct snd_soc_dai_link bells_dai_wm5110[] = { |
226 | { | 301 | { |
227 | .name = "CPU", | 302 | .name = "CPU-DSP", |
228 | .stream_name = "CPU", | 303 | .stream_name = "CPU-DSP", |
229 | .cpu_dai_name = "samsung-i2s.0", | 304 | .cpu_dai_name = "samsung-i2s.0", |
230 | .codec_dai_name = "wm5110-aif1", | 305 | .codec_dai_name = "wm0010-sdi1", |
231 | .platform_name = "samsung-audio", | 306 | .platform_name = "samsung-audio", |
307 | .codec_name = "spi0.0", | ||
308 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ||
309 | | SND_SOC_DAIFMT_CBM_CFM, | ||
310 | }, | ||
311 | { | ||
312 | .name = "DSP-CODEC", | ||
313 | .stream_name = "DSP-CODEC", | ||
314 | .cpu_dai_name = "wm0010-sdi2", | ||
315 | .codec_dai_name = "wm5110-aif1", | ||
232 | .codec_name = "wm5110-codec", | 316 | .codec_name = "wm5110-codec", |
233 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 317 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
234 | | SND_SOC_DAIFMT_CBM_CFM, | 318 | | SND_SOC_DAIFMT_CBM_CFM, |
319 | .params = &sub_params, | ||
320 | .ignore_suspend = 1, | ||
235 | }, | 321 | }, |
236 | { | 322 | { |
237 | .name = "Baseband", | 323 | .name = "Baseband", |
@@ -270,6 +356,24 @@ static struct snd_soc_dapm_route bells_routes[] = { | |||
270 | 356 | ||
271 | static struct snd_soc_card bells_cards[] = { | 357 | static struct snd_soc_card bells_cards[] = { |
272 | { | 358 | { |
359 | .name = "Bells WM2200", | ||
360 | .owner = THIS_MODULE, | ||
361 | .dai_link = bells_dai_wm2200, | ||
362 | .num_links = ARRAY_SIZE(bells_dai_wm2200), | ||
363 | .codec_conf = bells_codec_conf, | ||
364 | .num_configs = ARRAY_SIZE(bells_codec_conf), | ||
365 | |||
366 | .late_probe = bells_late_probe, | ||
367 | |||
368 | .dapm_routes = bells_routes, | ||
369 | .num_dapm_routes = ARRAY_SIZE(bells_routes), | ||
370 | |||
371 | .set_bias_level = bells_set_bias_level, | ||
372 | .set_bias_level_post = bells_set_bias_level_post, | ||
373 | |||
374 | .drvdata = &wm2200_drvdata, | ||
375 | }, | ||
376 | { | ||
273 | .name = "Bells WM5102", | 377 | .name = "Bells WM5102", |
274 | .owner = THIS_MODULE, | 378 | .owner = THIS_MODULE, |
275 | .dai_link = bells_dai_wm5102, | 379 | .dai_link = bells_dai_wm5102, |
@@ -284,6 +388,8 @@ static struct snd_soc_card bells_cards[] = { | |||
284 | 388 | ||
285 | .set_bias_level = bells_set_bias_level, | 389 | .set_bias_level = bells_set_bias_level, |
286 | .set_bias_level_post = bells_set_bias_level_post, | 390 | .set_bias_level_post = bells_set_bias_level_post, |
391 | |||
392 | .drvdata = &wm5102_drvdata, | ||
287 | }, | 393 | }, |
288 | { | 394 | { |
289 | .name = "Bells WM5110", | 395 | .name = "Bells WM5110", |
@@ -300,6 +406,8 @@ static struct snd_soc_card bells_cards[] = { | |||
300 | 406 | ||
301 | .set_bias_level = bells_set_bias_level, | 407 | .set_bias_level = bells_set_bias_level, |
302 | .set_bias_level_post = bells_set_bias_level_post, | 408 | .set_bias_level_post = bells_set_bias_level_post, |
409 | |||
410 | .drvdata = &wm5110_drvdata, | ||
303 | }, | 411 | }, |
304 | }; | 412 | }; |
305 | 413 | ||
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 40b00a13dcd1..aaf57b7caebb 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c | |||
@@ -49,8 +49,6 @@ struct i2s_dai { | |||
49 | struct clk *clk; | 49 | struct clk *clk; |
50 | /* Clock for generating I2S signals */ | 50 | /* Clock for generating I2S signals */ |
51 | struct clk *op_clk; | 51 | struct clk *op_clk; |
52 | /* Array of clock names for op_clk */ | ||
53 | const char **src_clk; | ||
54 | /* Pointer to the Primary_Fifo if this is Sec_Fifo, NULL otherwise */ | 52 | /* Pointer to the Primary_Fifo if this is Sec_Fifo, NULL otherwise */ |
55 | struct i2s_dai *pri_dai; | 53 | struct i2s_dai *pri_dai; |
56 | /* Pointer to the Secondary_Fifo if it has one, NULL otherwise */ | 54 | /* Pointer to the Secondary_Fifo if it has one, NULL otherwise */ |
@@ -423,7 +421,7 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, | |||
423 | if (i2s->op_clk) { | 421 | if (i2s->op_clk) { |
424 | if ((clk_id && !(mod & MOD_IMS_SYSMUX)) || | 422 | if ((clk_id && !(mod & MOD_IMS_SYSMUX)) || |
425 | (!clk_id && (mod & MOD_IMS_SYSMUX))) { | 423 | (!clk_id && (mod & MOD_IMS_SYSMUX))) { |
426 | clk_disable(i2s->op_clk); | 424 | clk_disable_unprepare(i2s->op_clk); |
427 | clk_put(i2s->op_clk); | 425 | clk_put(i2s->op_clk); |
428 | } else { | 426 | } else { |
429 | i2s->rclk_srcrate = | 427 | i2s->rclk_srcrate = |
@@ -432,9 +430,13 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, | |||
432 | } | 430 | } |
433 | } | 431 | } |
434 | 432 | ||
435 | i2s->op_clk = clk_get(&i2s->pdev->dev, | 433 | if (clk_id) |
436 | i2s->src_clk[clk_id]); | 434 | i2s->op_clk = clk_get(&i2s->pdev->dev, |
437 | clk_enable(i2s->op_clk); | 435 | "i2s_opclk1"); |
436 | else | ||
437 | i2s->op_clk = clk_get(&i2s->pdev->dev, | ||
438 | "i2s_opclk0"); | ||
439 | clk_prepare_enable(i2s->op_clk); | ||
438 | i2s->rclk_srcrate = clk_get_rate(i2s->op_clk); | 440 | i2s->rclk_srcrate = clk_get_rate(i2s->op_clk); |
439 | 441 | ||
440 | /* Over-ride the other's */ | 442 | /* Over-ride the other's */ |
@@ -880,7 +882,7 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) | |||
880 | iounmap(i2s->addr); | 882 | iounmap(i2s->addr); |
881 | return -ENOENT; | 883 | return -ENOENT; |
882 | } | 884 | } |
883 | clk_enable(i2s->clk); | 885 | clk_prepare_enable(i2s->clk); |
884 | 886 | ||
885 | if (other) { | 887 | if (other) { |
886 | other->addr = i2s->addr; | 888 | other->addr = i2s->addr; |
@@ -922,7 +924,7 @@ static int samsung_i2s_dai_remove(struct snd_soc_dai *dai) | |||
922 | if (i2s->quirks & QUIRK_NEED_RSTCLR) | 924 | if (i2s->quirks & QUIRK_NEED_RSTCLR) |
923 | writel(0, i2s->addr + I2SCON); | 925 | writel(0, i2s->addr + I2SCON); |
924 | 926 | ||
925 | clk_disable(i2s->clk); | 927 | clk_disable_unprepare(i2s->clk); |
926 | clk_put(i2s->clk); | 928 | clk_put(i2s->clk); |
927 | 929 | ||
928 | iounmap(i2s->addr); | 930 | iounmap(i2s->addr); |
@@ -1067,7 +1069,6 @@ static __devinit int samsung_i2s_probe(struct platform_device *pdev) | |||
1067 | (struct s3c2410_dma_client *)&pri_dai->dma_capture; | 1069 | (struct s3c2410_dma_client *)&pri_dai->dma_capture; |
1068 | pri_dai->dma_playback.channel = dma_pl_chan; | 1070 | pri_dai->dma_playback.channel = dma_pl_chan; |
1069 | pri_dai->dma_capture.channel = dma_cp_chan; | 1071 | pri_dai->dma_capture.channel = dma_cp_chan; |
1070 | pri_dai->src_clk = i2s_cfg->src_clk; | ||
1071 | pri_dai->dma_playback.dma_size = 4; | 1072 | pri_dai->dma_playback.dma_size = 4; |
1072 | pri_dai->dma_capture.dma_size = 4; | 1073 | pri_dai->dma_capture.dma_size = 4; |
1073 | pri_dai->base = regs_base; | 1074 | pri_dai->base = regs_base; |
@@ -1088,7 +1089,6 @@ static __devinit int samsung_i2s_probe(struct platform_device *pdev) | |||
1088 | (struct s3c2410_dma_client *)&sec_dai->dma_playback; | 1089 | (struct s3c2410_dma_client *)&sec_dai->dma_playback; |
1089 | /* Use iDMA always if SysDMA not provided */ | 1090 | /* Use iDMA always if SysDMA not provided */ |
1090 | sec_dai->dma_playback.channel = dma_pl_sec_chan ? : -1; | 1091 | sec_dai->dma_playback.channel = dma_pl_sec_chan ? : -1; |
1091 | sec_dai->src_clk = i2s_cfg->src_clk; | ||
1092 | sec_dai->dma_playback.dma_size = 4; | 1092 | sec_dai->dma_playback.dma_size = 4; |
1093 | sec_dai->base = regs_base; | 1093 | sec_dai->base = regs_base; |
1094 | sec_dai->quirks = quirks; | 1094 | sec_dai->quirks = quirks; |
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index c86081992dfd..45f4a752d2a0 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c | |||
@@ -543,7 +543,7 @@ static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev) | |||
543 | ret = PTR_ERR(pcm->cclk); | 543 | ret = PTR_ERR(pcm->cclk); |
544 | goto err1; | 544 | goto err1; |
545 | } | 545 | } |
546 | clk_enable(pcm->cclk); | 546 | clk_prepare_enable(pcm->cclk); |
547 | 547 | ||
548 | /* record our pcm structure for later use in the callbacks */ | 548 | /* record our pcm structure for later use in the callbacks */ |
549 | dev_set_drvdata(&pdev->dev, pcm); | 549 | dev_set_drvdata(&pdev->dev, pcm); |
@@ -568,7 +568,7 @@ static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev) | |||
568 | ret = -ENOENT; | 568 | ret = -ENOENT; |
569 | goto err4; | 569 | goto err4; |
570 | } | 570 | } |
571 | clk_enable(pcm->pclk); | 571 | clk_prepare_enable(pcm->pclk); |
572 | 572 | ||
573 | s3c_pcm_stereo_in[pdev->id].dma_addr = mem_res->start | 573 | s3c_pcm_stereo_in[pdev->id].dma_addr = mem_res->start |
574 | + S3C_PCM_RXFIFO; | 574 | + S3C_PCM_RXFIFO; |
@@ -592,14 +592,14 @@ static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev) | |||
592 | return 0; | 592 | return 0; |
593 | 593 | ||
594 | err5: | 594 | err5: |
595 | clk_disable(pcm->pclk); | 595 | clk_disable_unprepare(pcm->pclk); |
596 | clk_put(pcm->pclk); | 596 | clk_put(pcm->pclk); |
597 | err4: | 597 | err4: |
598 | iounmap(pcm->regs); | 598 | iounmap(pcm->regs); |
599 | err3: | 599 | err3: |
600 | release_mem_region(mem_res->start, resource_size(mem_res)); | 600 | release_mem_region(mem_res->start, resource_size(mem_res)); |
601 | err2: | 601 | err2: |
602 | clk_disable(pcm->cclk); | 602 | clk_disable_unprepare(pcm->cclk); |
603 | clk_put(pcm->cclk); | 603 | clk_put(pcm->cclk); |
604 | err1: | 604 | err1: |
605 | return ret; | 605 | return ret; |
@@ -619,8 +619,8 @@ static __devexit int s3c_pcm_dev_remove(struct platform_device *pdev) | |||
619 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 619 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
620 | release_mem_region(mem_res->start, resource_size(mem_res)); | 620 | release_mem_region(mem_res->start, resource_size(mem_res)); |
621 | 621 | ||
622 | clk_disable(pcm->cclk); | 622 | clk_disable_unprepare(pcm->cclk); |
623 | clk_disable(pcm->pclk); | 623 | clk_disable_unprepare(pcm->pclk); |
624 | clk_put(pcm->pclk); | 624 | clk_put(pcm->pclk); |
625 | clk_put(pcm->cclk); | 625 | clk_put(pcm->cclk); |
626 | 626 | ||
diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c index bc24c7af02b2..5f3b06d36e9c 100644 --- a/sound/soc/samsung/spdif.c +++ b/sound/soc/samsung/spdif.c | |||
@@ -397,7 +397,7 @@ static __devinit int spdif_probe(struct platform_device *pdev) | |||
397 | ret = -ENOENT; | 397 | ret = -ENOENT; |
398 | goto err0; | 398 | goto err0; |
399 | } | 399 | } |
400 | clk_enable(spdif->pclk); | 400 | clk_prepare_enable(spdif->pclk); |
401 | 401 | ||
402 | spdif->sclk = clk_get(&pdev->dev, "sclk_spdif"); | 402 | spdif->sclk = clk_get(&pdev->dev, "sclk_spdif"); |
403 | if (IS_ERR(spdif->sclk)) { | 403 | if (IS_ERR(spdif->sclk)) { |
@@ -405,7 +405,7 @@ static __devinit int spdif_probe(struct platform_device *pdev) | |||
405 | ret = -ENOENT; | 405 | ret = -ENOENT; |
406 | goto err1; | 406 | goto err1; |
407 | } | 407 | } |
408 | clk_enable(spdif->sclk); | 408 | clk_prepare_enable(spdif->sclk); |
409 | 409 | ||
410 | /* Request S/PDIF Register's memory region */ | 410 | /* Request S/PDIF Register's memory region */ |
411 | if (!request_mem_region(mem_res->start, | 411 | if (!request_mem_region(mem_res->start, |
@@ -444,10 +444,10 @@ err4: | |||
444 | err3: | 444 | err3: |
445 | release_mem_region(mem_res->start, resource_size(mem_res)); | 445 | release_mem_region(mem_res->start, resource_size(mem_res)); |
446 | err2: | 446 | err2: |
447 | clk_disable(spdif->sclk); | 447 | clk_disable_unprepare(spdif->sclk); |
448 | clk_put(spdif->sclk); | 448 | clk_put(spdif->sclk); |
449 | err1: | 449 | err1: |
450 | clk_disable(spdif->pclk); | 450 | clk_disable_unprepare(spdif->pclk); |
451 | clk_put(spdif->pclk); | 451 | clk_put(spdif->pclk); |
452 | err0: | 452 | err0: |
453 | return ret; | 453 | return ret; |
@@ -466,9 +466,9 @@ static __devexit int spdif_remove(struct platform_device *pdev) | |||
466 | if (mem_res) | 466 | if (mem_res) |
467 | release_mem_region(mem_res->start, resource_size(mem_res)); | 467 | release_mem_region(mem_res->start, resource_size(mem_res)); |
468 | 468 | ||
469 | clk_disable(spdif->sclk); | 469 | clk_disable_unprepare(spdif->sclk); |
470 | clk_put(spdif->sclk); | 470 | clk_put(spdif->sclk); |
471 | clk_disable(spdif->pclk); | 471 | clk_disable_unprepare(spdif->pclk); |
472 | clk_put(spdif->pclk); | 472 | clk_put(spdif->pclk); |
473 | 473 | ||
474 | return 0; | 474 | return 0; |
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 9d7f30774a44..a606d0f93d1c 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/workqueue.h> | 23 | #include <linux/workqueue.h> |
24 | #include <sound/soc.h> | 24 | #include <sound/soc.h> |
25 | #include <sound/pcm_params.h> | ||
25 | #include <sound/sh_fsi.h> | 26 | #include <sound/sh_fsi.h> |
26 | 27 | ||
27 | /* PortA/PortB register */ | 28 | /* PortA/PortB register */ |
@@ -189,6 +190,14 @@ typedef int (*set_rate_func)(struct device *dev, int rate, int enable); | |||
189 | */ | 190 | */ |
190 | 191 | ||
191 | /* | 192 | /* |
193 | * FSI clock | ||
194 | * | ||
195 | * FSIxCLK [CPG] (ick) -------> | | ||
196 | * |-> FSI_DIV (div)-> FSI2 | ||
197 | * FSIxCK [external] (xck) ---> | | ||
198 | */ | ||
199 | |||
200 | /* | ||
192 | * struct | 201 | * struct |
193 | */ | 202 | */ |
194 | 203 | ||
@@ -228,6 +237,20 @@ struct fsi_stream { | |||
228 | dma_addr_t dma; | 237 | dma_addr_t dma; |
229 | }; | 238 | }; |
230 | 239 | ||
240 | struct fsi_clk { | ||
241 | /* see [FSI clock] */ | ||
242 | struct clk *own; | ||
243 | struct clk *xck; | ||
244 | struct clk *ick; | ||
245 | struct clk *div; | ||
246 | int (*set_rate)(struct device *dev, | ||
247 | struct fsi_priv *fsi, | ||
248 | unsigned long rate); | ||
249 | |||
250 | unsigned long rate; | ||
251 | unsigned int count; | ||
252 | }; | ||
253 | |||
231 | struct fsi_priv { | 254 | struct fsi_priv { |
232 | void __iomem *base; | 255 | void __iomem *base; |
233 | struct fsi_master *master; | 256 | struct fsi_master *master; |
@@ -236,11 +259,17 @@ struct fsi_priv { | |||
236 | struct fsi_stream playback; | 259 | struct fsi_stream playback; |
237 | struct fsi_stream capture; | 260 | struct fsi_stream capture; |
238 | 261 | ||
262 | struct fsi_clk clock; | ||
263 | |||
239 | u32 fmt; | 264 | u32 fmt; |
240 | 265 | ||
241 | int chan_num:16; | 266 | int chan_num:16; |
242 | int clk_master:1; | 267 | int clk_master:1; |
268 | int clk_cpg:1; | ||
243 | int spdif:1; | 269 | int spdif:1; |
270 | int enable_stream:1; | ||
271 | int bit_clk_inv:1; | ||
272 | int lr_clk_inv:1; | ||
244 | 273 | ||
245 | long rate; | 274 | long rate; |
246 | }; | 275 | }; |
@@ -370,6 +399,11 @@ static int fsi_is_spdif(struct fsi_priv *fsi) | |||
370 | return fsi->spdif; | 399 | return fsi->spdif; |
371 | } | 400 | } |
372 | 401 | ||
402 | static int fsi_is_enable_stream(struct fsi_priv *fsi) | ||
403 | { | ||
404 | return fsi->enable_stream; | ||
405 | } | ||
406 | |||
373 | static int fsi_is_play(struct snd_pcm_substream *substream) | 407 | static int fsi_is_play(struct snd_pcm_substream *substream) |
374 | { | 408 | { |
375 | return substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | 409 | return substream->stream == SNDRV_PCM_STREAM_PLAYBACK; |
@@ -717,14 +751,335 @@ static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable) | |||
717 | /* | 751 | /* |
718 | * clock function | 752 | * clock function |
719 | */ | 753 | */ |
754 | static int fsi_clk_init(struct device *dev, | ||
755 | struct fsi_priv *fsi, | ||
756 | int xck, | ||
757 | int ick, | ||
758 | int div, | ||
759 | int (*set_rate)(struct device *dev, | ||
760 | struct fsi_priv *fsi, | ||
761 | unsigned long rate)) | ||
762 | { | ||
763 | struct fsi_clk *clock = &fsi->clock; | ||
764 | int is_porta = fsi_is_port_a(fsi); | ||
765 | |||
766 | clock->xck = NULL; | ||
767 | clock->ick = NULL; | ||
768 | clock->div = NULL; | ||
769 | clock->rate = 0; | ||
770 | clock->count = 0; | ||
771 | clock->set_rate = set_rate; | ||
772 | |||
773 | clock->own = devm_clk_get(dev, NULL); | ||
774 | if (IS_ERR(clock->own)) | ||
775 | return -EINVAL; | ||
776 | |||
777 | /* external clock */ | ||
778 | if (xck) { | ||
779 | clock->xck = devm_clk_get(dev, is_porta ? "xcka" : "xckb"); | ||
780 | if (IS_ERR(clock->xck)) { | ||
781 | dev_err(dev, "can't get xck clock\n"); | ||
782 | return -EINVAL; | ||
783 | } | ||
784 | if (clock->xck == clock->own) { | ||
785 | dev_err(dev, "cpu doesn't support xck clock\n"); | ||
786 | return -EINVAL; | ||
787 | } | ||
788 | } | ||
789 | |||
790 | /* FSIACLK/FSIBCLK */ | ||
791 | if (ick) { | ||
792 | clock->ick = devm_clk_get(dev, is_porta ? "icka" : "ickb"); | ||
793 | if (IS_ERR(clock->ick)) { | ||
794 | dev_err(dev, "can't get ick clock\n"); | ||
795 | return -EINVAL; | ||
796 | } | ||
797 | if (clock->ick == clock->own) { | ||
798 | dev_err(dev, "cpu doesn't support ick clock\n"); | ||
799 | return -EINVAL; | ||
800 | } | ||
801 | } | ||
802 | |||
803 | /* FSI-DIV */ | ||
804 | if (div) { | ||
805 | clock->div = devm_clk_get(dev, is_porta ? "diva" : "divb"); | ||
806 | if (IS_ERR(clock->div)) { | ||
807 | dev_err(dev, "can't get div clock\n"); | ||
808 | return -EINVAL; | ||
809 | } | ||
810 | if (clock->div == clock->own) { | ||
811 | dev_err(dev, "cpu doens't support div clock\n"); | ||
812 | return -EINVAL; | ||
813 | } | ||
814 | } | ||
815 | |||
816 | return 0; | ||
817 | } | ||
818 | |||
819 | #define fsi_clk_invalid(fsi) fsi_clk_valid(fsi, 0) | ||
820 | static void fsi_clk_valid(struct fsi_priv *fsi, unsigned long rate) | ||
821 | { | ||
822 | fsi->clock.rate = rate; | ||
823 | } | ||
824 | |||
825 | static int fsi_clk_is_valid(struct fsi_priv *fsi) | ||
826 | { | ||
827 | return fsi->clock.set_rate && | ||
828 | fsi->clock.rate; | ||
829 | } | ||
830 | |||
831 | static int fsi_clk_enable(struct device *dev, | ||
832 | struct fsi_priv *fsi, | ||
833 | unsigned long rate) | ||
834 | { | ||
835 | struct fsi_clk *clock = &fsi->clock; | ||
836 | int ret = -EINVAL; | ||
837 | |||
838 | if (!fsi_clk_is_valid(fsi)) | ||
839 | return ret; | ||
840 | |||
841 | if (0 == clock->count) { | ||
842 | ret = clock->set_rate(dev, fsi, rate); | ||
843 | if (ret < 0) { | ||
844 | fsi_clk_invalid(fsi); | ||
845 | return ret; | ||
846 | } | ||
847 | |||
848 | if (clock->xck) | ||
849 | clk_enable(clock->xck); | ||
850 | if (clock->ick) | ||
851 | clk_enable(clock->ick); | ||
852 | if (clock->div) | ||
853 | clk_enable(clock->div); | ||
854 | |||
855 | clock->count++; | ||
856 | } | ||
857 | |||
858 | return ret; | ||
859 | } | ||
860 | |||
861 | static int fsi_clk_disable(struct device *dev, | ||
862 | struct fsi_priv *fsi) | ||
863 | { | ||
864 | struct fsi_clk *clock = &fsi->clock; | ||
865 | |||
866 | if (!fsi_clk_is_valid(fsi)) | ||
867 | return -EINVAL; | ||
868 | |||
869 | if (1 == clock->count--) { | ||
870 | if (clock->xck) | ||
871 | clk_disable(clock->xck); | ||
872 | if (clock->ick) | ||
873 | clk_disable(clock->ick); | ||
874 | if (clock->div) | ||
875 | clk_disable(clock->div); | ||
876 | } | ||
877 | |||
878 | return 0; | ||
879 | } | ||
880 | |||
881 | static int fsi_clk_set_ackbpf(struct device *dev, | ||
882 | struct fsi_priv *fsi, | ||
883 | int ackmd, int bpfmd) | ||
884 | { | ||
885 | u32 data = 0; | ||
886 | |||
887 | /* check ackmd/bpfmd relationship */ | ||
888 | if (bpfmd > ackmd) { | ||
889 | dev_err(dev, "unsupported rate (%d/%d)\n", ackmd, bpfmd); | ||
890 | return -EINVAL; | ||
891 | } | ||
892 | |||
893 | /* ACKMD */ | ||
894 | switch (ackmd) { | ||
895 | case 512: | ||
896 | data |= (0x0 << 12); | ||
897 | break; | ||
898 | case 256: | ||
899 | data |= (0x1 << 12); | ||
900 | break; | ||
901 | case 128: | ||
902 | data |= (0x2 << 12); | ||
903 | break; | ||
904 | case 64: | ||
905 | data |= (0x3 << 12); | ||
906 | break; | ||
907 | case 32: | ||
908 | data |= (0x4 << 12); | ||
909 | break; | ||
910 | default: | ||
911 | dev_err(dev, "unsupported ackmd (%d)\n", ackmd); | ||
912 | return -EINVAL; | ||
913 | } | ||
914 | |||
915 | /* BPFMD */ | ||
916 | switch (bpfmd) { | ||
917 | case 32: | ||
918 | data |= (0x0 << 8); | ||
919 | break; | ||
920 | case 64: | ||
921 | data |= (0x1 << 8); | ||
922 | break; | ||
923 | case 128: | ||
924 | data |= (0x2 << 8); | ||
925 | break; | ||
926 | case 256: | ||
927 | data |= (0x3 << 8); | ||
928 | break; | ||
929 | case 512: | ||
930 | data |= (0x4 << 8); | ||
931 | break; | ||
932 | case 16: | ||
933 | data |= (0x7 << 8); | ||
934 | break; | ||
935 | default: | ||
936 | dev_err(dev, "unsupported bpfmd (%d)\n", bpfmd); | ||
937 | return -EINVAL; | ||
938 | } | ||
939 | |||
940 | dev_dbg(dev, "ACKMD/BPFMD = %d/%d\n", ackmd, bpfmd); | ||
941 | |||
942 | fsi_reg_mask_set(fsi, CKG1, (ACKMD_MASK | BPFMD_MASK) , data); | ||
943 | udelay(10); | ||
944 | |||
945 | return 0; | ||
946 | } | ||
947 | |||
948 | static int fsi_clk_set_rate_external(struct device *dev, | ||
949 | struct fsi_priv *fsi, | ||
950 | unsigned long rate) | ||
951 | { | ||
952 | struct clk *xck = fsi->clock.xck; | ||
953 | struct clk *ick = fsi->clock.ick; | ||
954 | unsigned long xrate; | ||
955 | int ackmd, bpfmd; | ||
956 | int ret = 0; | ||
957 | |||
958 | /* check clock rate */ | ||
959 | xrate = clk_get_rate(xck); | ||
960 | if (xrate % rate) { | ||
961 | dev_err(dev, "unsupported clock rate\n"); | ||
962 | return -EINVAL; | ||
963 | } | ||
964 | |||
965 | clk_set_parent(ick, xck); | ||
966 | clk_set_rate(ick, xrate); | ||
967 | |||
968 | bpfmd = fsi->chan_num * 32; | ||
969 | ackmd = xrate / rate; | ||
970 | |||
971 | dev_dbg(dev, "external/rate = %ld/%ld\n", xrate, rate); | ||
972 | |||
973 | ret = fsi_clk_set_ackbpf(dev, fsi, ackmd, bpfmd); | ||
974 | if (ret < 0) | ||
975 | dev_err(dev, "%s failed", __func__); | ||
976 | |||
977 | return ret; | ||
978 | } | ||
979 | |||
980 | static int fsi_clk_set_rate_cpg(struct device *dev, | ||
981 | struct fsi_priv *fsi, | ||
982 | unsigned long rate) | ||
983 | { | ||
984 | struct clk *ick = fsi->clock.ick; | ||
985 | struct clk *div = fsi->clock.div; | ||
986 | unsigned long target = 0; /* 12288000 or 11289600 */ | ||
987 | unsigned long actual, cout; | ||
988 | unsigned long diff, min; | ||
989 | unsigned long best_cout, best_act; | ||
990 | int adj; | ||
991 | int ackmd, bpfmd; | ||
992 | int ret = -EINVAL; | ||
993 | |||
994 | if (!(12288000 % rate)) | ||
995 | target = 12288000; | ||
996 | if (!(11289600 % rate)) | ||
997 | target = 11289600; | ||
998 | if (!target) { | ||
999 | dev_err(dev, "unsupported rate\n"); | ||
1000 | return ret; | ||
1001 | } | ||
1002 | |||
1003 | bpfmd = fsi->chan_num * 32; | ||
1004 | ackmd = target / rate; | ||
1005 | ret = fsi_clk_set_ackbpf(dev, fsi, ackmd, bpfmd); | ||
1006 | if (ret < 0) { | ||
1007 | dev_err(dev, "%s failed", __func__); | ||
1008 | return ret; | ||
1009 | } | ||
1010 | |||
1011 | /* | ||
1012 | * The clock flow is | ||
1013 | * | ||
1014 | * [CPG] = cout => [FSI_DIV] = audio => [FSI] => [codec] | ||
1015 | * | ||
1016 | * But, it needs to find best match of CPG and FSI_DIV | ||
1017 | * combination, since it is difficult to generate correct | ||
1018 | * frequency of audio clock from ick clock only. | ||
1019 | * Because ick is created from its parent clock. | ||
1020 | * | ||
1021 | * target = rate x [512/256/128/64]fs | ||
1022 | * cout = round(target x adjustment) | ||
1023 | * actual = cout / adjustment (by FSI-DIV) ~= target | ||
1024 | * audio = actual | ||
1025 | */ | ||
1026 | min = ~0; | ||
1027 | best_cout = 0; | ||
1028 | best_act = 0; | ||
1029 | for (adj = 1; adj < 0xffff; adj++) { | ||
1030 | |||
1031 | cout = target * adj; | ||
1032 | if (cout > 100000000) /* max clock = 100MHz */ | ||
1033 | break; | ||
1034 | |||
1035 | /* cout/actual audio clock */ | ||
1036 | cout = clk_round_rate(ick, cout); | ||
1037 | actual = cout / adj; | ||
1038 | |||
1039 | /* find best frequency */ | ||
1040 | diff = abs(actual - target); | ||
1041 | if (diff < min) { | ||
1042 | min = diff; | ||
1043 | best_cout = cout; | ||
1044 | best_act = actual; | ||
1045 | } | ||
1046 | } | ||
1047 | |||
1048 | ret = clk_set_rate(ick, best_cout); | ||
1049 | if (ret < 0) { | ||
1050 | dev_err(dev, "ick clock failed\n"); | ||
1051 | return -EIO; | ||
1052 | } | ||
1053 | |||
1054 | ret = clk_set_rate(div, clk_round_rate(div, best_act)); | ||
1055 | if (ret < 0) { | ||
1056 | dev_err(dev, "div clock failed\n"); | ||
1057 | return -EIO; | ||
1058 | } | ||
1059 | |||
1060 | dev_dbg(dev, "ick/div = %ld/%ld\n", | ||
1061 | clk_get_rate(ick), clk_get_rate(div)); | ||
1062 | |||
1063 | return ret; | ||
1064 | } | ||
1065 | |||
720 | static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, | 1066 | static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, |
721 | long rate, int enable) | 1067 | long rate, int enable) |
722 | { | 1068 | { |
723 | set_rate_func set_rate = fsi_get_info_set_rate(fsi); | 1069 | set_rate_func set_rate = fsi_get_info_set_rate(fsi); |
724 | int ret; | 1070 | int ret; |
725 | 1071 | ||
726 | if (!set_rate) | 1072 | /* |
727 | return 0; | 1073 | * CAUTION |
1074 | * | ||
1075 | * set_rate will be deleted | ||
1076 | */ | ||
1077 | if (!set_rate) { | ||
1078 | if (enable) | ||
1079 | return fsi_clk_enable(dev, fsi, rate); | ||
1080 | else | ||
1081 | return fsi_clk_disable(dev, fsi); | ||
1082 | } | ||
728 | 1083 | ||
729 | ret = set_rate(dev, rate, enable); | 1084 | ret = set_rate(dev, rate, enable); |
730 | if (ret < 0) /* error */ | 1085 | if (ret < 0) /* error */ |
@@ -792,10 +1147,9 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, | |||
792 | */ | 1147 | */ |
793 | static void fsi_pio_push16(struct fsi_priv *fsi, u8 *_buf, int samples) | 1148 | static void fsi_pio_push16(struct fsi_priv *fsi, u8 *_buf, int samples) |
794 | { | 1149 | { |
795 | u32 enable_stream = fsi_get_info_flags(fsi) & SH_FSI_ENABLE_STREAM_MODE; | ||
796 | int i; | 1150 | int i; |
797 | 1151 | ||
798 | if (enable_stream) { | 1152 | if (fsi_is_enable_stream(fsi)) { |
799 | /* | 1153 | /* |
800 | * stream mode | 1154 | * stream mode |
801 | * see | 1155 | * see |
@@ -953,8 +1307,6 @@ static void fsi_pio_start_stop(struct fsi_priv *fsi, struct fsi_stream *io, | |||
953 | 1307 | ||
954 | static int fsi_pio_push_init(struct fsi_priv *fsi, struct fsi_stream *io) | 1308 | static int fsi_pio_push_init(struct fsi_priv *fsi, struct fsi_stream *io) |
955 | { | 1309 | { |
956 | u32 enable_stream = fsi_get_info_flags(fsi) & SH_FSI_ENABLE_STREAM_MODE; | ||
957 | |||
958 | /* | 1310 | /* |
959 | * we can use 16bit stream mode | 1311 | * we can use 16bit stream mode |
960 | * when "playback" and "16bit data" | 1312 | * when "playback" and "16bit data" |
@@ -962,7 +1314,7 @@ static int fsi_pio_push_init(struct fsi_priv *fsi, struct fsi_stream *io) | |||
962 | * see | 1314 | * see |
963 | * fsi_pio_push16() | 1315 | * fsi_pio_push16() |
964 | */ | 1316 | */ |
965 | if (enable_stream) | 1317 | if (fsi_is_enable_stream(fsi)) |
966 | io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) | | 1318 | io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) | |
967 | BUSOP_SET(16, PACKAGE_16BITBUS_STREAM); | 1319 | BUSOP_SET(16, PACKAGE_16BITBUS_STREAM); |
968 | else | 1320 | else |
@@ -1296,6 +1648,16 @@ static int fsi_hw_startup(struct fsi_priv *fsi, | |||
1296 | 1648 | ||
1297 | /* clock inversion (CKG2) */ | 1649 | /* clock inversion (CKG2) */ |
1298 | data = 0; | 1650 | data = 0; |
1651 | if (fsi->bit_clk_inv) | ||
1652 | data |= (1 << 0); | ||
1653 | if (fsi->lr_clk_inv) | ||
1654 | data |= (1 << 4); | ||
1655 | if (fsi_is_clk_master(fsi)) | ||
1656 | data <<= 8; | ||
1657 | /* FIXME | ||
1658 | * | ||
1659 | * SH_FSI_xxx_INV style will be removed | ||
1660 | */ | ||
1299 | if (SH_FSI_LRM_INV & flags) | 1661 | if (SH_FSI_LRM_INV & flags) |
1300 | data |= 1 << 12; | 1662 | data |= 1 << 12; |
1301 | if (SH_FSI_BRM_INV & flags) | 1663 | if (SH_FSI_BRM_INV & flags) |
@@ -1334,14 +1696,21 @@ static int fsi_hw_startup(struct fsi_priv *fsi, | |||
1334 | /* fifo init */ | 1696 | /* fifo init */ |
1335 | fsi_fifo_init(fsi, io, dev); | 1697 | fsi_fifo_init(fsi, io, dev); |
1336 | 1698 | ||
1699 | /* start master clock */ | ||
1700 | if (fsi_is_clk_master(fsi)) | ||
1701 | return fsi_set_master_clk(dev, fsi, fsi->rate, 1); | ||
1702 | |||
1337 | return 0; | 1703 | return 0; |
1338 | } | 1704 | } |
1339 | 1705 | ||
1340 | static void fsi_hw_shutdown(struct fsi_priv *fsi, | 1706 | static int fsi_hw_shutdown(struct fsi_priv *fsi, |
1341 | struct device *dev) | 1707 | struct device *dev) |
1342 | { | 1708 | { |
1709 | /* stop master clock */ | ||
1343 | if (fsi_is_clk_master(fsi)) | 1710 | if (fsi_is_clk_master(fsi)) |
1344 | fsi_set_master_clk(dev, fsi, fsi->rate, 0); | 1711 | return fsi_set_master_clk(dev, fsi, fsi->rate, 0); |
1712 | |||
1713 | return 0; | ||
1345 | } | 1714 | } |
1346 | 1715 | ||
1347 | static int fsi_dai_startup(struct snd_pcm_substream *substream, | 1716 | static int fsi_dai_startup(struct snd_pcm_substream *substream, |
@@ -1349,6 +1718,7 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, | |||
1349 | { | 1718 | { |
1350 | struct fsi_priv *fsi = fsi_get_priv(substream); | 1719 | struct fsi_priv *fsi = fsi_get_priv(substream); |
1351 | 1720 | ||
1721 | fsi_clk_invalid(fsi); | ||
1352 | fsi->rate = 0; | 1722 | fsi->rate = 0; |
1353 | 1723 | ||
1354 | return 0; | 1724 | return 0; |
@@ -1359,6 +1729,7 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream, | |||
1359 | { | 1729 | { |
1360 | struct fsi_priv *fsi = fsi_get_priv(substream); | 1730 | struct fsi_priv *fsi = fsi_get_priv(substream); |
1361 | 1731 | ||
1732 | fsi_clk_invalid(fsi); | ||
1362 | fsi->rate = 0; | 1733 | fsi->rate = 0; |
1363 | } | 1734 | } |
1364 | 1735 | ||
@@ -1372,13 +1743,16 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
1372 | switch (cmd) { | 1743 | switch (cmd) { |
1373 | case SNDRV_PCM_TRIGGER_START: | 1744 | case SNDRV_PCM_TRIGGER_START: |
1374 | fsi_stream_init(fsi, io, substream); | 1745 | fsi_stream_init(fsi, io, substream); |
1375 | fsi_hw_startup(fsi, io, dai->dev); | 1746 | if (!ret) |
1376 | ret = fsi_stream_transfer(io); | 1747 | ret = fsi_hw_startup(fsi, io, dai->dev); |
1377 | if (0 == ret) | 1748 | if (!ret) |
1749 | ret = fsi_stream_transfer(io); | ||
1750 | if (!ret) | ||
1378 | fsi_stream_start(fsi, io); | 1751 | fsi_stream_start(fsi, io); |
1379 | break; | 1752 | break; |
1380 | case SNDRV_PCM_TRIGGER_STOP: | 1753 | case SNDRV_PCM_TRIGGER_STOP: |
1381 | fsi_hw_shutdown(fsi, dai->dev); | 1754 | if (!ret) |
1755 | ret = fsi_hw_shutdown(fsi, dai->dev); | ||
1382 | fsi_stream_stop(fsi, io); | 1756 | fsi_stream_stop(fsi, io); |
1383 | fsi_stream_quit(fsi, io); | 1757 | fsi_stream_quit(fsi, io); |
1384 | break; | 1758 | break; |
@@ -1414,7 +1788,6 @@ static int fsi_set_fmt_spdif(struct fsi_priv *fsi) | |||
1414 | 1788 | ||
1415 | fsi->fmt = CR_DTMD_SPDIF_PCM | CR_PCM; | 1789 | fsi->fmt = CR_DTMD_SPDIF_PCM | CR_PCM; |
1416 | fsi->chan_num = 2; | 1790 | fsi->chan_num = 2; |
1417 | fsi->spdif = 1; | ||
1418 | 1791 | ||
1419 | return 0; | 1792 | return 0; |
1420 | } | 1793 | } |
@@ -1423,7 +1796,6 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
1423 | { | 1796 | { |
1424 | struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai); | 1797 | struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai); |
1425 | set_rate_func set_rate = fsi_get_info_set_rate(fsi); | 1798 | set_rate_func set_rate = fsi_get_info_set_rate(fsi); |
1426 | u32 flags = fsi_get_info_flags(fsi); | ||
1427 | int ret; | 1799 | int ret; |
1428 | 1800 | ||
1429 | /* set master/slave audio interface */ | 1801 | /* set master/slave audio interface */ |
@@ -1437,23 +1809,50 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
1437 | return -EINVAL; | 1809 | return -EINVAL; |
1438 | } | 1810 | } |
1439 | 1811 | ||
1440 | if (fsi_is_clk_master(fsi) && !set_rate) { | 1812 | /* set clock inversion */ |
1441 | dev_err(dai->dev, "platform doesn't have set_rate\n"); | 1813 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
1442 | return -EINVAL; | 1814 | case SND_SOC_DAIFMT_NB_IF: |
1443 | } | 1815 | fsi->bit_clk_inv = 0; |
1444 | 1816 | fsi->lr_clk_inv = 1; | |
1445 | /* set format */ | ||
1446 | switch (flags & SH_FSI_FMT_MASK) { | ||
1447 | case SH_FSI_FMT_DAI: | ||
1448 | ret = fsi_set_fmt_dai(fsi, fmt & SND_SOC_DAIFMT_FORMAT_MASK); | ||
1449 | break; | 1817 | break; |
1450 | case SH_FSI_FMT_SPDIF: | 1818 | case SND_SOC_DAIFMT_IB_NF: |
1451 | ret = fsi_set_fmt_spdif(fsi); | 1819 | fsi->bit_clk_inv = 1; |
1820 | fsi->lr_clk_inv = 0; | ||
1452 | break; | 1821 | break; |
1822 | case SND_SOC_DAIFMT_IB_IF: | ||
1823 | fsi->bit_clk_inv = 1; | ||
1824 | fsi->lr_clk_inv = 1; | ||
1825 | break; | ||
1826 | case SND_SOC_DAIFMT_NB_NF: | ||
1453 | default: | 1827 | default: |
1454 | ret = -EINVAL; | 1828 | fsi->bit_clk_inv = 0; |
1829 | fsi->lr_clk_inv = 0; | ||
1830 | break; | ||
1831 | } | ||
1832 | |||
1833 | if (fsi_is_clk_master(fsi)) { | ||
1834 | /* | ||
1835 | * CAUTION | ||
1836 | * | ||
1837 | * set_rate will be deleted | ||
1838 | */ | ||
1839 | if (set_rate) | ||
1840 | dev_warn(dai->dev, "set_rate will be removed soon\n"); | ||
1841 | |||
1842 | if (fsi->clk_cpg) | ||
1843 | fsi_clk_init(dai->dev, fsi, 0, 1, 1, | ||
1844 | fsi_clk_set_rate_cpg); | ||
1845 | else | ||
1846 | fsi_clk_init(dai->dev, fsi, 1, 1, 0, | ||
1847 | fsi_clk_set_rate_external); | ||
1455 | } | 1848 | } |
1456 | 1849 | ||
1850 | /* set format */ | ||
1851 | if (fsi_is_spdif(fsi)) | ||
1852 | ret = fsi_set_fmt_spdif(fsi); | ||
1853 | else | ||
1854 | ret = fsi_set_fmt_dai(fsi, fmt & SND_SOC_DAIFMT_FORMAT_MASK); | ||
1855 | |||
1457 | return ret; | 1856 | return ret; |
1458 | } | 1857 | } |
1459 | 1858 | ||
@@ -1462,19 +1861,13 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream, | |||
1462 | struct snd_soc_dai *dai) | 1861 | struct snd_soc_dai *dai) |
1463 | { | 1862 | { |
1464 | struct fsi_priv *fsi = fsi_get_priv(substream); | 1863 | struct fsi_priv *fsi = fsi_get_priv(substream); |
1465 | long rate = params_rate(params); | ||
1466 | int ret; | ||
1467 | 1864 | ||
1468 | if (!fsi_is_clk_master(fsi)) | 1865 | if (fsi_is_clk_master(fsi)) { |
1469 | return 0; | 1866 | fsi->rate = params_rate(params); |
1470 | 1867 | fsi_clk_valid(fsi, fsi->rate); | |
1471 | ret = fsi_set_master_clk(dai->dev, fsi, rate, 1); | 1868 | } |
1472 | if (ret < 0) | ||
1473 | return ret; | ||
1474 | |||
1475 | fsi->rate = rate; | ||
1476 | 1869 | ||
1477 | return ret; | 1870 | return 0; |
1478 | } | 1871 | } |
1479 | 1872 | ||
1480 | static const struct snd_soc_dai_ops fsi_dai_ops = { | 1873 | static const struct snd_soc_dai_ops fsi_dai_ops = { |
@@ -1498,7 +1891,7 @@ static struct snd_pcm_hardware fsi_pcm_hardware = { | |||
1498 | .rates = FSI_RATES, | 1891 | .rates = FSI_RATES, |
1499 | .rate_min = 8000, | 1892 | .rate_min = 8000, |
1500 | .rate_max = 192000, | 1893 | .rate_max = 192000, |
1501 | .channels_min = 1, | 1894 | .channels_min = 2, |
1502 | .channels_max = 2, | 1895 | .channels_max = 2, |
1503 | .buffer_bytes_max = 64 * 1024, | 1896 | .buffer_bytes_max = 64 * 1024, |
1504 | .period_bytes_min = 32, | 1897 | .period_bytes_min = 32, |
@@ -1586,14 +1979,14 @@ static struct snd_soc_dai_driver fsi_soc_dai[] = { | |||
1586 | .playback = { | 1979 | .playback = { |
1587 | .rates = FSI_RATES, | 1980 | .rates = FSI_RATES, |
1588 | .formats = FSI_FMTS, | 1981 | .formats = FSI_FMTS, |
1589 | .channels_min = 1, | 1982 | .channels_min = 2, |
1590 | .channels_max = 8, | 1983 | .channels_max = 2, |
1591 | }, | 1984 | }, |
1592 | .capture = { | 1985 | .capture = { |
1593 | .rates = FSI_RATES, | 1986 | .rates = FSI_RATES, |
1594 | .formats = FSI_FMTS, | 1987 | .formats = FSI_FMTS, |
1595 | .channels_min = 1, | 1988 | .channels_min = 2, |
1596 | .channels_max = 8, | 1989 | .channels_max = 2, |
1597 | }, | 1990 | }, |
1598 | .ops = &fsi_dai_ops, | 1991 | .ops = &fsi_dai_ops, |
1599 | }, | 1992 | }, |
@@ -1602,14 +1995,14 @@ static struct snd_soc_dai_driver fsi_soc_dai[] = { | |||
1602 | .playback = { | 1995 | .playback = { |
1603 | .rates = FSI_RATES, | 1996 | .rates = FSI_RATES, |
1604 | .formats = FSI_FMTS, | 1997 | .formats = FSI_FMTS, |
1605 | .channels_min = 1, | 1998 | .channels_min = 2, |
1606 | .channels_max = 8, | 1999 | .channels_max = 2, |
1607 | }, | 2000 | }, |
1608 | .capture = { | 2001 | .capture = { |
1609 | .rates = FSI_RATES, | 2002 | .rates = FSI_RATES, |
1610 | .formats = FSI_FMTS, | 2003 | .formats = FSI_FMTS, |
1611 | .channels_min = 1, | 2004 | .channels_min = 2, |
1612 | .channels_max = 8, | 2005 | .channels_max = 2, |
1613 | }, | 2006 | }, |
1614 | .ops = &fsi_dai_ops, | 2007 | .ops = &fsi_dai_ops, |
1615 | }, | 2008 | }, |
@@ -1624,15 +2017,29 @@ static struct snd_soc_platform_driver fsi_soc_platform = { | |||
1624 | /* | 2017 | /* |
1625 | * platform function | 2018 | * platform function |
1626 | */ | 2019 | */ |
1627 | static void fsi_handler_init(struct fsi_priv *fsi) | 2020 | static void fsi_port_info_init(struct fsi_priv *fsi, |
2021 | struct sh_fsi_port_info *info) | ||
2022 | { | ||
2023 | if (info->flags & SH_FSI_FMT_SPDIF) | ||
2024 | fsi->spdif = 1; | ||
2025 | |||
2026 | if (info->flags & SH_FSI_CLK_CPG) | ||
2027 | fsi->clk_cpg = 1; | ||
2028 | |||
2029 | if (info->flags & SH_FSI_ENABLE_STREAM_MODE) | ||
2030 | fsi->enable_stream = 1; | ||
2031 | } | ||
2032 | |||
2033 | static void fsi_handler_init(struct fsi_priv *fsi, | ||
2034 | struct sh_fsi_port_info *info) | ||
1628 | { | 2035 | { |
1629 | fsi->playback.handler = &fsi_pio_push_handler; /* default PIO */ | 2036 | fsi->playback.handler = &fsi_pio_push_handler; /* default PIO */ |
1630 | fsi->playback.priv = fsi; | 2037 | fsi->playback.priv = fsi; |
1631 | fsi->capture.handler = &fsi_pio_pop_handler; /* default PIO */ | 2038 | fsi->capture.handler = &fsi_pio_pop_handler; /* default PIO */ |
1632 | fsi->capture.priv = fsi; | 2039 | fsi->capture.priv = fsi; |
1633 | 2040 | ||
1634 | if (fsi->info->tx_id) { | 2041 | if (info->tx_id) { |
1635 | fsi->playback.slave.shdma_slave.slave_id = fsi->info->tx_id; | 2042 | fsi->playback.slave.shdma_slave.slave_id = info->tx_id; |
1636 | fsi->playback.handler = &fsi_dma_push_handler; | 2043 | fsi->playback.handler = &fsi_dma_push_handler; |
1637 | } | 2044 | } |
1638 | } | 2045 | } |
@@ -1642,10 +2049,16 @@ static int fsi_probe(struct platform_device *pdev) | |||
1642 | struct fsi_master *master; | 2049 | struct fsi_master *master; |
1643 | const struct platform_device_id *id_entry; | 2050 | const struct platform_device_id *id_entry; |
1644 | struct sh_fsi_platform_info *info = pdev->dev.platform_data; | 2051 | struct sh_fsi_platform_info *info = pdev->dev.platform_data; |
2052 | struct sh_fsi_port_info nul_info, *pinfo; | ||
2053 | struct fsi_priv *fsi; | ||
1645 | struct resource *res; | 2054 | struct resource *res; |
1646 | unsigned int irq; | 2055 | unsigned int irq; |
1647 | int ret; | 2056 | int ret; |
1648 | 2057 | ||
2058 | nul_info.flags = 0; | ||
2059 | nul_info.tx_id = 0; | ||
2060 | nul_info.rx_id = 0; | ||
2061 | |||
1649 | id_entry = pdev->id_entry; | 2062 | id_entry = pdev->id_entry; |
1650 | if (!id_entry) { | 2063 | if (!id_entry) { |
1651 | dev_err(&pdev->dev, "unknown fsi device\n"); | 2064 | dev_err(&pdev->dev, "unknown fsi device\n"); |
@@ -1678,22 +2091,28 @@ static int fsi_probe(struct platform_device *pdev) | |||
1678 | spin_lock_init(&master->lock); | 2091 | spin_lock_init(&master->lock); |
1679 | 2092 | ||
1680 | /* FSI A setting */ | 2093 | /* FSI A setting */ |
1681 | master->fsia.base = master->base; | 2094 | pinfo = (info) ? &info->port_a : &nul_info; |
1682 | master->fsia.master = master; | 2095 | fsi = &master->fsia; |
1683 | master->fsia.info = &info->port_a; | 2096 | fsi->base = master->base; |
1684 | fsi_handler_init(&master->fsia); | 2097 | fsi->master = master; |
1685 | ret = fsi_stream_probe(&master->fsia, &pdev->dev); | 2098 | fsi->info = pinfo; |
2099 | fsi_port_info_init(fsi, pinfo); | ||
2100 | fsi_handler_init(fsi, pinfo); | ||
2101 | ret = fsi_stream_probe(fsi, &pdev->dev); | ||
1686 | if (ret < 0) { | 2102 | if (ret < 0) { |
1687 | dev_err(&pdev->dev, "FSIA stream probe failed\n"); | 2103 | dev_err(&pdev->dev, "FSIA stream probe failed\n"); |
1688 | return ret; | 2104 | return ret; |
1689 | } | 2105 | } |
1690 | 2106 | ||
1691 | /* FSI B setting */ | 2107 | /* FSI B setting */ |
1692 | master->fsib.base = master->base + 0x40; | 2108 | pinfo = (info) ? &info->port_b : &nul_info; |
1693 | master->fsib.master = master; | 2109 | fsi = &master->fsib; |
1694 | master->fsib.info = &info->port_b; | 2110 | fsi->base = master->base + 0x40; |
1695 | fsi_handler_init(&master->fsib); | 2111 | fsi->master = master; |
1696 | ret = fsi_stream_probe(&master->fsib, &pdev->dev); | 2112 | fsi->info = pinfo; |
2113 | fsi_port_info_init(fsi, pinfo); | ||
2114 | fsi_handler_init(fsi, pinfo); | ||
2115 | ret = fsi_stream_probe(fsi, &pdev->dev); | ||
1697 | if (ret < 0) { | 2116 | if (ret < 0) { |
1698 | dev_err(&pdev->dev, "FSIB stream probe failed\n"); | 2117 | dev_err(&pdev->dev, "FSIB stream probe failed\n"); |
1699 | goto exit_fsia; | 2118 | goto exit_fsia; |
@@ -1702,7 +2121,7 @@ static int fsi_probe(struct platform_device *pdev) | |||
1702 | pm_runtime_enable(&pdev->dev); | 2121 | pm_runtime_enable(&pdev->dev); |
1703 | dev_set_drvdata(&pdev->dev, master); | 2122 | dev_set_drvdata(&pdev->dev, master); |
1704 | 2123 | ||
1705 | ret = request_irq(irq, &fsi_interrupt, 0, | 2124 | ret = devm_request_irq(&pdev->dev, irq, &fsi_interrupt, 0, |
1706 | id_entry->name, master); | 2125 | id_entry->name, master); |
1707 | if (ret) { | 2126 | if (ret) { |
1708 | dev_err(&pdev->dev, "irq request err\n"); | 2127 | dev_err(&pdev->dev, "irq request err\n"); |
@@ -1712,7 +2131,7 @@ static int fsi_probe(struct platform_device *pdev) | |||
1712 | ret = snd_soc_register_platform(&pdev->dev, &fsi_soc_platform); | 2131 | ret = snd_soc_register_platform(&pdev->dev, &fsi_soc_platform); |
1713 | if (ret < 0) { | 2132 | if (ret < 0) { |
1714 | dev_err(&pdev->dev, "cannot snd soc register\n"); | 2133 | dev_err(&pdev->dev, "cannot snd soc register\n"); |
1715 | goto exit_free_irq; | 2134 | goto exit_fsib; |
1716 | } | 2135 | } |
1717 | 2136 | ||
1718 | ret = snd_soc_register_dais(&pdev->dev, fsi_soc_dai, | 2137 | ret = snd_soc_register_dais(&pdev->dev, fsi_soc_dai, |
@@ -1726,8 +2145,6 @@ static int fsi_probe(struct platform_device *pdev) | |||
1726 | 2145 | ||
1727 | exit_snd_soc: | 2146 | exit_snd_soc: |
1728 | snd_soc_unregister_platform(&pdev->dev); | 2147 | snd_soc_unregister_platform(&pdev->dev); |
1729 | exit_free_irq: | ||
1730 | free_irq(irq, master); | ||
1731 | exit_fsib: | 2148 | exit_fsib: |
1732 | pm_runtime_disable(&pdev->dev); | 2149 | pm_runtime_disable(&pdev->dev); |
1733 | fsi_stream_remove(&master->fsib); | 2150 | fsi_stream_remove(&master->fsib); |
@@ -1743,7 +2160,6 @@ static int fsi_remove(struct platform_device *pdev) | |||
1743 | 2160 | ||
1744 | master = dev_get_drvdata(&pdev->dev); | 2161 | master = dev_get_drvdata(&pdev->dev); |
1745 | 2162 | ||
1746 | free_irq(master->irq, master); | ||
1747 | pm_runtime_disable(&pdev->dev); | 2163 | pm_runtime_disable(&pdev->dev); |
1748 | 2164 | ||
1749 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(fsi_soc_dai)); | 2165 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(fsi_soc_dai)); |
@@ -1774,10 +2190,6 @@ static void __fsi_resume(struct fsi_priv *fsi, | |||
1774 | return; | 2190 | return; |
1775 | 2191 | ||
1776 | fsi_hw_startup(fsi, io, dev); | 2192 | fsi_hw_startup(fsi, io, dev); |
1777 | |||
1778 | if (fsi_is_clk_master(fsi) && fsi->rate) | ||
1779 | fsi_set_master_clk(dev, fsi, fsi->rate, 1); | ||
1780 | |||
1781 | fsi_stream_start(fsi, io); | 2193 | fsi_stream_start(fsi, io); |
1782 | } | 2194 | } |
1783 | 2195 | ||
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 9d56f0218f41..e72f55428f0b 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c | |||
@@ -88,7 +88,7 @@ static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec) | |||
88 | ret = snd_soc_write(codec, i, val); | 88 | ret = snd_soc_write(codec, i, val); |
89 | if (ret) | 89 | if (ret) |
90 | return ret; | 90 | return ret; |
91 | dev_dbg(codec->dev, "Synced register %#x, value = %#x\n", | 91 | dev_dbg(codec->dev, "ASoC: Synced register %#x, value = %#x\n", |
92 | i, val); | 92 | i, val); |
93 | } | 93 | } |
94 | return 0; | 94 | return 0; |
@@ -156,7 +156,7 @@ int snd_soc_cache_init(struct snd_soc_codec *codec) | |||
156 | 156 | ||
157 | /* Fall back to flat compression */ | 157 | /* Fall back to flat compression */ |
158 | if (i == ARRAY_SIZE(cache_types)) { | 158 | if (i == ARRAY_SIZE(cache_types)) { |
159 | dev_warn(codec->dev, "Could not match compress type: %d\n", | 159 | dev_warn(codec->dev, "ASoC: Could not match compress type: %d\n", |
160 | codec->compress_type); | 160 | codec->compress_type); |
161 | i = 0; | 161 | i = 0; |
162 | } | 162 | } |
@@ -166,7 +166,7 @@ int snd_soc_cache_init(struct snd_soc_codec *codec) | |||
166 | 166 | ||
167 | if (codec->cache_ops->init) { | 167 | if (codec->cache_ops->init) { |
168 | if (codec->cache_ops->name) | 168 | if (codec->cache_ops->name) |
169 | dev_dbg(codec->dev, "Initializing %s cache for %s codec\n", | 169 | dev_dbg(codec->dev, "ASoC: Initializing %s cache for %s codec\n", |
170 | codec->cache_ops->name, codec->name); | 170 | codec->cache_ops->name, codec->name); |
171 | return codec->cache_ops->init(codec); | 171 | return codec->cache_ops->init(codec); |
172 | } | 172 | } |
@@ -181,7 +181,7 @@ int snd_soc_cache_exit(struct snd_soc_codec *codec) | |||
181 | { | 181 | { |
182 | if (codec->cache_ops && codec->cache_ops->exit) { | 182 | if (codec->cache_ops && codec->cache_ops->exit) { |
183 | if (codec->cache_ops->name) | 183 | if (codec->cache_ops->name) |
184 | dev_dbg(codec->dev, "Destroying %s cache for %s codec\n", | 184 | dev_dbg(codec->dev, "ASoC: Destroying %s cache for %s codec\n", |
185 | codec->cache_ops->name, codec->name); | 185 | codec->cache_ops->name, codec->name); |
186 | return codec->cache_ops->exit(codec); | 186 | return codec->cache_ops->exit(codec); |
187 | } | 187 | } |
@@ -265,7 +265,7 @@ int snd_soc_cache_sync(struct snd_soc_codec *codec) | |||
265 | name = "unknown"; | 265 | name = "unknown"; |
266 | 266 | ||
267 | if (codec->cache_ops->name) | 267 | if (codec->cache_ops->name) |
268 | dev_dbg(codec->dev, "Syncing %s cache for %s codec\n", | 268 | dev_dbg(codec->dev, "ASoC: Syncing %s cache for %s codec\n", |
269 | codec->cache_ops->name, codec->name); | 269 | codec->cache_ops->name, codec->name); |
270 | trace_snd_soc_cache_sync(codec, name, "start"); | 270 | trace_snd_soc_cache_sync(codec, name, "start"); |
271 | ret = codec->cache_ops->sync(codec); | 271 | ret = codec->cache_ops->sync(codec); |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 10d21be383f6..9c768bcb98a6 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -271,7 +271,8 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec) | |||
271 | codec->debugfs_codec_root = debugfs_create_dir(codec->name, | 271 | codec->debugfs_codec_root = debugfs_create_dir(codec->name, |
272 | debugfs_card_root); | 272 | debugfs_card_root); |
273 | if (!codec->debugfs_codec_root) { | 273 | if (!codec->debugfs_codec_root) { |
274 | dev_warn(codec->dev, "Failed to create codec debugfs directory\n"); | 274 | dev_warn(codec->dev, "ASoC: Failed to create codec debugfs" |
275 | " directory\n"); | ||
275 | return; | 276 | return; |
276 | } | 277 | } |
277 | 278 | ||
@@ -284,7 +285,8 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec) | |||
284 | codec->debugfs_codec_root, | 285 | codec->debugfs_codec_root, |
285 | codec, &codec_reg_fops); | 286 | codec, &codec_reg_fops); |
286 | if (!codec->debugfs_reg) | 287 | if (!codec->debugfs_reg) |
287 | dev_warn(codec->dev, "Failed to create codec register debugfs file\n"); | 288 | dev_warn(codec->dev, "ASoC: Failed to create codec register" |
289 | " debugfs file\n"); | ||
288 | 290 | ||
289 | snd_soc_dapm_debugfs_init(&codec->dapm, codec->debugfs_codec_root); | 291 | snd_soc_dapm_debugfs_init(&codec->dapm, codec->debugfs_codec_root); |
290 | } | 292 | } |
@@ -302,7 +304,7 @@ static void soc_init_platform_debugfs(struct snd_soc_platform *platform) | |||
302 | debugfs_card_root); | 304 | debugfs_card_root); |
303 | if (!platform->debugfs_platform_root) { | 305 | if (!platform->debugfs_platform_root) { |
304 | dev_warn(platform->dev, | 306 | dev_warn(platform->dev, |
305 | "Failed to create platform debugfs directory\n"); | 307 | "ASoC: Failed to create platform debugfs directory\n"); |
306 | return; | 308 | return; |
307 | } | 309 | } |
308 | 310 | ||
@@ -430,7 +432,7 @@ static void soc_init_card_debugfs(struct snd_soc_card *card) | |||
430 | &card->pop_time); | 432 | &card->pop_time); |
431 | if (!card->debugfs_pop_time) | 433 | if (!card->debugfs_pop_time) |
432 | dev_warn(card->dev, | 434 | dev_warn(card->dev, |
433 | "Failed to create pop time debugfs file\n"); | 435 | "ASoC: Failed to create pop time debugfs file\n"); |
434 | } | 436 | } |
435 | 437 | ||
436 | static void soc_cleanup_card_debugfs(struct snd_soc_card *card) | 438 | static void soc_cleanup_card_debugfs(struct snd_soc_card *card) |
@@ -475,7 +477,7 @@ struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card, | |||
475 | !strcmp(card->rtd[i].dai_link->name, dai_link)) | 477 | !strcmp(card->rtd[i].dai_link->name, dai_link)) |
476 | return card->rtd[i].pcm->streams[stream].substream; | 478 | return card->rtd[i].pcm->streams[stream].substream; |
477 | } | 479 | } |
478 | dev_dbg(card->dev, "failed to find dai link %s\n", dai_link); | 480 | dev_dbg(card->dev, "ASoC: failed to find dai link %s\n", dai_link); |
479 | return NULL; | 481 | return NULL; |
480 | } | 482 | } |
481 | EXPORT_SYMBOL_GPL(snd_soc_get_dai_substream); | 483 | EXPORT_SYMBOL_GPL(snd_soc_get_dai_substream); |
@@ -489,7 +491,7 @@ struct snd_soc_pcm_runtime *snd_soc_get_pcm_runtime(struct snd_soc_card *card, | |||
489 | if (!strcmp(card->rtd[i].dai_link->name, dai_link)) | 491 | if (!strcmp(card->rtd[i].dai_link->name, dai_link)) |
490 | return &card->rtd[i]; | 492 | return &card->rtd[i]; |
491 | } | 493 | } |
492 | dev_dbg(card->dev, "failed to find rtd %s\n", dai_link); | 494 | dev_dbg(card->dev, "ASoC: failed to find rtd %s\n", dai_link); |
493 | return NULL; | 495 | return NULL; |
494 | } | 496 | } |
495 | EXPORT_SYMBOL_GPL(snd_soc_get_pcm_runtime); | 497 | EXPORT_SYMBOL_GPL(snd_soc_get_pcm_runtime); |
@@ -519,7 +521,7 @@ static int soc_ac97_dev_register(struct snd_soc_codec *codec) | |||
519 | codec->card->snd_card->number, 0, codec->name); | 521 | codec->card->snd_card->number, 0, codec->name); |
520 | err = device_register(&codec->ac97->dev); | 522 | err = device_register(&codec->ac97->dev); |
521 | if (err < 0) { | 523 | if (err < 0) { |
522 | snd_printk(KERN_ERR "Can't register ac97 bus\n"); | 524 | dev_err(codec->dev, "ASoC: Can't register ac97 bus\n"); |
523 | codec->ac97->dev.bus = NULL; | 525 | codec->ac97->dev.bus = NULL; |
524 | return err; | 526 | return err; |
525 | } | 527 | } |
@@ -628,7 +630,8 @@ int snd_soc_suspend(struct device *dev) | |||
628 | */ | 630 | */ |
629 | if (codec->dapm.idle_bias_off) { | 631 | if (codec->dapm.idle_bias_off) { |
630 | dev_dbg(codec->dev, | 632 | dev_dbg(codec->dev, |
631 | "idle_bias_off CODEC on over suspend\n"); | 633 | "ASoC: idle_bias_off CODEC on" |
634 | " over suspend\n"); | ||
632 | break; | 635 | break; |
633 | } | 636 | } |
634 | case SND_SOC_BIAS_OFF: | 637 | case SND_SOC_BIAS_OFF: |
@@ -639,7 +642,8 @@ int snd_soc_suspend(struct device *dev) | |||
639 | regcache_mark_dirty(codec->control_data); | 642 | regcache_mark_dirty(codec->control_data); |
640 | break; | 643 | break; |
641 | default: | 644 | default: |
642 | dev_dbg(codec->dev, "CODEC is on over suspend\n"); | 645 | dev_dbg(codec->dev, "ASoC: CODEC is on" |
646 | " over suspend\n"); | ||
643 | break; | 647 | break; |
644 | } | 648 | } |
645 | } | 649 | } |
@@ -676,7 +680,7 @@ static void soc_resume_deferred(struct work_struct *work) | |||
676 | * so userspace apps are blocked from touching us | 680 | * so userspace apps are blocked from touching us |
677 | */ | 681 | */ |
678 | 682 | ||
679 | dev_dbg(card->dev, "starting resume work\n"); | 683 | dev_dbg(card->dev, "ASoC: starting resume work\n"); |
680 | 684 | ||
681 | /* Bring us up into D2 so that DAPM starts enabling things */ | 685 | /* Bring us up into D2 so that DAPM starts enabling things */ |
682 | snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D2); | 686 | snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D2); |
@@ -708,7 +712,8 @@ static void soc_resume_deferred(struct work_struct *work) | |||
708 | codec->suspended = 0; | 712 | codec->suspended = 0; |
709 | break; | 713 | break; |
710 | default: | 714 | default: |
711 | dev_dbg(codec->dev, "CODEC was on over suspend\n"); | 715 | dev_dbg(codec->dev, "ASoC: CODEC was on over" |
716 | " suspend\n"); | ||
712 | break; | 717 | break; |
713 | } | 718 | } |
714 | } | 719 | } |
@@ -758,7 +763,7 @@ static void soc_resume_deferred(struct work_struct *work) | |||
758 | if (card->resume_post) | 763 | if (card->resume_post) |
759 | card->resume_post(card); | 764 | card->resume_post(card); |
760 | 765 | ||
761 | dev_dbg(card->dev, "resume work completed\n"); | 766 | dev_dbg(card->dev, "ASoC: resume work completed\n"); |
762 | 767 | ||
763 | /* userspace can access us now we are back as we were before */ | 768 | /* userspace can access us now we are back as we were before */ |
764 | snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D0); | 769 | snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D0); |
@@ -790,12 +795,12 @@ int snd_soc_resume(struct device *dev) | |||
790 | ac97_control |= cpu_dai->driver->ac97_control; | 795 | ac97_control |= cpu_dai->driver->ac97_control; |
791 | } | 796 | } |
792 | if (ac97_control) { | 797 | if (ac97_control) { |
793 | dev_dbg(dev, "Resuming AC97 immediately\n"); | 798 | dev_dbg(dev, "ASoC: Resuming AC97 immediately\n"); |
794 | soc_resume_deferred(&card->deferred_resume_work); | 799 | soc_resume_deferred(&card->deferred_resume_work); |
795 | } else { | 800 | } else { |
796 | dev_dbg(dev, "Scheduling resume work\n"); | 801 | dev_dbg(dev, "ASoC: Scheduling resume work\n"); |
797 | if (!schedule_work(&card->deferred_resume_work)) | 802 | if (!schedule_work(&card->deferred_resume_work)) |
798 | dev_err(dev, "resume work item may be lost\n"); | 803 | dev_err(dev, "ASoC: resume work item may be lost\n"); |
799 | } | 804 | } |
800 | 805 | ||
801 | return 0; | 806 | return 0; |
@@ -818,7 +823,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) | |||
818 | struct snd_soc_dai *codec_dai, *cpu_dai; | 823 | struct snd_soc_dai *codec_dai, *cpu_dai; |
819 | const char *platform_name; | 824 | const char *platform_name; |
820 | 825 | ||
821 | dev_dbg(card->dev, "binding %s at idx %d\n", dai_link->name, num); | 826 | dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num); |
822 | 827 | ||
823 | /* Find CPU DAI from registered DAIs*/ | 828 | /* Find CPU DAI from registered DAIs*/ |
824 | list_for_each_entry(cpu_dai, &dai_list, list) { | 829 | list_for_each_entry(cpu_dai, &dai_list, list) { |
@@ -836,7 +841,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) | |||
836 | } | 841 | } |
837 | 842 | ||
838 | if (!rtd->cpu_dai) { | 843 | if (!rtd->cpu_dai) { |
839 | dev_err(card->dev, "CPU DAI %s not registered\n", | 844 | dev_err(card->dev, "ASoC: CPU DAI %s not registered\n", |
840 | dai_link->cpu_dai_name); | 845 | dai_link->cpu_dai_name); |
841 | return -EPROBE_DEFER; | 846 | return -EPROBE_DEFER; |
842 | } | 847 | } |
@@ -867,14 +872,14 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) | |||
867 | } | 872 | } |
868 | 873 | ||
869 | if (!rtd->codec_dai) { | 874 | if (!rtd->codec_dai) { |
870 | dev_err(card->dev, "CODEC DAI %s not registered\n", | 875 | dev_err(card->dev, "ASoC: CODEC DAI %s not registered\n", |
871 | dai_link->codec_dai_name); | 876 | dai_link->codec_dai_name); |
872 | return -EPROBE_DEFER; | 877 | return -EPROBE_DEFER; |
873 | } | 878 | } |
874 | } | 879 | } |
875 | 880 | ||
876 | if (!rtd->codec) { | 881 | if (!rtd->codec) { |
877 | dev_err(card->dev, "CODEC %s not registered\n", | 882 | dev_err(card->dev, "ASoC: CODEC %s not registered\n", |
878 | dai_link->codec_name); | 883 | dai_link->codec_name); |
879 | return -EPROBE_DEFER; | 884 | return -EPROBE_DEFER; |
880 | } | 885 | } |
@@ -898,7 +903,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) | |||
898 | rtd->platform = platform; | 903 | rtd->platform = platform; |
899 | } | 904 | } |
900 | if (!rtd->platform) { | 905 | if (!rtd->platform) { |
901 | dev_err(card->dev, "platform %s not registered\n", | 906 | dev_err(card->dev, "ASoC: platform %s not registered\n", |
902 | dai_link->platform_name); | 907 | dai_link->platform_name); |
903 | return -EPROBE_DEFER; | 908 | return -EPROBE_DEFER; |
904 | } | 909 | } |
@@ -915,8 +920,8 @@ static int soc_remove_platform(struct snd_soc_platform *platform) | |||
915 | if (platform->driver->remove) { | 920 | if (platform->driver->remove) { |
916 | ret = platform->driver->remove(platform); | 921 | ret = platform->driver->remove(platform); |
917 | if (ret < 0) | 922 | if (ret < 0) |
918 | pr_err("asoc: failed to remove %s: %d\n", | 923 | dev_err(platform->dev, "ASoC: failed to remove %d\n", |
919 | platform->name, ret); | 924 | ret); |
920 | } | 925 | } |
921 | 926 | ||
922 | /* Make sure all DAPM widgets are freed */ | 927 | /* Make sure all DAPM widgets are freed */ |
@@ -937,9 +942,7 @@ static void soc_remove_codec(struct snd_soc_codec *codec) | |||
937 | if (codec->driver->remove) { | 942 | if (codec->driver->remove) { |
938 | err = codec->driver->remove(codec); | 943 | err = codec->driver->remove(codec); |
939 | if (err < 0) | 944 | if (err < 0) |
940 | dev_err(codec->dev, | 945 | dev_err(codec->dev, "ASoC: failed to remove %d\n", err); |
941 | "asoc: failed to remove %s: %d\n", | ||
942 | codec->name, err); | ||
943 | } | 946 | } |
944 | 947 | ||
945 | /* Make sure all DAPM widgets are freed */ | 948 | /* Make sure all DAPM widgets are freed */ |
@@ -971,8 +974,9 @@ static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order) | |||
971 | if (codec_dai->driver->remove) { | 974 | if (codec_dai->driver->remove) { |
972 | err = codec_dai->driver->remove(codec_dai); | 975 | err = codec_dai->driver->remove(codec_dai); |
973 | if (err < 0) | 976 | if (err < 0) |
974 | pr_err("asoc: failed to remove %s: %d\n", | 977 | dev_err(codec_dai->dev, |
975 | codec_dai->name, err); | 978 | "ASoC: failed to remove %s: %d\n", |
979 | codec_dai->name, err); | ||
976 | } | 980 | } |
977 | codec_dai->probed = 0; | 981 | codec_dai->probed = 0; |
978 | list_del(&codec_dai->card_list); | 982 | list_del(&codec_dai->card_list); |
@@ -984,8 +988,9 @@ static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order) | |||
984 | if (cpu_dai->driver->remove) { | 988 | if (cpu_dai->driver->remove) { |
985 | err = cpu_dai->driver->remove(cpu_dai); | 989 | err = cpu_dai->driver->remove(cpu_dai); |
986 | if (err < 0) | 990 | if (err < 0) |
987 | pr_err("asoc: failed to remove %s: %d\n", | 991 | dev_err(cpu_dai->dev, |
988 | cpu_dai->name, err); | 992 | "ASoC: failed to remove %s: %d\n", |
993 | cpu_dai->name, err); | ||
989 | } | 994 | } |
990 | cpu_dai->probed = 0; | 995 | cpu_dai->probed = 0; |
991 | list_del(&cpu_dai->card_list); | 996 | list_del(&cpu_dai->card_list); |
@@ -1099,8 +1104,7 @@ static int soc_probe_codec(struct snd_soc_card *card, | |||
1099 | ret = driver->probe(codec); | 1104 | ret = driver->probe(codec); |
1100 | if (ret < 0) { | 1105 | if (ret < 0) { |
1101 | dev_err(codec->dev, | 1106 | dev_err(codec->dev, |
1102 | "asoc: failed to probe CODEC %s: %d\n", | 1107 | "ASoC: failed to probe CODEC %d\n", ret); |
1103 | codec->name, ret); | ||
1104 | goto err_probe; | 1108 | goto err_probe; |
1105 | } | 1109 | } |
1106 | } | 1110 | } |
@@ -1163,8 +1167,7 @@ static int soc_probe_platform(struct snd_soc_card *card, | |||
1163 | ret = driver->probe(platform); | 1167 | ret = driver->probe(platform); |
1164 | if (ret < 0) { | 1168 | if (ret < 0) { |
1165 | dev_err(platform->dev, | 1169 | dev_err(platform->dev, |
1166 | "asoc: failed to probe platform %s: %d\n", | 1170 | "ASoC: failed to probe platform %d\n", ret); |
1167 | platform->name, ret); | ||
1168 | goto err_probe; | 1171 | goto err_probe; |
1169 | } | 1172 | } |
1170 | } | 1173 | } |
@@ -1229,7 +1232,7 @@ static int soc_post_component_init(struct snd_soc_card *card, | |||
1229 | else if (dailess && aux_dev->init) | 1232 | else if (dailess && aux_dev->init) |
1230 | ret = aux_dev->init(&codec->dapm); | 1233 | ret = aux_dev->init(&codec->dapm); |
1231 | if (ret < 0) { | 1234 | if (ret < 0) { |
1232 | dev_err(card->dev, "asoc: failed to init %s: %d\n", name, ret); | 1235 | dev_err(card->dev, "ASoC: failed to init %s: %d\n", name, ret); |
1233 | return ret; | 1236 | return ret; |
1234 | } | 1237 | } |
1235 | codec->name_prefix = temp; | 1238 | codec->name_prefix = temp; |
@@ -1253,7 +1256,7 @@ static int soc_post_component_init(struct snd_soc_card *card, | |||
1253 | ret = device_add(rtd->dev); | 1256 | ret = device_add(rtd->dev); |
1254 | if (ret < 0) { | 1257 | if (ret < 0) { |
1255 | dev_err(card->dev, | 1258 | dev_err(card->dev, |
1256 | "asoc: failed to register runtime device: %d\n", ret); | 1259 | "ASoC: failed to register runtime device: %d\n", ret); |
1257 | return ret; | 1260 | return ret; |
1258 | } | 1261 | } |
1259 | rtd->dev_registered = 1; | 1262 | rtd->dev_registered = 1; |
@@ -1262,14 +1265,13 @@ static int soc_post_component_init(struct snd_soc_card *card, | |||
1262 | ret = snd_soc_dapm_sys_add(rtd->dev); | 1265 | ret = snd_soc_dapm_sys_add(rtd->dev); |
1263 | if (ret < 0) | 1266 | if (ret < 0) |
1264 | dev_err(codec->dev, | 1267 | dev_err(codec->dev, |
1265 | "asoc: failed to add codec dapm sysfs entries: %d\n", | 1268 | "ASoC: failed to add codec dapm sysfs entries: %d\n", ret); |
1266 | ret); | ||
1267 | 1269 | ||
1268 | /* add codec sysfs entries */ | 1270 | /* add codec sysfs entries */ |
1269 | ret = device_create_file(rtd->dev, &dev_attr_codec_reg); | 1271 | ret = device_create_file(rtd->dev, &dev_attr_codec_reg); |
1270 | if (ret < 0) | 1272 | if (ret < 0) |
1271 | dev_err(codec->dev, | 1273 | dev_err(codec->dev, |
1272 | "asoc: failed to add codec sysfs files: %d\n", ret); | 1274 | "ASoC: failed to add codec sysfs files: %d\n", ret); |
1273 | 1275 | ||
1274 | #ifdef CONFIG_DEBUG_FS | 1276 | #ifdef CONFIG_DEBUG_FS |
1275 | /* add DPCM sysfs entries */ | 1277 | /* add DPCM sysfs entries */ |
@@ -1278,7 +1280,7 @@ static int soc_post_component_init(struct snd_soc_card *card, | |||
1278 | 1280 | ||
1279 | ret = soc_dpcm_debugfs_add(rtd); | 1281 | ret = soc_dpcm_debugfs_add(rtd); |
1280 | if (ret < 0) | 1282 | if (ret < 0) |
1281 | dev_err(rtd->dev, "asoc: failed to add dpcm sysfs entries: %d\n", ret); | 1283 | dev_err(rtd->dev, "ASoC: failed to add dpcm sysfs entries: %d\n", ret); |
1282 | 1284 | ||
1283 | out: | 1285 | out: |
1284 | #endif | 1286 | #endif |
@@ -1333,7 +1335,7 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) | |||
1333 | struct snd_soc_dapm_widget *play_w, *capture_w; | 1335 | struct snd_soc_dapm_widget *play_w, *capture_w; |
1334 | int ret; | 1336 | int ret; |
1335 | 1337 | ||
1336 | dev_dbg(card->dev, "probe %s dai link %d late %d\n", | 1338 | dev_dbg(card->dev, "ASoC: probe %s dai link %d late %d\n", |
1337 | card->name, num, order); | 1339 | card->name, num, order); |
1338 | 1340 | ||
1339 | /* config components */ | 1341 | /* config components */ |
@@ -1359,8 +1361,9 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) | |||
1359 | if (cpu_dai->driver->probe) { | 1361 | if (cpu_dai->driver->probe) { |
1360 | ret = cpu_dai->driver->probe(cpu_dai); | 1362 | ret = cpu_dai->driver->probe(cpu_dai); |
1361 | if (ret < 0) { | 1363 | if (ret < 0) { |
1362 | pr_err("asoc: failed to probe CPU DAI %s: %d\n", | 1364 | dev_err(cpu_dai->dev, |
1363 | cpu_dai->name, ret); | 1365 | "ASoC: failed to probe CPU DAI %s: %d\n", |
1366 | cpu_dai->name, ret); | ||
1364 | module_put(cpu_dai->dev->driver->owner); | 1367 | module_put(cpu_dai->dev->driver->owner); |
1365 | return ret; | 1368 | return ret; |
1366 | } | 1369 | } |
@@ -1375,8 +1378,9 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) | |||
1375 | if (codec_dai->driver->probe) { | 1378 | if (codec_dai->driver->probe) { |
1376 | ret = codec_dai->driver->probe(codec_dai); | 1379 | ret = codec_dai->driver->probe(codec_dai); |
1377 | if (ret < 0) { | 1380 | if (ret < 0) { |
1378 | pr_err("asoc: failed to probe CODEC DAI %s: %d\n", | 1381 | dev_err(codec_dai->dev, |
1379 | codec_dai->name, ret); | 1382 | "ASoC: failed to probe CODEC DAI %s: %d\n", |
1383 | codec_dai->name, ret); | ||
1380 | return ret; | 1384 | return ret; |
1381 | } | 1385 | } |
1382 | } | 1386 | } |
@@ -1396,13 +1400,14 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) | |||
1396 | 1400 | ||
1397 | ret = device_create_file(rtd->dev, &dev_attr_pmdown_time); | 1401 | ret = device_create_file(rtd->dev, &dev_attr_pmdown_time); |
1398 | if (ret < 0) | 1402 | if (ret < 0) |
1399 | pr_warn("asoc: failed to add pmdown_time sysfs:%d\n", ret); | 1403 | dev_warn(rtd->dev, "ASoC: failed to add pmdown_time sysfs: %d\n", |
1404 | ret); | ||
1400 | 1405 | ||
1401 | if (cpu_dai->driver->compress_dai) { | 1406 | if (cpu_dai->driver->compress_dai) { |
1402 | /*create compress_device"*/ | 1407 | /*create compress_device"*/ |
1403 | ret = soc_new_compress(rtd, num); | 1408 | ret = soc_new_compress(rtd, num); |
1404 | if (ret < 0) { | 1409 | if (ret < 0) { |
1405 | pr_err("asoc: can't create compress %s\n", | 1410 | dev_err(card->dev, "ASoC: can't create compress %s\n", |
1406 | dai_link->stream_name); | 1411 | dai_link->stream_name); |
1407 | return ret; | 1412 | return ret; |
1408 | } | 1413 | } |
@@ -1412,7 +1417,7 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) | |||
1412 | /* create the pcm */ | 1417 | /* create the pcm */ |
1413 | ret = soc_new_pcm(rtd, num); | 1418 | ret = soc_new_pcm(rtd, num); |
1414 | if (ret < 0) { | 1419 | if (ret < 0) { |
1415 | pr_err("asoc: can't create pcm %s :%d\n", | 1420 | dev_err(card->dev, "ASoC: can't create pcm %s :%d\n", |
1416 | dai_link->stream_name, ret); | 1421 | dai_link->stream_name, ret); |
1417 | return ret; | 1422 | return ret; |
1418 | } | 1423 | } |
@@ -1424,7 +1429,7 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) | |||
1424 | ret = snd_soc_dapm_new_pcm(card, dai_link->params, | 1429 | ret = snd_soc_dapm_new_pcm(card, dai_link->params, |
1425 | capture_w, play_w); | 1430 | capture_w, play_w); |
1426 | if (ret != 0) { | 1431 | if (ret != 0) { |
1427 | dev_err(card->dev, "Can't link %s to %s: %d\n", | 1432 | dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", |
1428 | play_w->name, capture_w->name, ret); | 1433 | play_w->name, capture_w->name, ret); |
1429 | return ret; | 1434 | return ret; |
1430 | } | 1435 | } |
@@ -1436,7 +1441,7 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) | |||
1436 | ret = snd_soc_dapm_new_pcm(card, dai_link->params, | 1441 | ret = snd_soc_dapm_new_pcm(card, dai_link->params, |
1437 | capture_w, play_w); | 1442 | capture_w, play_w); |
1438 | if (ret != 0) { | 1443 | if (ret != 0) { |
1439 | dev_err(card->dev, "Can't link %s to %s: %d\n", | 1444 | dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", |
1440 | play_w->name, capture_w->name, ret); | 1445 | play_w->name, capture_w->name, ret); |
1441 | return ret; | 1446 | return ret; |
1442 | } | 1447 | } |
@@ -1473,7 +1478,8 @@ static int soc_register_ac97_dai_link(struct snd_soc_pcm_runtime *rtd) | |||
1473 | 1478 | ||
1474 | ret = soc_ac97_dev_register(rtd->codec); | 1479 | ret = soc_ac97_dev_register(rtd->codec); |
1475 | if (ret < 0) { | 1480 | if (ret < 0) { |
1476 | pr_err("asoc: AC97 device register failed:%d\n", ret); | 1481 | dev_err(rtd->codec->dev, |
1482 | "ASoC: AC97 device register failed: %d\n", ret); | ||
1477 | return ret; | 1483 | return ret; |
1478 | } | 1484 | } |
1479 | 1485 | ||
@@ -1502,7 +1508,7 @@ static int soc_check_aux_dev(struct snd_soc_card *card, int num) | |||
1502 | return 0; | 1508 | return 0; |
1503 | } | 1509 | } |
1504 | 1510 | ||
1505 | dev_err(card->dev, "%s not registered\n", aux_dev->codec_name); | 1511 | dev_err(card->dev, "ASoC: %s not registered\n", aux_dev->codec_name); |
1506 | 1512 | ||
1507 | return -EPROBE_DEFER; | 1513 | return -EPROBE_DEFER; |
1508 | } | 1514 | } |
@@ -1518,7 +1524,7 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num) | |||
1518 | if (!strcmp(codec->name, aux_dev->codec_name)) { | 1524 | if (!strcmp(codec->name, aux_dev->codec_name)) { |
1519 | if (codec->probed) { | 1525 | if (codec->probed) { |
1520 | dev_err(codec->dev, | 1526 | dev_err(codec->dev, |
1521 | "asoc: codec already probed"); | 1527 | "ASoC: codec already probed"); |
1522 | ret = -EBUSY; | 1528 | ret = -EBUSY; |
1523 | goto out; | 1529 | goto out; |
1524 | } | 1530 | } |
@@ -1526,7 +1532,7 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num) | |||
1526 | } | 1532 | } |
1527 | } | 1533 | } |
1528 | /* codec not found */ | 1534 | /* codec not found */ |
1529 | dev_err(card->dev, "asoc: codec %s not found", aux_dev->codec_name); | 1535 | dev_err(card->dev, "ASoC: codec %s not found", aux_dev->codec_name); |
1530 | return -EPROBE_DEFER; | 1536 | return -EPROBE_DEFER; |
1531 | 1537 | ||
1532 | found: | 1538 | found: |
@@ -1569,8 +1575,8 @@ static int snd_soc_init_codec_cache(struct snd_soc_codec *codec, | |||
1569 | codec->compress_type = compress_type; | 1575 | codec->compress_type = compress_type; |
1570 | ret = snd_soc_cache_init(codec); | 1576 | ret = snd_soc_cache_init(codec); |
1571 | if (ret < 0) { | 1577 | if (ret < 0) { |
1572 | dev_err(codec->dev, "Failed to set cache compression type: %d\n", | 1578 | dev_err(codec->dev, "ASoC: Failed to set cache compression" |
1573 | ret); | 1579 | " type: %d\n", ret); |
1574 | return ret; | 1580 | return ret; |
1575 | } | 1581 | } |
1576 | codec->cache_init = 1; | 1582 | codec->cache_init = 1; |
@@ -1626,8 +1632,8 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1626 | ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, | 1632 | ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, |
1627 | card->owner, 0, &card->snd_card); | 1633 | card->owner, 0, &card->snd_card); |
1628 | if (ret < 0) { | 1634 | if (ret < 0) { |
1629 | pr_err("asoc: can't create sound card for card %s: %d\n", | 1635 | dev_err(card->dev, "ASoC: can't create sound card for" |
1630 | card->name, ret); | 1636 | " card %s: %d\n", card->name, ret); |
1631 | goto base_error; | 1637 | goto base_error; |
1632 | } | 1638 | } |
1633 | card->snd_card->dev = card->dev; | 1639 | card->snd_card->dev = card->dev; |
@@ -1663,8 +1669,9 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1663 | for (i = 0; i < card->num_links; i++) { | 1669 | for (i = 0; i < card->num_links; i++) { |
1664 | ret = soc_probe_link_components(card, i, order); | 1670 | ret = soc_probe_link_components(card, i, order); |
1665 | if (ret < 0) { | 1671 | if (ret < 0) { |
1666 | pr_err("asoc: failed to instantiate card %s: %d\n", | 1672 | dev_err(card->dev, |
1667 | card->name, ret); | 1673 | "ASoC: failed to instantiate card %d\n", |
1674 | ret); | ||
1668 | goto probe_dai_err; | 1675 | goto probe_dai_err; |
1669 | } | 1676 | } |
1670 | } | 1677 | } |
@@ -1676,8 +1683,9 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1676 | for (i = 0; i < card->num_links; i++) { | 1683 | for (i = 0; i < card->num_links; i++) { |
1677 | ret = soc_probe_link_dais(card, i, order); | 1684 | ret = soc_probe_link_dais(card, i, order); |
1678 | if (ret < 0) { | 1685 | if (ret < 0) { |
1679 | pr_err("asoc: failed to instantiate card %s: %d\n", | 1686 | dev_err(card->dev, |
1680 | card->name, ret); | 1687 | "ASoC: failed to instantiate card %d\n", |
1688 | ret); | ||
1681 | goto probe_dai_err; | 1689 | goto probe_dai_err; |
1682 | } | 1690 | } |
1683 | } | 1691 | } |
@@ -1686,8 +1694,9 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1686 | for (i = 0; i < card->num_aux_devs; i++) { | 1694 | for (i = 0; i < card->num_aux_devs; i++) { |
1687 | ret = soc_probe_aux_dev(card, i); | 1695 | ret = soc_probe_aux_dev(card, i); |
1688 | if (ret < 0) { | 1696 | if (ret < 0) { |
1689 | pr_err("asoc: failed to add auxiliary devices %s: %d\n", | 1697 | dev_err(card->dev, |
1690 | card->name, ret); | 1698 | "ASoC: failed to add auxiliary devices %d\n", |
1699 | ret); | ||
1691 | goto probe_aux_dev_err; | 1700 | goto probe_aux_dev_err; |
1692 | } | 1701 | } |
1693 | } | 1702 | } |
@@ -1712,7 +1721,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1712 | dai_fmt); | 1721 | dai_fmt); |
1713 | if (ret != 0 && ret != -ENOTSUPP) | 1722 | if (ret != 0 && ret != -ENOTSUPP) |
1714 | dev_warn(card->rtd[i].codec_dai->dev, | 1723 | dev_warn(card->rtd[i].codec_dai->dev, |
1715 | "Failed to set DAI format: %d\n", | 1724 | "ASoC: Failed to set DAI format: %d\n", |
1716 | ret); | 1725 | ret); |
1717 | } | 1726 | } |
1718 | 1727 | ||
@@ -1723,7 +1732,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1723 | dai_fmt); | 1732 | dai_fmt); |
1724 | if (ret != 0 && ret != -ENOTSUPP) | 1733 | if (ret != 0 && ret != -ENOTSUPP) |
1725 | dev_warn(card->rtd[i].cpu_dai->dev, | 1734 | dev_warn(card->rtd[i].cpu_dai->dev, |
1726 | "Failed to set DAI format: %d\n", | 1735 | "ASoC: Failed to set DAI format: %d\n", |
1727 | ret); | 1736 | ret); |
1728 | } else if (dai_fmt) { | 1737 | } else if (dai_fmt) { |
1729 | /* Flip the polarity for the "CPU" end */ | 1738 | /* Flip the polarity for the "CPU" end */ |
@@ -1748,7 +1757,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1748 | dai_fmt); | 1757 | dai_fmt); |
1749 | if (ret != 0 && ret != -ENOTSUPP) | 1758 | if (ret != 0 && ret != -ENOTSUPP) |
1750 | dev_warn(card->rtd[i].cpu_dai->dev, | 1759 | dev_warn(card->rtd[i].cpu_dai->dev, |
1751 | "Failed to set DAI format: %d\n", | 1760 | "ASoC: Failed to set DAI format: %d\n", |
1752 | ret); | 1761 | ret); |
1753 | } | 1762 | } |
1754 | } | 1763 | } |
@@ -1775,7 +1784,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1775 | if (card->late_probe) { | 1784 | if (card->late_probe) { |
1776 | ret = card->late_probe(card); | 1785 | ret = card->late_probe(card); |
1777 | if (ret < 0) { | 1786 | if (ret < 0) { |
1778 | dev_err(card->dev, "%s late_probe() failed: %d\n", | 1787 | dev_err(card->dev, "ASoC: %s late_probe() failed: %d\n", |
1779 | card->name, ret); | 1788 | card->name, ret); |
1780 | goto probe_aux_dev_err; | 1789 | goto probe_aux_dev_err; |
1781 | } | 1790 | } |
@@ -1789,8 +1798,8 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1789 | 1798 | ||
1790 | ret = snd_card_register(card->snd_card); | 1799 | ret = snd_card_register(card->snd_card); |
1791 | if (ret < 0) { | 1800 | if (ret < 0) { |
1792 | pr_err("asoc: failed to register soundcard for %s: %d\n", | 1801 | dev_err(card->dev, "ASoC: failed to register soundcard %d\n", |
1793 | card->name, ret); | 1802 | ret); |
1794 | goto probe_aux_dev_err; | 1803 | goto probe_aux_dev_err; |
1795 | } | 1804 | } |
1796 | 1805 | ||
@@ -1799,8 +1808,8 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1799 | for (i = 0; i < card->num_rtd; i++) { | 1808 | for (i = 0; i < card->num_rtd; i++) { |
1800 | ret = soc_register_ac97_dai_link(&card->rtd[i]); | 1809 | ret = soc_register_ac97_dai_link(&card->rtd[i]); |
1801 | if (ret < 0) { | 1810 | if (ret < 0) { |
1802 | pr_err("asoc: failed to register AC97 %s: %d\n", | 1811 | dev_err(card->dev, "ASoC: failed to register AC97:" |
1803 | card->name, ret); | 1812 | " %d\n", ret); |
1804 | while (--i >= 0) | 1813 | while (--i >= 0) |
1805 | soc_unregister_ac97_dai_link(card->rtd[i].codec); | 1814 | soc_unregister_ac97_dai_link(card->rtd[i].codec); |
1806 | goto probe_aux_dev_err; | 1815 | goto probe_aux_dev_err; |
@@ -1846,7 +1855,7 @@ static int soc_probe(struct platform_device *pdev) | |||
1846 | return -EINVAL; | 1855 | return -EINVAL; |
1847 | 1856 | ||
1848 | dev_warn(&pdev->dev, | 1857 | dev_warn(&pdev->dev, |
1849 | "ASoC machine %s should use snd_soc_register_card()\n", | 1858 | "ASoC: machine %s should use snd_soc_register_card()\n", |
1850 | card->name); | 1859 | card->name); |
1851 | 1860 | ||
1852 | /* Bodge while we unpick instantiation */ | 1861 | /* Bodge while we unpick instantiation */ |
@@ -1996,7 +2005,7 @@ int snd_soc_platform_read(struct snd_soc_platform *platform, | |||
1996 | unsigned int ret; | 2005 | unsigned int ret; |
1997 | 2006 | ||
1998 | if (!platform->driver->read) { | 2007 | if (!platform->driver->read) { |
1999 | dev_err(platform->dev, "platform has no read back\n"); | 2008 | dev_err(platform->dev, "ASoC: platform has no read back\n"); |
2000 | return -1; | 2009 | return -1; |
2001 | } | 2010 | } |
2002 | 2011 | ||
@@ -2012,7 +2021,7 @@ int snd_soc_platform_write(struct snd_soc_platform *platform, | |||
2012 | unsigned int reg, unsigned int val) | 2021 | unsigned int reg, unsigned int val) |
2013 | { | 2022 | { |
2014 | if (!platform->driver->write) { | 2023 | if (!platform->driver->write) { |
2015 | dev_err(platform->dev, "platform has no write back\n"); | 2024 | dev_err(platform->dev, "ASoC: platform has no write back\n"); |
2016 | return -1; | 2025 | return -1; |
2017 | } | 2026 | } |
2018 | 2027 | ||
@@ -2283,7 +2292,8 @@ static int snd_soc_add_controls(struct snd_card *card, struct device *dev, | |||
2283 | err = snd_ctl_add(card, snd_soc_cnew(control, data, | 2292 | err = snd_ctl_add(card, snd_soc_cnew(control, data, |
2284 | control->name, prefix)); | 2293 | control->name, prefix)); |
2285 | if (err < 0) { | 2294 | if (err < 0) { |
2286 | dev_err(dev, "Failed to add %s: %d\n", control->name, err); | 2295 | dev_err(dev, "ASoC: Failed to add %s: %d\n", |
2296 | control->name, err); | ||
2287 | return err; | 2297 | return err; |
2288 | } | 2298 | } |
2289 | } | 2299 | } |
@@ -3534,15 +3544,14 @@ int snd_soc_register_card(struct snd_soc_card *card) | |||
3534 | * not both or neither. | 3544 | * not both or neither. |
3535 | */ | 3545 | */ |
3536 | if (!!link->codec_name == !!link->codec_of_node) { | 3546 | if (!!link->codec_name == !!link->codec_of_node) { |
3537 | dev_err(card->dev, | 3547 | dev_err(card->dev, "ASoC: Neither/both codec" |
3538 | "Neither/both codec name/of_node are set for %s\n", | 3548 | " name/of_node are set for %s\n", link->name); |
3539 | link->name); | ||
3540 | return -EINVAL; | 3549 | return -EINVAL; |
3541 | } | 3550 | } |
3542 | /* Codec DAI name must be specified */ | 3551 | /* Codec DAI name must be specified */ |
3543 | if (!link->codec_dai_name) { | 3552 | if (!link->codec_dai_name) { |
3544 | dev_err(card->dev, "codec_dai_name not set for %s\n", | 3553 | dev_err(card->dev, "ASoC: codec_dai_name not" |
3545 | link->name); | 3554 | " set for %s\n", link->name); |
3546 | return -EINVAL; | 3555 | return -EINVAL; |
3547 | } | 3556 | } |
3548 | 3557 | ||
@@ -3551,8 +3560,8 @@ int snd_soc_register_card(struct snd_soc_card *card) | |||
3551 | * can be left unspecified, and a dummy platform will be used. | 3560 | * can be left unspecified, and a dummy platform will be used. |
3552 | */ | 3561 | */ |
3553 | if (link->platform_name && link->platform_of_node) { | 3562 | if (link->platform_name && link->platform_of_node) { |
3554 | dev_err(card->dev, | 3563 | dev_err(card->dev, "ASoC: Both platform name/of_node" |
3555 | "Both platform name/of_node are set for %s\n", link->name); | 3564 | " are set for %s\n", link->name); |
3556 | return -EINVAL; | 3565 | return -EINVAL; |
3557 | } | 3566 | } |
3558 | 3567 | ||
@@ -3562,9 +3571,8 @@ int snd_soc_register_card(struct snd_soc_card *card) | |||
3562 | * name alone.. | 3571 | * name alone.. |
3563 | */ | 3572 | */ |
3564 | if (link->cpu_name && link->cpu_of_node) { | 3573 | if (link->cpu_name && link->cpu_of_node) { |
3565 | dev_err(card->dev, | 3574 | dev_err(card->dev, "ASoC: Neither/both " |
3566 | "Neither/both cpu name/of_node are set for %s\n", | 3575 | "cpu name/of_node are set for %s\n",link->name); |
3567 | link->name); | ||
3568 | return -EINVAL; | 3576 | return -EINVAL; |
3569 | } | 3577 | } |
3570 | /* | 3578 | /* |
@@ -3573,9 +3581,8 @@ int snd_soc_register_card(struct snd_soc_card *card) | |||
3573 | */ | 3581 | */ |
3574 | if (!link->cpu_dai_name && | 3582 | if (!link->cpu_dai_name && |
3575 | !(link->cpu_name || link->cpu_of_node)) { | 3583 | !(link->cpu_name || link->cpu_of_node)) { |
3576 | dev_err(card->dev, | 3584 | dev_err(card->dev, "ASoC: Neither cpu_dai_name nor " |
3577 | "Neither cpu_dai_name nor cpu_name/of_node are set for %s\n", | 3585 | "cpu_name/of_node are set for %s\n", link->name); |
3578 | link->name); | ||
3579 | return -EINVAL; | 3586 | return -EINVAL; |
3580 | } | 3587 | } |
3581 | } | 3588 | } |
@@ -3622,7 +3629,7 @@ int snd_soc_unregister_card(struct snd_soc_card *card) | |||
3622 | { | 3629 | { |
3623 | if (card->instantiated) | 3630 | if (card->instantiated) |
3624 | soc_cleanup_card_resources(card); | 3631 | soc_cleanup_card_resources(card); |
3625 | dev_dbg(card->dev, "Unregistered card '%s'\n", card->name); | 3632 | dev_dbg(card->dev, "ASoC: Unregistered card '%s'\n", card->name); |
3626 | 3633 | ||
3627 | return 0; | 3634 | return 0; |
3628 | } | 3635 | } |
@@ -3679,8 +3686,8 @@ static inline char *fmt_multiple_name(struct device *dev, | |||
3679 | struct snd_soc_dai_driver *dai_drv) | 3686 | struct snd_soc_dai_driver *dai_drv) |
3680 | { | 3687 | { |
3681 | if (dai_drv->name == NULL) { | 3688 | if (dai_drv->name == NULL) { |
3682 | pr_err("asoc: error - multiple DAI %s registered with no name\n", | 3689 | dev_err(dev, "ASoC: error - multiple DAI %s registered with" |
3683 | dev_name(dev)); | 3690 | " no name\n", dev_name(dev)); |
3684 | return NULL; | 3691 | return NULL; |
3685 | } | 3692 | } |
3686 | 3693 | ||
@@ -3698,7 +3705,7 @@ int snd_soc_register_dai(struct device *dev, | |||
3698 | struct snd_soc_codec *codec; | 3705 | struct snd_soc_codec *codec; |
3699 | struct snd_soc_dai *dai; | 3706 | struct snd_soc_dai *dai; |
3700 | 3707 | ||
3701 | dev_dbg(dev, "dai register %s\n", dev_name(dev)); | 3708 | dev_dbg(dev, "ASoC: dai register %s\n", dev_name(dev)); |
3702 | 3709 | ||
3703 | dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL); | 3710 | dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL); |
3704 | if (dai == NULL) | 3711 | if (dai == NULL) |
@@ -3721,7 +3728,7 @@ int snd_soc_register_dai(struct device *dev, | |||
3721 | 3728 | ||
3722 | list_for_each_entry(codec, &codec_list, list) { | 3729 | list_for_each_entry(codec, &codec_list, list) { |
3723 | if (codec->dev == dev) { | 3730 | if (codec->dev == dev) { |
3724 | dev_dbg(dev, "Mapped DAI %s to CODEC %s\n", | 3731 | dev_dbg(dev, "ASoC: Mapped DAI %s to CODEC %s\n", |
3725 | dai->name, codec->name); | 3732 | dai->name, codec->name); |
3726 | dai->codec = codec; | 3733 | dai->codec = codec; |
3727 | break; | 3734 | break; |
@@ -3735,7 +3742,7 @@ int snd_soc_register_dai(struct device *dev, | |||
3735 | 3742 | ||
3736 | mutex_unlock(&client_mutex); | 3743 | mutex_unlock(&client_mutex); |
3737 | 3744 | ||
3738 | pr_debug("Registered DAI '%s'\n", dai->name); | 3745 | dev_dbg(dev, "ASoC: Registered DAI '%s'\n", dai->name); |
3739 | 3746 | ||
3740 | return 0; | 3747 | return 0; |
3741 | } | 3748 | } |
@@ -3761,7 +3768,7 @@ found: | |||
3761 | list_del(&dai->list); | 3768 | list_del(&dai->list); |
3762 | mutex_unlock(&client_mutex); | 3769 | mutex_unlock(&client_mutex); |
3763 | 3770 | ||
3764 | pr_debug("Unregistered DAI '%s'\n", dai->name); | 3771 | dev_dbg(dev, "ASoC: Unregistered DAI '%s'\n", dai->name); |
3765 | kfree(dai->name); | 3772 | kfree(dai->name); |
3766 | kfree(dai); | 3773 | kfree(dai); |
3767 | } | 3774 | } |
@@ -3780,7 +3787,7 @@ int snd_soc_register_dais(struct device *dev, | |||
3780 | struct snd_soc_dai *dai; | 3787 | struct snd_soc_dai *dai; |
3781 | int i, ret = 0; | 3788 | int i, ret = 0; |
3782 | 3789 | ||
3783 | dev_dbg(dev, "dai register %s #%Zu\n", dev_name(dev), count); | 3790 | dev_dbg(dev, "ASoC: dai register %s #%Zu\n", dev_name(dev), count); |
3784 | 3791 | ||
3785 | for (i = 0; i < count; i++) { | 3792 | for (i = 0; i < count; i++) { |
3786 | 3793 | ||
@@ -3812,8 +3819,8 @@ int snd_soc_register_dais(struct device *dev, | |||
3812 | 3819 | ||
3813 | list_for_each_entry(codec, &codec_list, list) { | 3820 | list_for_each_entry(codec, &codec_list, list) { |
3814 | if (codec->dev == dev) { | 3821 | if (codec->dev == dev) { |
3815 | dev_dbg(dev, "Mapped DAI %s to CODEC %s\n", | 3822 | dev_dbg(dev, "ASoC: Mapped DAI %s to " |
3816 | dai->name, codec->name); | 3823 | "CODEC %s\n", dai->name, codec->name); |
3817 | dai->codec = codec; | 3824 | dai->codec = codec; |
3818 | break; | 3825 | break; |
3819 | } | 3826 | } |
@@ -3826,7 +3833,7 @@ int snd_soc_register_dais(struct device *dev, | |||
3826 | 3833 | ||
3827 | mutex_unlock(&client_mutex); | 3834 | mutex_unlock(&client_mutex); |
3828 | 3835 | ||
3829 | pr_debug("Registered DAI '%s'\n", dai->name); | 3836 | dev_dbg(dai->dev, "ASoC: Registered DAI '%s'\n", dai->name); |
3830 | } | 3837 | } |
3831 | 3838 | ||
3832 | return 0; | 3839 | return 0; |
@@ -3864,7 +3871,7 @@ int snd_soc_register_platform(struct device *dev, | |||
3864 | { | 3871 | { |
3865 | struct snd_soc_platform *platform; | 3872 | struct snd_soc_platform *platform; |
3866 | 3873 | ||
3867 | dev_dbg(dev, "platform register %s\n", dev_name(dev)); | 3874 | dev_dbg(dev, "ASoC: platform register %s\n", dev_name(dev)); |
3868 | 3875 | ||
3869 | platform = kzalloc(sizeof(struct snd_soc_platform), GFP_KERNEL); | 3876 | platform = kzalloc(sizeof(struct snd_soc_platform), GFP_KERNEL); |
3870 | if (platform == NULL) | 3877 | if (platform == NULL) |
@@ -3888,7 +3895,7 @@ int snd_soc_register_platform(struct device *dev, | |||
3888 | list_add(&platform->list, &platform_list); | 3895 | list_add(&platform->list, &platform_list); |
3889 | mutex_unlock(&client_mutex); | 3896 | mutex_unlock(&client_mutex); |
3890 | 3897 | ||
3891 | pr_debug("Registered platform '%s'\n", platform->name); | 3898 | dev_dbg(dev, "ASoC: Registered platform '%s'\n", platform->name); |
3892 | 3899 | ||
3893 | return 0; | 3900 | return 0; |
3894 | } | 3901 | } |
@@ -3914,7 +3921,7 @@ found: | |||
3914 | list_del(&platform->list); | 3921 | list_del(&platform->list); |
3915 | mutex_unlock(&client_mutex); | 3922 | mutex_unlock(&client_mutex); |
3916 | 3923 | ||
3917 | pr_debug("Unregistered platform '%s'\n", platform->name); | 3924 | dev_dbg(dev, "ASoC: Unregistered platform '%s'\n", platform->name); |
3918 | kfree(platform->name); | 3925 | kfree(platform->name); |
3919 | kfree(platform); | 3926 | kfree(platform); |
3920 | } | 3927 | } |
@@ -4007,7 +4014,7 @@ int snd_soc_register_codec(struct device *dev, | |||
4007 | codec->reg_size = reg_size; | 4014 | codec->reg_size = reg_size; |
4008 | /* it is necessary to make a copy of the default register cache | 4015 | /* it is necessary to make a copy of the default register cache |
4009 | * because in the case of using a compression type that requires | 4016 | * because in the case of using a compression type that requires |
4010 | * the default register cache to be marked as __devinitconst the | 4017 | * the default register cache to be marked as the |
4011 | * kernel might have freed the array by the time we initialize | 4018 | * kernel might have freed the array by the time we initialize |
4012 | * the cache. | 4019 | * the cache. |
4013 | */ | 4020 | */ |
@@ -4043,11 +4050,11 @@ int snd_soc_register_codec(struct device *dev, | |||
4043 | if (num_dai) { | 4050 | if (num_dai) { |
4044 | ret = snd_soc_register_dais(dev, dai_drv, num_dai); | 4051 | ret = snd_soc_register_dais(dev, dai_drv, num_dai); |
4045 | if (ret < 0) | 4052 | if (ret < 0) |
4046 | dev_err(codec->dev, "Failed to regster DAIs: %d\n", | 4053 | dev_err(codec->dev, "ASoC: Failed to regster" |
4047 | ret); | 4054 | " DAIs: %d\n", ret); |
4048 | } | 4055 | } |
4049 | 4056 | ||
4050 | pr_debug("Registered codec '%s'\n", codec->name); | 4057 | dev_dbg(codec->dev, "ASoC: Registered codec '%s'\n", codec->name); |
4051 | return 0; | 4058 | return 0; |
4052 | 4059 | ||
4053 | fail: | 4060 | fail: |
@@ -4082,7 +4089,7 @@ found: | |||
4082 | list_del(&codec->list); | 4089 | list_del(&codec->list); |
4083 | mutex_unlock(&client_mutex); | 4090 | mutex_unlock(&client_mutex); |
4084 | 4091 | ||
4085 | pr_debug("Unregistered codec '%s'\n", codec->name); | 4092 | dev_dbg(codec->dev, "ASoC: Unregistered codec '%s'\n", codec->name); |
4086 | 4093 | ||
4087 | snd_soc_cache_exit(codec); | 4094 | snd_soc_cache_exit(codec); |
4088 | kfree(codec->reg_def_copy); | 4095 | kfree(codec->reg_def_copy); |
@@ -4106,7 +4113,7 @@ int snd_soc_of_parse_card_name(struct snd_soc_card *card, | |||
4106 | */ | 4113 | */ |
4107 | if (ret < 0 && ret != -EINVAL) { | 4114 | if (ret < 0 && ret != -EINVAL) { |
4108 | dev_err(card->dev, | 4115 | dev_err(card->dev, |
4109 | "Property '%s' could not be read: %d\n", | 4116 | "ASoC: Property '%s' could not be read: %d\n", |
4110 | propname, ret); | 4117 | propname, ret); |
4111 | return ret; | 4118 | return ret; |
4112 | } | 4119 | } |
@@ -4125,15 +4132,13 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, | |||
4125 | 4132 | ||
4126 | num_routes = of_property_count_strings(np, propname); | 4133 | num_routes = of_property_count_strings(np, propname); |
4127 | if (num_routes < 0 || num_routes & 1) { | 4134 | if (num_routes < 0 || num_routes & 1) { |
4128 | dev_err(card->dev, | 4135 | dev_err(card->dev, "ASoC: Property '%s' does not exist or its" |
4129 | "Property '%s' does not exist or its length is not even\n", | 4136 | " length is not even\n", propname); |
4130 | propname); | ||
4131 | return -EINVAL; | 4137 | return -EINVAL; |
4132 | } | 4138 | } |
4133 | num_routes /= 2; | 4139 | num_routes /= 2; |
4134 | if (!num_routes) { | 4140 | if (!num_routes) { |
4135 | dev_err(card->dev, | 4141 | dev_err(card->dev, "ASoC: Property '%s's length is zero\n", |
4136 | "Property '%s's length is zero\n", | ||
4137 | propname); | 4142 | propname); |
4138 | return -EINVAL; | 4143 | return -EINVAL; |
4139 | } | 4144 | } |
@@ -4142,7 +4147,7 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, | |||
4142 | GFP_KERNEL); | 4147 | GFP_KERNEL); |
4143 | if (!routes) { | 4148 | if (!routes) { |
4144 | dev_err(card->dev, | 4149 | dev_err(card->dev, |
4145 | "Could not allocate DAPM route table\n"); | 4150 | "ASoC: Could not allocate DAPM route table\n"); |
4146 | return -EINVAL; | 4151 | return -EINVAL; |
4147 | } | 4152 | } |
4148 | 4153 | ||
@@ -4150,9 +4155,9 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, | |||
4150 | ret = of_property_read_string_index(np, propname, | 4155 | ret = of_property_read_string_index(np, propname, |
4151 | 2 * i, &routes[i].sink); | 4156 | 2 * i, &routes[i].sink); |
4152 | if (ret) { | 4157 | if (ret) { |
4153 | dev_err(card->dev, | 4158 | dev_err(card->dev, "ASoC: Property '%s' index %d" |
4154 | "Property '%s' index %d could not be read: %d\n", | 4159 | " could not be read: %d\n", propname, 2 * i, |
4155 | propname, 2 * i, ret); | 4160 | ret); |
4156 | kfree(routes); | 4161 | kfree(routes); |
4157 | return -EINVAL; | 4162 | return -EINVAL; |
4158 | } | 4163 | } |
@@ -4160,8 +4165,8 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, | |||
4160 | (2 * i) + 1, &routes[i].source); | 4165 | (2 * i) + 1, &routes[i].source); |
4161 | if (ret) { | 4166 | if (ret) { |
4162 | dev_err(card->dev, | 4167 | dev_err(card->dev, |
4163 | "Property '%s' index %d could not be read: %d\n", | 4168 | "ASoC: Property '%s' index %d could not be" |
4164 | propname, (2 * i) + 1, ret); | 4169 | " read: %d\n", propname, (2 * i) + 1, ret); |
4165 | kfree(routes); | 4170 | kfree(routes); |
4166 | return -EINVAL; | 4171 | return -EINVAL; |
4167 | } | 4172 | } |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 6e35bcae02df..1e36bc81e5af 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -220,7 +220,7 @@ static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg) | |||
220 | else if (w->platform) | 220 | else if (w->platform) |
221 | return snd_soc_platform_read(w->platform, reg); | 221 | return snd_soc_platform_read(w->platform, reg); |
222 | 222 | ||
223 | dev_err(w->dapm->dev, "no valid widget read method\n"); | 223 | dev_err(w->dapm->dev, "ASoC: no valid widget read method\n"); |
224 | return -1; | 224 | return -1; |
225 | } | 225 | } |
226 | 226 | ||
@@ -231,7 +231,7 @@ static int soc_widget_write(struct snd_soc_dapm_widget *w, int reg, int val) | |||
231 | else if (w->platform) | 231 | else if (w->platform) |
232 | return snd_soc_platform_write(w->platform, reg, val); | 232 | return snd_soc_platform_write(w->platform, reg, val); |
233 | 233 | ||
234 | dev_err(w->dapm->dev, "no valid widget write method\n"); | 234 | dev_err(w->dapm->dev, "ASoC: no valid widget write method\n"); |
235 | return -1; | 235 | return -1; |
236 | } | 236 | } |
237 | 237 | ||
@@ -546,7 +546,7 @@ static int dapm_new_mixer(struct snd_soc_dapm_widget *w) | |||
546 | wlist = kzalloc(wlistsize, GFP_KERNEL); | 546 | wlist = kzalloc(wlistsize, GFP_KERNEL); |
547 | if (wlist == NULL) { | 547 | if (wlist == NULL) { |
548 | dev_err(dapm->dev, | 548 | dev_err(dapm->dev, |
549 | "asoc: can't allocate widget list for %s\n", | 549 | "ASoC: can't allocate widget list for %s\n", |
550 | w->name); | 550 | w->name); |
551 | return -ENOMEM; | 551 | return -ENOMEM; |
552 | } | 552 | } |
@@ -595,9 +595,9 @@ static int dapm_new_mixer(struct snd_soc_dapm_widget *w) | |||
595 | prefix); | 595 | prefix); |
596 | ret = snd_ctl_add(card, path->kcontrol); | 596 | ret = snd_ctl_add(card, path->kcontrol); |
597 | if (ret < 0) { | 597 | if (ret < 0) { |
598 | dev_err(dapm->dev, | 598 | dev_err(dapm->dev, "ASoC: failed to add widget" |
599 | "asoc: failed to add dapm kcontrol %s: %d\n", | 599 | " %s dapm kcontrol %s: %d\n", |
600 | path->long_name, ret); | 600 | w->name, path->long_name, ret); |
601 | kfree(wlist); | 601 | kfree(wlist); |
602 | kfree(path->long_name); | 602 | kfree(path->long_name); |
603 | path->long_name = NULL; | 603 | path->long_name = NULL; |
@@ -626,7 +626,7 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w) | |||
626 | 626 | ||
627 | if (w->num_kcontrols != 1) { | 627 | if (w->num_kcontrols != 1) { |
628 | dev_err(dapm->dev, | 628 | dev_err(dapm->dev, |
629 | "asoc: mux %s has incorrect number of controls\n", | 629 | "ASoC: mux %s has incorrect number of controls\n", |
630 | w->name); | 630 | w->name); |
631 | return -EINVAL; | 631 | return -EINVAL; |
632 | } | 632 | } |
@@ -645,7 +645,7 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w) | |||
645 | wlist = krealloc(wlist, wlistsize, GFP_KERNEL); | 645 | wlist = krealloc(wlist, wlistsize, GFP_KERNEL); |
646 | if (wlist == NULL) { | 646 | if (wlist == NULL) { |
647 | dev_err(dapm->dev, | 647 | dev_err(dapm->dev, |
648 | "asoc: can't allocate widget list for %s\n", w->name); | 648 | "ASoC: can't allocate widget list for %s\n", w->name); |
649 | return -ENOMEM; | 649 | return -ENOMEM; |
650 | } | 650 | } |
651 | wlist->num_widgets = wlistentries; | 651 | wlist->num_widgets = wlistentries; |
@@ -677,7 +677,7 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w) | |||
677 | name + prefix_len, prefix); | 677 | name + prefix_len, prefix); |
678 | ret = snd_ctl_add(card, kcontrol); | 678 | ret = snd_ctl_add(card, kcontrol); |
679 | if (ret < 0) { | 679 | if (ret < 0) { |
680 | dev_err(dapm->dev, "failed to add kcontrol %s: %d\n", | 680 | dev_err(dapm->dev, "ASoC: failed to add kcontrol %s: %d\n", |
681 | w->name, ret); | 681 | w->name, ret); |
682 | kfree(wlist); | 682 | kfree(wlist); |
683 | return ret; | 683 | return ret; |
@@ -699,7 +699,7 @@ static int dapm_new_pga(struct snd_soc_dapm_widget *w) | |||
699 | { | 699 | { |
700 | if (w->num_kcontrols) | 700 | if (w->num_kcontrols) |
701 | dev_err(w->dapm->dev, | 701 | dev_err(w->dapm->dev, |
702 | "asoc: PGA controls not supported: '%s'\n", w->name); | 702 | "ASoC: PGA controls not supported: '%s'\n", w->name); |
703 | 703 | ||
704 | return 0; | 704 | return 0; |
705 | } | 705 | } |
@@ -725,7 +725,7 @@ static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget) | |||
725 | case SNDRV_CTL_POWER_D3hot: | 725 | case SNDRV_CTL_POWER_D3hot: |
726 | case SNDRV_CTL_POWER_D3cold: | 726 | case SNDRV_CTL_POWER_D3cold: |
727 | if (widget->ignore_suspend) | 727 | if (widget->ignore_suspend) |
728 | dev_dbg(widget->dapm->dev, "%s ignoring suspend\n", | 728 | dev_dbg(widget->dapm->dev, "ASoC: %s ignoring suspend\n", |
729 | widget->name); | 729 | widget->name); |
730 | return widget->ignore_suspend; | 730 | return widget->ignore_suspend; |
731 | default: | 731 | default: |
@@ -757,14 +757,14 @@ static int dapm_list_add_widget(struct snd_soc_dapm_widget_list **list, | |||
757 | wlistentries * sizeof(struct snd_soc_dapm_widget *); | 757 | wlistentries * sizeof(struct snd_soc_dapm_widget *); |
758 | *list = krealloc(wlist, wlistsize, GFP_KERNEL); | 758 | *list = krealloc(wlist, wlistsize, GFP_KERNEL); |
759 | if (*list == NULL) { | 759 | if (*list == NULL) { |
760 | dev_err(w->dapm->dev, "can't allocate widget list for %s\n", | 760 | dev_err(w->dapm->dev, "ASoC: can't allocate widget list for %s\n", |
761 | w->name); | 761 | w->name); |
762 | return -ENOMEM; | 762 | return -ENOMEM; |
763 | } | 763 | } |
764 | wlist = *list; | 764 | wlist = *list; |
765 | 765 | ||
766 | /* insert the widget */ | 766 | /* insert the widget */ |
767 | dev_dbg(w->dapm->dev, "added %s in widget list pos %d\n", | 767 | dev_dbg(w->dapm->dev, "ASoC: added %s in widget list pos %d\n", |
768 | w->name, wlist->num_widgets); | 768 | w->name, wlist->num_widgets); |
769 | 769 | ||
770 | wlist->widgets[wlist->num_widgets] = w; | 770 | wlist->widgets[wlist->num_widgets] = w; |
@@ -844,7 +844,8 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget, | |||
844 | int err; | 844 | int err; |
845 | err = dapm_list_add_widget(list, path->sink); | 845 | err = dapm_list_add_widget(list, path->sink); |
846 | if (err < 0) { | 846 | if (err < 0) { |
847 | dev_err(widget->dapm->dev, "could not add widget %s\n", | 847 | dev_err(widget->dapm->dev, |
848 | "ASoC: could not add widget %s\n", | ||
848 | widget->name); | 849 | widget->name); |
849 | return con; | 850 | return con; |
850 | } | 851 | } |
@@ -943,7 +944,8 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget, | |||
943 | int err; | 944 | int err; |
944 | err = dapm_list_add_widget(list, path->source); | 945 | err = dapm_list_add_widget(list, path->source); |
945 | if (err < 0) { | 946 | if (err < 0) { |
946 | dev_err(widget->dapm->dev, "could not add widget %s\n", | 947 | dev_err(widget->dapm->dev, |
948 | "ASoC: could not add widget %s\n", | ||
947 | widget->name); | 949 | widget->name); |
948 | return con; | 950 | return con; |
949 | } | 951 | } |
@@ -1024,7 +1026,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w, | |||
1024 | ret = regulator_allow_bypass(w->regulator, true); | 1026 | ret = regulator_allow_bypass(w->regulator, true); |
1025 | if (ret != 0) | 1027 | if (ret != 0) |
1026 | dev_warn(w->dapm->dev, | 1028 | dev_warn(w->dapm->dev, |
1027 | "Failed to bypass %s: %d\n", | 1029 | "ASoC: Failed to bypass %s: %d\n", |
1028 | w->name, ret); | 1030 | w->name, ret); |
1029 | } | 1031 | } |
1030 | 1032 | ||
@@ -1034,7 +1036,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w, | |||
1034 | ret = regulator_allow_bypass(w->regulator, false); | 1036 | ret = regulator_allow_bypass(w->regulator, false); |
1035 | if (ret != 0) | 1037 | if (ret != 0) |
1036 | dev_warn(w->dapm->dev, | 1038 | dev_warn(w->dapm->dev, |
1037 | "Failed to unbypass %s: %d\n", | 1039 | "ASoC: Failed to unbypass %s: %d\n", |
1038 | w->name, ret); | 1040 | w->name, ret); |
1039 | } | 1041 | } |
1040 | 1042 | ||
@@ -1253,7 +1255,7 @@ static void dapm_seq_check_event(struct snd_soc_dapm_context *dapm, | |||
1253 | ret = w->event(w, NULL, event); | 1255 | ret = w->event(w, NULL, event); |
1254 | trace_snd_soc_dapm_widget_event_done(w, event); | 1256 | trace_snd_soc_dapm_widget_event_done(w, event); |
1255 | if (ret < 0) | 1257 | if (ret < 0) |
1256 | pr_err("%s: %s event failed: %d\n", | 1258 | dev_err(dapm->dev, "ASoC: %s: %s event failed: %d\n", |
1257 | ev_name, w->name, ret); | 1259 | ev_name, w->name, ret); |
1258 | } | 1260 | } |
1259 | } | 1261 | } |
@@ -1402,7 +1404,7 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm, | |||
1402 | 1404 | ||
1403 | if (ret < 0) | 1405 | if (ret < 0) |
1404 | dev_err(w->dapm->dev, | 1406 | dev_err(w->dapm->dev, |
1405 | "Failed to apply widget power: %d\n", ret); | 1407 | "ASoC: Failed to apply widget power: %d\n", ret); |
1406 | } | 1408 | } |
1407 | 1409 | ||
1408 | if (!list_empty(&pending)) | 1410 | if (!list_empty(&pending)) |
@@ -1431,20 +1433,21 @@ static void dapm_widget_update(struct snd_soc_dapm_context *dapm) | |||
1431 | (w->event_flags & SND_SOC_DAPM_PRE_REG)) { | 1433 | (w->event_flags & SND_SOC_DAPM_PRE_REG)) { |
1432 | ret = w->event(w, update->kcontrol, SND_SOC_DAPM_PRE_REG); | 1434 | ret = w->event(w, update->kcontrol, SND_SOC_DAPM_PRE_REG); |
1433 | if (ret != 0) | 1435 | if (ret != 0) |
1434 | pr_err("%s DAPM pre-event failed: %d\n", | 1436 | dev_err(dapm->dev, "ASoC: %s DAPM pre-event failed: %d\n", |
1435 | w->name, ret); | 1437 | w->name, ret); |
1436 | } | 1438 | } |
1437 | 1439 | ||
1438 | ret = soc_widget_update_bits_locked(w, update->reg, update->mask, | 1440 | ret = soc_widget_update_bits_locked(w, update->reg, update->mask, |
1439 | update->val); | 1441 | update->val); |
1440 | if (ret < 0) | 1442 | if (ret < 0) |
1441 | pr_err("%s DAPM update failed: %d\n", w->name, ret); | 1443 | dev_err(dapm->dev, "ASoC: %s DAPM update failed: %d\n", |
1444 | w->name, ret); | ||
1442 | 1445 | ||
1443 | if (w->event && | 1446 | if (w->event && |
1444 | (w->event_flags & SND_SOC_DAPM_POST_REG)) { | 1447 | (w->event_flags & SND_SOC_DAPM_POST_REG)) { |
1445 | ret = w->event(w, update->kcontrol, SND_SOC_DAPM_POST_REG); | 1448 | ret = w->event(w, update->kcontrol, SND_SOC_DAPM_POST_REG); |
1446 | if (ret != 0) | 1449 | if (ret != 0) |
1447 | pr_err("%s DAPM post-event failed: %d\n", | 1450 | dev_err(dapm->dev, "ASoC: %s DAPM post-event failed: %d\n", |
1448 | w->name, ret); | 1451 | w->name, ret); |
1449 | } | 1452 | } |
1450 | } | 1453 | } |
@@ -1466,7 +1469,7 @@ static void dapm_pre_sequence_async(void *data, async_cookie_t cookie) | |||
1466 | ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY); | 1469 | ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY); |
1467 | if (ret != 0) | 1470 | if (ret != 0) |
1468 | dev_err(d->dev, | 1471 | dev_err(d->dev, |
1469 | "Failed to turn on bias: %d\n", ret); | 1472 | "ASoC: Failed to turn on bias: %d\n", ret); |
1470 | } | 1473 | } |
1471 | 1474 | ||
1472 | /* Prepare for a STADDBY->ON or ON->STANDBY transition */ | 1475 | /* Prepare for a STADDBY->ON or ON->STANDBY transition */ |
@@ -1474,7 +1477,7 @@ static void dapm_pre_sequence_async(void *data, async_cookie_t cookie) | |||
1474 | ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_PREPARE); | 1477 | ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_PREPARE); |
1475 | if (ret != 0) | 1478 | if (ret != 0) |
1476 | dev_err(d->dev, | 1479 | dev_err(d->dev, |
1477 | "Failed to prepare bias: %d\n", ret); | 1480 | "ASoC: Failed to prepare bias: %d\n", ret); |
1478 | } | 1481 | } |
1479 | } | 1482 | } |
1480 | 1483 | ||
@@ -1492,7 +1495,7 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie) | |||
1492 | d->target_bias_level == SND_SOC_BIAS_OFF)) { | 1495 | d->target_bias_level == SND_SOC_BIAS_OFF)) { |
1493 | ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY); | 1496 | ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY); |
1494 | if (ret != 0) | 1497 | if (ret != 0) |
1495 | dev_err(d->dev, "Failed to apply standby bias: %d\n", | 1498 | dev_err(d->dev, "ASoC: Failed to apply standby bias: %d\n", |
1496 | ret); | 1499 | ret); |
1497 | } | 1500 | } |
1498 | 1501 | ||
@@ -1501,7 +1504,8 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie) | |||
1501 | d->target_bias_level == SND_SOC_BIAS_OFF) { | 1504 | d->target_bias_level == SND_SOC_BIAS_OFF) { |
1502 | ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_OFF); | 1505 | ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_OFF); |
1503 | if (ret != 0) | 1506 | if (ret != 0) |
1504 | dev_err(d->dev, "Failed to turn off bias: %d\n", ret); | 1507 | dev_err(d->dev, "ASoC: Failed to turn off bias: %d\n", |
1508 | ret); | ||
1505 | 1509 | ||
1506 | if (d->dev) | 1510 | if (d->dev) |
1507 | pm_runtime_put(d->dev); | 1511 | pm_runtime_put(d->dev); |
@@ -1512,7 +1516,7 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie) | |||
1512 | d->target_bias_level == SND_SOC_BIAS_ON) { | 1516 | d->target_bias_level == SND_SOC_BIAS_ON) { |
1513 | ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_ON); | 1517 | ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_ON); |
1514 | if (ret != 0) | 1518 | if (ret != 0) |
1515 | dev_err(d->dev, "Failed to apply active bias: %d\n", | 1519 | dev_err(d->dev, "ASoC: Failed to apply active bias: %d\n", |
1516 | ret); | 1520 | ret); |
1517 | } | 1521 | } |
1518 | } | 1522 | } |
@@ -1838,7 +1842,7 @@ void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm, | |||
1838 | 1842 | ||
1839 | if (!dapm->debugfs_dapm) { | 1843 | if (!dapm->debugfs_dapm) { |
1840 | dev_warn(dapm->dev, | 1844 | dev_warn(dapm->dev, |
1841 | "Failed to create DAPM debugfs directory\n"); | 1845 | "ASoC: Failed to create DAPM debugfs directory\n"); |
1842 | return; | 1846 | return; |
1843 | } | 1847 | } |
1844 | 1848 | ||
@@ -2123,7 +2127,7 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, | |||
2123 | struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); | 2127 | struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); |
2124 | 2128 | ||
2125 | if (!w) { | 2129 | if (!w) { |
2126 | dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); | 2130 | dev_err(dapm->dev, "ASoC: DAPM unknown pin %s\n", pin); |
2127 | return -EINVAL; | 2131 | return -EINVAL; |
2128 | } | 2132 | } |
2129 | 2133 | ||
@@ -2212,8 +2216,16 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, | |||
2212 | if (!wsource) | 2216 | if (!wsource) |
2213 | wsource = wtsource; | 2217 | wsource = wtsource; |
2214 | 2218 | ||
2215 | if (wsource == NULL || wsink == NULL) | 2219 | if (wsource == NULL) { |
2220 | dev_err(dapm->dev, "ASoC: no source widget found for %s\n", | ||
2221 | route->source); | ||
2216 | return -ENODEV; | 2222 | return -ENODEV; |
2223 | } | ||
2224 | if (wsink == NULL) { | ||
2225 | dev_err(dapm->dev, "ASoC: no sink widget found for %s\n", | ||
2226 | route->sink); | ||
2227 | return -ENODEV; | ||
2228 | } | ||
2217 | 2229 | ||
2218 | path = kzalloc(sizeof(struct snd_soc_dapm_path), GFP_KERNEL); | 2230 | path = kzalloc(sizeof(struct snd_soc_dapm_path), GFP_KERNEL); |
2219 | if (!path) | 2231 | if (!path) |
@@ -2308,7 +2320,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, | |||
2308 | return 0; | 2320 | return 0; |
2309 | 2321 | ||
2310 | err: | 2322 | err: |
2311 | dev_warn(dapm->dev, "asoc: no dapm match for %s --> %s --> %s\n", | 2323 | dev_warn(dapm->dev, "ASoC: no dapm match for %s --> %s --> %s\n", |
2312 | source, control, sink); | 2324 | source, control, sink); |
2313 | kfree(path); | 2325 | kfree(path); |
2314 | return ret; | 2326 | return ret; |
@@ -2325,7 +2337,7 @@ static int snd_soc_dapm_del_route(struct snd_soc_dapm_context *dapm, | |||
2325 | 2337 | ||
2326 | if (route->control) { | 2338 | if (route->control) { |
2327 | dev_err(dapm->dev, | 2339 | dev_err(dapm->dev, |
2328 | "Removal of routes with controls not supported\n"); | 2340 | "ASoC: Removal of routes with controls not supported\n"); |
2329 | return -EINVAL; | 2341 | return -EINVAL; |
2330 | } | 2342 | } |
2331 | 2343 | ||
@@ -2360,7 +2372,7 @@ static int snd_soc_dapm_del_route(struct snd_soc_dapm_context *dapm, | |||
2360 | list_del(&path->list_source); | 2372 | list_del(&path->list_source); |
2361 | kfree(path); | 2373 | kfree(path); |
2362 | } else { | 2374 | } else { |
2363 | dev_warn(dapm->dev, "Route %s->%s does not exist\n", | 2375 | dev_warn(dapm->dev, "ASoC: Route %s->%s does not exist\n", |
2364 | source, sink); | 2376 | source, sink); |
2365 | } | 2377 | } |
2366 | 2378 | ||
@@ -2389,8 +2401,10 @@ int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, | |||
2389 | for (i = 0; i < num; i++) { | 2401 | for (i = 0; i < num; i++) { |
2390 | r = snd_soc_dapm_add_route(dapm, route); | 2402 | r = snd_soc_dapm_add_route(dapm, route); |
2391 | if (r < 0) { | 2403 | if (r < 0) { |
2392 | dev_err(dapm->dev, "Failed to add route %s->%s\n", | 2404 | dev_err(dapm->dev, "ASoC: Failed to add route %s -> %s -> %s\n", |
2393 | route->source, route->sink); | 2405 | route->source, |
2406 | route->control ? route->control : "direct", | ||
2407 | route->sink); | ||
2394 | ret = r; | 2408 | ret = r; |
2395 | } | 2409 | } |
2396 | route++; | 2410 | route++; |
@@ -2438,19 +2452,19 @@ static int snd_soc_dapm_weak_route(struct snd_soc_dapm_context *dapm, | |||
2438 | int count = 0; | 2452 | int count = 0; |
2439 | 2453 | ||
2440 | if (!source) { | 2454 | if (!source) { |
2441 | dev_err(dapm->dev, "Unable to find source %s for weak route\n", | 2455 | dev_err(dapm->dev, "ASoC: Unable to find source %s for weak route\n", |
2442 | route->source); | 2456 | route->source); |
2443 | return -ENODEV; | 2457 | return -ENODEV; |
2444 | } | 2458 | } |
2445 | 2459 | ||
2446 | if (!sink) { | 2460 | if (!sink) { |
2447 | dev_err(dapm->dev, "Unable to find sink %s for weak route\n", | 2461 | dev_err(dapm->dev, "ASoC: Unable to find sink %s for weak route\n", |
2448 | route->sink); | 2462 | route->sink); |
2449 | return -ENODEV; | 2463 | return -ENODEV; |
2450 | } | 2464 | } |
2451 | 2465 | ||
2452 | if (route->control || route->connected) | 2466 | if (route->control || route->connected) |
2453 | dev_warn(dapm->dev, "Ignoring control for weak route %s->%s\n", | 2467 | dev_warn(dapm->dev, "ASoC: Ignoring control for weak route %s->%s\n", |
2454 | route->source, route->sink); | 2468 | route->source, route->sink); |
2455 | 2469 | ||
2456 | list_for_each_entry(path, &source->sinks, list_source) { | 2470 | list_for_each_entry(path, &source->sinks, list_source) { |
@@ -2461,10 +2475,10 @@ static int snd_soc_dapm_weak_route(struct snd_soc_dapm_context *dapm, | |||
2461 | } | 2475 | } |
2462 | 2476 | ||
2463 | if (count == 0) | 2477 | if (count == 0) |
2464 | dev_err(dapm->dev, "No path found for weak route %s->%s\n", | 2478 | dev_err(dapm->dev, "ASoC: No path found for weak route %s->%s\n", |
2465 | route->source, route->sink); | 2479 | route->source, route->sink); |
2466 | if (count > 1) | 2480 | if (count > 1) |
2467 | dev_warn(dapm->dev, "%d paths found for weak route %s->%s\n", | 2481 | dev_warn(dapm->dev, "ASoC: %d paths found for weak route %s->%s\n", |
2468 | count, route->source, route->sink); | 2482 | count, route->source, route->sink); |
2469 | 2483 | ||
2470 | return 0; | 2484 | return 0; |
@@ -2601,7 +2615,7 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, | |||
2601 | 2615 | ||
2602 | if (snd_soc_volsw_is_stereo(mc)) | 2616 | if (snd_soc_volsw_is_stereo(mc)) |
2603 | dev_warn(widget->dapm->dev, | 2617 | dev_warn(widget->dapm->dev, |
2604 | "Control '%s' is stereo, which is not supported\n", | 2618 | "ASoC: Control '%s' is stereo, which is not supported\n", |
2605 | kcontrol->id.name); | 2619 | kcontrol->id.name); |
2606 | 2620 | ||
2607 | ucontrol->value.integer.value[0] = | 2621 | ucontrol->value.integer.value[0] = |
@@ -2644,7 +2658,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, | |||
2644 | 2658 | ||
2645 | if (snd_soc_volsw_is_stereo(mc)) | 2659 | if (snd_soc_volsw_is_stereo(mc)) |
2646 | dev_warn(widget->dapm->dev, | 2660 | dev_warn(widget->dapm->dev, |
2647 | "Control '%s' is stereo, which is not supported\n", | 2661 | "ASoC: Control '%s' is stereo, which is not supported\n", |
2648 | kcontrol->id.name); | 2662 | kcontrol->id.name); |
2649 | 2663 | ||
2650 | val = (ucontrol->value.integer.value[0] & mask); | 2664 | val = (ucontrol->value.integer.value[0] & mask); |
@@ -3021,7 +3035,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, | |||
3021 | w->regulator = devm_regulator_get(dapm->dev, w->name); | 3035 | w->regulator = devm_regulator_get(dapm->dev, w->name); |
3022 | if (IS_ERR(w->regulator)) { | 3036 | if (IS_ERR(w->regulator)) { |
3023 | ret = PTR_ERR(w->regulator); | 3037 | ret = PTR_ERR(w->regulator); |
3024 | dev_err(dapm->dev, "Failed to request %s: %d\n", | 3038 | dev_err(dapm->dev, "ASoC: Failed to request %s: %d\n", |
3025 | w->name, ret); | 3039 | w->name, ret); |
3026 | return NULL; | 3040 | return NULL; |
3027 | } | 3041 | } |
@@ -3031,7 +3045,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, | |||
3031 | w->clk = devm_clk_get(dapm->dev, w->name); | 3045 | w->clk = devm_clk_get(dapm->dev, w->name); |
3032 | if (IS_ERR(w->clk)) { | 3046 | if (IS_ERR(w->clk)) { |
3033 | ret = PTR_ERR(w->clk); | 3047 | ret = PTR_ERR(w->clk); |
3034 | dev_err(dapm->dev, "Failed to request %s: %d\n", | 3048 | dev_err(dapm->dev, "ASoC: Failed to request %s: %d\n", |
3035 | w->name, ret); | 3049 | w->name, ret); |
3036 | return NULL; | 3050 | return NULL; |
3037 | } | 3051 | } |
@@ -3182,7 +3196,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w, | |||
3182 | if (config->formats) { | 3196 | if (config->formats) { |
3183 | fmt = ffs(config->formats) - 1; | 3197 | fmt = ffs(config->formats) - 1; |
3184 | } else { | 3198 | } else { |
3185 | dev_warn(w->dapm->dev, "Invalid format %llx specified\n", | 3199 | dev_warn(w->dapm->dev, "ASoC: Invalid format %llx specified\n", |
3186 | config->formats); | 3200 | config->formats); |
3187 | fmt = 0; | 3201 | fmt = 0; |
3188 | } | 3202 | } |
@@ -3215,7 +3229,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w, | |||
3215 | params, source); | 3229 | params, source); |
3216 | if (ret != 0) { | 3230 | if (ret != 0) { |
3217 | dev_err(source->dev, | 3231 | dev_err(source->dev, |
3218 | "hw_params() failed: %d\n", ret); | 3232 | "ASoC: hw_params() failed: %d\n", ret); |
3219 | goto out; | 3233 | goto out; |
3220 | } | 3234 | } |
3221 | } | 3235 | } |
@@ -3226,7 +3240,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w, | |||
3226 | sink); | 3240 | sink); |
3227 | if (ret != 0) { | 3241 | if (ret != 0) { |
3228 | dev_err(sink->dev, | 3242 | dev_err(sink->dev, |
3229 | "hw_params() failed: %d\n", ret); | 3243 | "ASoC: hw_params() failed: %d\n", ret); |
3230 | goto out; | 3244 | goto out; |
3231 | } | 3245 | } |
3232 | } | 3246 | } |
@@ -3235,14 +3249,14 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w, | |||
3235 | case SND_SOC_DAPM_POST_PMU: | 3249 | case SND_SOC_DAPM_POST_PMU: |
3236 | ret = snd_soc_dai_digital_mute(sink, 0); | 3250 | ret = snd_soc_dai_digital_mute(sink, 0); |
3237 | if (ret != 0 && ret != -ENOTSUPP) | 3251 | if (ret != 0 && ret != -ENOTSUPP) |
3238 | dev_warn(sink->dev, "Failed to unmute: %d\n", ret); | 3252 | dev_warn(sink->dev, "ASoC: Failed to unmute: %d\n", ret); |
3239 | ret = 0; | 3253 | ret = 0; |
3240 | break; | 3254 | break; |
3241 | 3255 | ||
3242 | case SND_SOC_DAPM_PRE_PMD: | 3256 | case SND_SOC_DAPM_PRE_PMD: |
3243 | ret = snd_soc_dai_digital_mute(sink, 1); | 3257 | ret = snd_soc_dai_digital_mute(sink, 1); |
3244 | if (ret != 0 && ret != -ENOTSUPP) | 3258 | if (ret != 0 && ret != -ENOTSUPP) |
3245 | dev_warn(sink->dev, "Failed to mute: %d\n", ret); | 3259 | dev_warn(sink->dev, "ASoC: Failed to mute: %d\n", ret); |
3246 | ret = 0; | 3260 | ret = 0; |
3247 | break; | 3261 | break; |
3248 | 3262 | ||
@@ -3281,11 +3295,11 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card, | |||
3281 | template.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | 3295 | template.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | |
3282 | SND_SOC_DAPM_PRE_PMD; | 3296 | SND_SOC_DAPM_PRE_PMD; |
3283 | 3297 | ||
3284 | dev_dbg(card->dev, "adding %s widget\n", link_name); | 3298 | dev_dbg(card->dev, "ASoC: adding %s widget\n", link_name); |
3285 | 3299 | ||
3286 | w = snd_soc_dapm_new_control(&card->dapm, &template); | 3300 | w = snd_soc_dapm_new_control(&card->dapm, &template); |
3287 | if (!w) { | 3301 | if (!w) { |
3288 | dev_err(card->dev, "Failed to create %s widget\n", | 3302 | dev_err(card->dev, "ASoC: Failed to create %s widget\n", |
3289 | link_name); | 3303 | link_name); |
3290 | return -ENOMEM; | 3304 | return -ENOMEM; |
3291 | } | 3305 | } |
@@ -3319,12 +3333,12 @@ int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, | |||
3319 | template.name = dai->driver->playback.stream_name; | 3333 | template.name = dai->driver->playback.stream_name; |
3320 | template.sname = dai->driver->playback.stream_name; | 3334 | template.sname = dai->driver->playback.stream_name; |
3321 | 3335 | ||
3322 | dev_dbg(dai->dev, "adding %s widget\n", | 3336 | dev_dbg(dai->dev, "ASoC: adding %s widget\n", |
3323 | template.name); | 3337 | template.name); |
3324 | 3338 | ||
3325 | w = snd_soc_dapm_new_control(dapm, &template); | 3339 | w = snd_soc_dapm_new_control(dapm, &template); |
3326 | if (!w) { | 3340 | if (!w) { |
3327 | dev_err(dapm->dev, "Failed to create %s widget\n", | 3341 | dev_err(dapm->dev, "ASoC: Failed to create %s widget\n", |
3328 | dai->driver->playback.stream_name); | 3342 | dai->driver->playback.stream_name); |
3329 | } | 3343 | } |
3330 | 3344 | ||
@@ -3337,12 +3351,12 @@ int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, | |||
3337 | template.name = dai->driver->capture.stream_name; | 3351 | template.name = dai->driver->capture.stream_name; |
3338 | template.sname = dai->driver->capture.stream_name; | 3352 | template.sname = dai->driver->capture.stream_name; |
3339 | 3353 | ||
3340 | dev_dbg(dai->dev, "adding %s widget\n", | 3354 | dev_dbg(dai->dev, "ASoC: adding %s widget\n", |
3341 | template.name); | 3355 | template.name); |
3342 | 3356 | ||
3343 | w = snd_soc_dapm_new_control(dapm, &template); | 3357 | w = snd_soc_dapm_new_control(dapm, &template); |
3344 | if (!w) { | 3358 | if (!w) { |
3345 | dev_err(dapm->dev, "Failed to create %s widget\n", | 3359 | dev_err(dapm->dev, "ASoC: Failed to create %s widget\n", |
3346 | dai->driver->capture.stream_name); | 3360 | dai->driver->capture.stream_name); |
3347 | } | 3361 | } |
3348 | 3362 | ||
@@ -3518,11 +3532,11 @@ int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, | |||
3518 | struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); | 3532 | struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); |
3519 | 3533 | ||
3520 | if (!w) { | 3534 | if (!w) { |
3521 | dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); | 3535 | dev_err(dapm->dev, "ASoC: unknown pin %s\n", pin); |
3522 | return -EINVAL; | 3536 | return -EINVAL; |
3523 | } | 3537 | } |
3524 | 3538 | ||
3525 | dev_dbg(w->dapm->dev, "dapm: force enable pin %s\n", pin); | 3539 | dev_dbg(w->dapm->dev, "ASoC: force enable pin %s\n", pin); |
3526 | w->connected = 1; | 3540 | w->connected = 1; |
3527 | w->force = 1; | 3541 | w->force = 1; |
3528 | dapm_mark_dirty(w, "force enable"); | 3542 | dapm_mark_dirty(w, "force enable"); |
@@ -3605,7 +3619,7 @@ int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, | |||
3605 | struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, false); | 3619 | struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, false); |
3606 | 3620 | ||
3607 | if (!w) { | 3621 | if (!w) { |
3608 | dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); | 3622 | dev_err(dapm->dev, "ASoC: unknown pin %s\n", pin); |
3609 | return -EINVAL; | 3623 | return -EINVAL; |
3610 | } | 3624 | } |
3611 | 3625 | ||
@@ -3664,7 +3678,7 @@ void snd_soc_dapm_auto_nc_codec_pins(struct snd_soc_codec *codec) | |||
3664 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 3678 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
3665 | struct snd_soc_dapm_widget *w; | 3679 | struct snd_soc_dapm_widget *w; |
3666 | 3680 | ||
3667 | dev_dbg(codec->dev, "Auto NC: DAPMs: card:%p codec:%p\n", | 3681 | dev_dbg(codec->dev, "ASoC: Auto NC: DAPMs: card:%p codec:%p\n", |
3668 | &card->dapm, &codec->dapm); | 3682 | &card->dapm, &codec->dapm); |
3669 | 3683 | ||
3670 | list_for_each_entry(w, &card->widgets, list) { | 3684 | list_for_each_entry(w, &card->widgets, list) { |
@@ -3674,7 +3688,7 @@ void snd_soc_dapm_auto_nc_codec_pins(struct snd_soc_codec *codec) | |||
3674 | case snd_soc_dapm_input: | 3688 | case snd_soc_dapm_input: |
3675 | case snd_soc_dapm_output: | 3689 | case snd_soc_dapm_output: |
3676 | case snd_soc_dapm_micbias: | 3690 | case snd_soc_dapm_micbias: |
3677 | dev_dbg(codec->dev, "Auto NC: Checking widget %s\n", | 3691 | dev_dbg(codec->dev, "ASoC: Auto NC: Checking widget %s\n", |
3678 | w->name); | 3692 | w->name); |
3679 | if (!snd_soc_dapm_widget_in_card_paths(card, w)) { | 3693 | if (!snd_soc_dapm_widget_in_card_paths(card, w)) { |
3680 | dev_dbg(codec->dev, | 3694 | dev_dbg(codec->dev, |
diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c index bbc125748a38..111b7d921e89 100644 --- a/sound/soc/soc-dmaengine-pcm.c +++ b/sound/soc/soc-dmaengine-pcm.c | |||
@@ -317,3 +317,5 @@ int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream) | |||
317 | return 0; | 317 | return 0; |
318 | } | 318 | } |
319 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close); | 319 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close); |
320 | |||
321 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index 1ab5fe04bfcc..0bb5cccd7766 100644 --- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c | |||
@@ -66,7 +66,6 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) | |||
66 | struct snd_soc_dapm_context *dapm; | 66 | struct snd_soc_dapm_context *dapm; |
67 | struct snd_soc_jack_pin *pin; | 67 | struct snd_soc_jack_pin *pin; |
68 | int enable; | 68 | int enable; |
69 | int oldstatus; | ||
70 | 69 | ||
71 | trace_snd_soc_jack_report(jack, mask, status); | 70 | trace_snd_soc_jack_report(jack, mask, status); |
72 | 71 | ||
@@ -78,8 +77,6 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) | |||
78 | 77 | ||
79 | mutex_lock(&jack->mutex); | 78 | mutex_lock(&jack->mutex); |
80 | 79 | ||
81 | oldstatus = jack->status; | ||
82 | |||
83 | jack->status &= ~mask; | 80 | jack->status &= ~mask; |
84 | jack->status |= status & mask; | 81 | jack->status |= status & mask; |
85 | 82 | ||
@@ -172,12 +169,13 @@ int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count, | |||
172 | 169 | ||
173 | for (i = 0; i < count; i++) { | 170 | for (i = 0; i < count; i++) { |
174 | if (!pins[i].pin) { | 171 | if (!pins[i].pin) { |
175 | printk(KERN_ERR "No name for pin %d\n", i); | 172 | dev_err(jack->codec->dev, "ASoC: No name for pin %d\n", |
173 | i); | ||
176 | return -EINVAL; | 174 | return -EINVAL; |
177 | } | 175 | } |
178 | if (!pins[i].mask) { | 176 | if (!pins[i].mask) { |
179 | printk(KERN_ERR "No mask for pin %d (%s)\n", i, | 177 | dev_err(jack->codec->dev, "ASoC: No mask for pin %d" |
180 | pins[i].pin); | 178 | " (%s)\n", i, pins[i].pin); |
181 | return -EINVAL; | 179 | return -EINVAL; |
182 | } | 180 | } |
183 | 181 | ||
@@ -297,13 +295,13 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, | |||
297 | 295 | ||
298 | for (i = 0; i < count; i++) { | 296 | for (i = 0; i < count; i++) { |
299 | if (!gpio_is_valid(gpios[i].gpio)) { | 297 | if (!gpio_is_valid(gpios[i].gpio)) { |
300 | printk(KERN_ERR "Invalid gpio %d\n", | 298 | dev_err(jack->codec->dev, "ASoC: Invalid gpio %d\n", |
301 | gpios[i].gpio); | 299 | gpios[i].gpio); |
302 | ret = -EINVAL; | 300 | ret = -EINVAL; |
303 | goto undo; | 301 | goto undo; |
304 | } | 302 | } |
305 | if (!gpios[i].name) { | 303 | if (!gpios[i].name) { |
306 | printk(KERN_ERR "No name for gpio %d\n", | 304 | dev_err(jack->codec->dev, "ASoC: No name for gpio %d\n", |
307 | gpios[i].gpio); | 305 | gpios[i].gpio); |
308 | ret = -EINVAL; | 306 | ret = -EINVAL; |
309 | goto undo; | 307 | goto undo; |
@@ -332,7 +330,7 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, | |||
332 | if (gpios[i].wake) { | 330 | if (gpios[i].wake) { |
333 | ret = irq_set_irq_wake(gpio_to_irq(gpios[i].gpio), 1); | 331 | ret = irq_set_irq_wake(gpio_to_irq(gpios[i].gpio), 1); |
334 | if (ret != 0) | 332 | if (ret != 0) |
335 | printk(KERN_ERR | 333 | dev_err(jack->codec->dev, "ASoC: " |
336 | "Failed to mark GPIO %d as wake source: %d\n", | 334 | "Failed to mark GPIO %d as wake source: %d\n", |
337 | gpios[i].gpio, ret); | 335 | gpios[i].gpio, ret); |
338 | } | 336 | } |
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index ef22d0bd9e9e..5c3ca2a34661 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c | |||
@@ -43,7 +43,7 @@ static int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir, | |||
43 | 43 | ||
44 | struct snd_soc_pcm_runtime *be = dpcm->be; | 44 | struct snd_soc_pcm_runtime *be = dpcm->be; |
45 | 45 | ||
46 | dev_dbg(be->dev, "pm: BE %s event %d dir %d\n", | 46 | dev_dbg(be->dev, "ASoC: BE %s event %d dir %d\n", |
47 | be->dai_link->name, event, dir); | 47 | be->dai_link->name, event, dir); |
48 | 48 | ||
49 | snd_soc_dapm_stream_event(be, dir, event); | 49 | snd_soc_dapm_stream_event(be, dir, event); |
@@ -70,18 +70,19 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream, | |||
70 | */ | 70 | */ |
71 | if (!soc_dai->rate) { | 71 | if (!soc_dai->rate) { |
72 | dev_warn(soc_dai->dev, | 72 | dev_warn(soc_dai->dev, |
73 | "Not enforcing symmetric_rates due to race\n"); | 73 | "ASoC: Not enforcing symmetric_rates due to race\n"); |
74 | return 0; | 74 | return 0; |
75 | } | 75 | } |
76 | 76 | ||
77 | dev_dbg(soc_dai->dev, "Symmetry forces %dHz rate\n", soc_dai->rate); | 77 | dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %dHz rate\n", soc_dai->rate); |
78 | 78 | ||
79 | ret = snd_pcm_hw_constraint_minmax(substream->runtime, | 79 | ret = snd_pcm_hw_constraint_minmax(substream->runtime, |
80 | SNDRV_PCM_HW_PARAM_RATE, | 80 | SNDRV_PCM_HW_PARAM_RATE, |
81 | soc_dai->rate, soc_dai->rate); | 81 | soc_dai->rate, soc_dai->rate); |
82 | if (ret < 0) { | 82 | if (ret < 0) { |
83 | dev_err(soc_dai->dev, | 83 | dev_err(soc_dai->dev, |
84 | "Unable to apply rate symmetry constraint: %d\n", ret); | 84 | "ASoC: Unable to apply rate symmetry constraint: %d\n", |
85 | ret); | ||
85 | return ret; | 86 | return ret; |
86 | } | 87 | } |
87 | 88 | ||
@@ -118,7 +119,7 @@ static void soc_pcm_apply_msb(struct snd_pcm_substream *substream, | |||
118 | sample_sizes[i], bits); | 119 | sample_sizes[i], bits); |
119 | if (ret != 0) | 120 | if (ret != 0) |
120 | dev_warn(dai->dev, | 121 | dev_warn(dai->dev, |
121 | "Failed to set MSB %d/%d: %d\n", | 122 | "ASoC: Failed to set MSB %d/%d: %d\n", |
122 | bits, sample_sizes[i], ret); | 123 | bits, sample_sizes[i], ret); |
123 | } | 124 | } |
124 | } | 125 | } |
@@ -149,8 +150,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) | |||
149 | if (cpu_dai->driver->ops->startup) { | 150 | if (cpu_dai->driver->ops->startup) { |
150 | ret = cpu_dai->driver->ops->startup(substream, cpu_dai); | 151 | ret = cpu_dai->driver->ops->startup(substream, cpu_dai); |
151 | if (ret < 0) { | 152 | if (ret < 0) { |
152 | dev_err(cpu_dai->dev, "can't open interface %s: %d\n", | 153 | dev_err(cpu_dai->dev, "ASoC: can't open interface" |
153 | cpu_dai->name, ret); | 154 | " %s: %d\n", cpu_dai->name, ret); |
154 | goto out; | 155 | goto out; |
155 | } | 156 | } |
156 | } | 157 | } |
@@ -158,8 +159,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) | |||
158 | if (platform->driver->ops && platform->driver->ops->open) { | 159 | if (platform->driver->ops && platform->driver->ops->open) { |
159 | ret = platform->driver->ops->open(substream); | 160 | ret = platform->driver->ops->open(substream); |
160 | if (ret < 0) { | 161 | if (ret < 0) { |
161 | dev_err(platform->dev, "can't open platform %s: %d\n", | 162 | dev_err(platform->dev, "ASoC: can't open platform" |
162 | platform->name, ret); | 163 | " %s: %d\n", platform->name, ret); |
163 | goto platform_err; | 164 | goto platform_err; |
164 | } | 165 | } |
165 | } | 166 | } |
@@ -167,8 +168,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) | |||
167 | if (codec_dai->driver->ops->startup) { | 168 | if (codec_dai->driver->ops->startup) { |
168 | ret = codec_dai->driver->ops->startup(substream, codec_dai); | 169 | ret = codec_dai->driver->ops->startup(substream, codec_dai); |
169 | if (ret < 0) { | 170 | if (ret < 0) { |
170 | dev_err(codec_dai->dev, "can't open codec %s: %d\n", | 171 | dev_err(codec_dai->dev, "ASoC: can't open codec" |
171 | codec_dai->name, ret); | 172 | " %s: %d\n", codec_dai->name, ret); |
172 | goto codec_dai_err; | 173 | goto codec_dai_err; |
173 | } | 174 | } |
174 | } | 175 | } |
@@ -176,7 +177,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) | |||
176 | if (rtd->dai_link->ops && rtd->dai_link->ops->startup) { | 177 | if (rtd->dai_link->ops && rtd->dai_link->ops->startup) { |
177 | ret = rtd->dai_link->ops->startup(substream); | 178 | ret = rtd->dai_link->ops->startup(substream); |
178 | if (ret < 0) { | 179 | if (ret < 0) { |
179 | pr_err("asoc: %s startup failed: %d\n", | 180 | pr_err("ASoC: %s startup failed: %d\n", |
180 | rtd->dai_link->name, ret); | 181 | rtd->dai_link->name, ret); |
181 | goto machine_err; | 182 | goto machine_err; |
182 | } | 183 | } |
@@ -238,18 +239,18 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) | |||
238 | ret = -EINVAL; | 239 | ret = -EINVAL; |
239 | snd_pcm_limit_hw_rates(runtime); | 240 | snd_pcm_limit_hw_rates(runtime); |
240 | if (!runtime->hw.rates) { | 241 | if (!runtime->hw.rates) { |
241 | printk(KERN_ERR "asoc: %s <-> %s No matching rates\n", | 242 | printk(KERN_ERR "ASoC: %s <-> %s No matching rates\n", |
242 | codec_dai->name, cpu_dai->name); | 243 | codec_dai->name, cpu_dai->name); |
243 | goto config_err; | 244 | goto config_err; |
244 | } | 245 | } |
245 | if (!runtime->hw.formats) { | 246 | if (!runtime->hw.formats) { |
246 | printk(KERN_ERR "asoc: %s <-> %s No matching formats\n", | 247 | printk(KERN_ERR "ASoC: %s <-> %s No matching formats\n", |
247 | codec_dai->name, cpu_dai->name); | 248 | codec_dai->name, cpu_dai->name); |
248 | goto config_err; | 249 | goto config_err; |
249 | } | 250 | } |
250 | if (!runtime->hw.channels_min || !runtime->hw.channels_max || | 251 | if (!runtime->hw.channels_min || !runtime->hw.channels_max || |
251 | runtime->hw.channels_min > runtime->hw.channels_max) { | 252 | runtime->hw.channels_min > runtime->hw.channels_max) { |
252 | printk(KERN_ERR "asoc: %s <-> %s No matching channels\n", | 253 | printk(KERN_ERR "ASoC: %s <-> %s No matching channels\n", |
253 | codec_dai->name, cpu_dai->name); | 254 | codec_dai->name, cpu_dai->name); |
254 | goto config_err; | 255 | goto config_err; |
255 | } | 256 | } |
@@ -270,12 +271,12 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) | |||
270 | goto config_err; | 271 | goto config_err; |
271 | } | 272 | } |
272 | 273 | ||
273 | pr_debug("asoc: %s <-> %s info:\n", | 274 | pr_debug("ASoC: %s <-> %s info:\n", |
274 | codec_dai->name, cpu_dai->name); | 275 | codec_dai->name, cpu_dai->name); |
275 | pr_debug("asoc: rate mask 0x%x\n", runtime->hw.rates); | 276 | pr_debug("ASoC: rate mask 0x%x\n", runtime->hw.rates); |
276 | pr_debug("asoc: min ch %d max ch %d\n", runtime->hw.channels_min, | 277 | pr_debug("ASoC: min ch %d max ch %d\n", runtime->hw.channels_min, |
277 | runtime->hw.channels_max); | 278 | runtime->hw.channels_max); |
278 | pr_debug("asoc: min rate %d max rate %d\n", runtime->hw.rate_min, | 279 | pr_debug("ASoC: min rate %d max rate %d\n", runtime->hw.rate_min, |
279 | runtime->hw.rate_max); | 280 | runtime->hw.rate_max); |
280 | 281 | ||
281 | dynamic: | 282 | dynamic: |
@@ -330,7 +331,7 @@ static void close_delayed_work(struct work_struct *work) | |||
330 | 331 | ||
331 | mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); | 332 | mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); |
332 | 333 | ||
333 | pr_debug("pop wq checking: %s status: %s waiting: %s\n", | 334 | dev_dbg(rtd->dev, "ASoC: pop wq checking: %s status: %s waiting: %s\n", |
334 | codec_dai->driver->playback.stream_name, | 335 | codec_dai->driver->playback.stream_name, |
335 | codec_dai->playback_active ? "active" : "inactive", | 336 | codec_dai->playback_active ? "active" : "inactive", |
336 | codec_dai->pop_wait ? "yes" : "no"); | 337 | codec_dai->pop_wait ? "yes" : "no"); |
@@ -444,7 +445,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) | |||
444 | if (rtd->dai_link->ops && rtd->dai_link->ops->prepare) { | 445 | if (rtd->dai_link->ops && rtd->dai_link->ops->prepare) { |
445 | ret = rtd->dai_link->ops->prepare(substream); | 446 | ret = rtd->dai_link->ops->prepare(substream); |
446 | if (ret < 0) { | 447 | if (ret < 0) { |
447 | pr_err("asoc: machine prepare error: %d\n", ret); | 448 | dev_err(rtd->card->dev, "ASoC: machine prepare error:" |
449 | " %d\n", ret); | ||
448 | goto out; | 450 | goto out; |
449 | } | 451 | } |
450 | } | 452 | } |
@@ -452,8 +454,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) | |||
452 | if (platform->driver->ops && platform->driver->ops->prepare) { | 454 | if (platform->driver->ops && platform->driver->ops->prepare) { |
453 | ret = platform->driver->ops->prepare(substream); | 455 | ret = platform->driver->ops->prepare(substream); |
454 | if (ret < 0) { | 456 | if (ret < 0) { |
455 | dev_err(platform->dev, "platform prepare error: %d\n", | 457 | dev_err(platform->dev, "ASoC: platform prepare error:" |
456 | ret); | 458 | " %d\n", ret); |
457 | goto out; | 459 | goto out; |
458 | } | 460 | } |
459 | } | 461 | } |
@@ -461,7 +463,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) | |||
461 | if (codec_dai->driver->ops->prepare) { | 463 | if (codec_dai->driver->ops->prepare) { |
462 | ret = codec_dai->driver->ops->prepare(substream, codec_dai); | 464 | ret = codec_dai->driver->ops->prepare(substream, codec_dai); |
463 | if (ret < 0) { | 465 | if (ret < 0) { |
464 | dev_err(codec_dai->dev, "DAI prepare error: %d\n", | 466 | dev_err(codec_dai->dev, "ASoC: DAI prepare error: %d\n", |
465 | ret); | 467 | ret); |
466 | goto out; | 468 | goto out; |
467 | } | 469 | } |
@@ -470,7 +472,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) | |||
470 | if (cpu_dai->driver->ops->prepare) { | 472 | if (cpu_dai->driver->ops->prepare) { |
471 | ret = cpu_dai->driver->ops->prepare(substream, cpu_dai); | 473 | ret = cpu_dai->driver->ops->prepare(substream, cpu_dai); |
472 | if (ret < 0) { | 474 | if (ret < 0) { |
473 | dev_err(cpu_dai->dev, "DAI prepare error: %d\n", | 475 | dev_err(cpu_dai->dev, "ASoC: DAI prepare error: %d\n", |
474 | ret); | 476 | ret); |
475 | goto out; | 477 | goto out; |
476 | } | 478 | } |
@@ -512,7 +514,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, | |||
512 | if (rtd->dai_link->ops && rtd->dai_link->ops->hw_params) { | 514 | if (rtd->dai_link->ops && rtd->dai_link->ops->hw_params) { |
513 | ret = rtd->dai_link->ops->hw_params(substream, params); | 515 | ret = rtd->dai_link->ops->hw_params(substream, params); |
514 | if (ret < 0) { | 516 | if (ret < 0) { |
515 | pr_err("asoc: machine hw_params failed: %d\n", ret); | 517 | dev_err(rtd->card->dev, "ASoC: machine hw_params" |
518 | " failed: %d\n", ret); | ||
516 | goto out; | 519 | goto out; |
517 | } | 520 | } |
518 | } | 521 | } |
@@ -520,8 +523,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, | |||
520 | if (codec_dai->driver->ops->hw_params) { | 523 | if (codec_dai->driver->ops->hw_params) { |
521 | ret = codec_dai->driver->ops->hw_params(substream, params, codec_dai); | 524 | ret = codec_dai->driver->ops->hw_params(substream, params, codec_dai); |
522 | if (ret < 0) { | 525 | if (ret < 0) { |
523 | dev_err(codec_dai->dev, "can't set %s hw params: %d\n", | 526 | dev_err(codec_dai->dev, "ASoC: can't set %s hw params:" |
524 | codec_dai->name, ret); | 527 | " %d\n", codec_dai->name, ret); |
525 | goto codec_err; | 528 | goto codec_err; |
526 | } | 529 | } |
527 | } | 530 | } |
@@ -529,7 +532,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, | |||
529 | if (cpu_dai->driver->ops->hw_params) { | 532 | if (cpu_dai->driver->ops->hw_params) { |
530 | ret = cpu_dai->driver->ops->hw_params(substream, params, cpu_dai); | 533 | ret = cpu_dai->driver->ops->hw_params(substream, params, cpu_dai); |
531 | if (ret < 0) { | 534 | if (ret < 0) { |
532 | dev_err(cpu_dai->dev, "%s hw params failed: %d\n", | 535 | dev_err(cpu_dai->dev, "ASoC: %s hw params failed: %d\n", |
533 | cpu_dai->name, ret); | 536 | cpu_dai->name, ret); |
534 | goto interface_err; | 537 | goto interface_err; |
535 | } | 538 | } |
@@ -538,7 +541,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, | |||
538 | if (platform->driver->ops && platform->driver->ops->hw_params) { | 541 | if (platform->driver->ops && platform->driver->ops->hw_params) { |
539 | ret = platform->driver->ops->hw_params(substream, params); | 542 | ret = platform->driver->ops->hw_params(substream, params); |
540 | if (ret < 0) { | 543 | if (ret < 0) { |
541 | dev_err(platform->dev, "%s hw params failed: %d\n", | 544 | dev_err(platform->dev, "ASoC: %s hw params failed: %d\n", |
542 | platform->name, ret); | 545 | platform->name, ret); |
543 | goto platform_err; | 546 | goto platform_err; |
544 | } | 547 | } |
@@ -760,7 +763,7 @@ static void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream) | |||
760 | struct snd_soc_dpcm *dpcm, *d; | 763 | struct snd_soc_dpcm *dpcm, *d; |
761 | 764 | ||
762 | list_for_each_entry_safe(dpcm, d, &fe->dpcm[stream].be_clients, list_be) { | 765 | list_for_each_entry_safe(dpcm, d, &fe->dpcm[stream].be_clients, list_be) { |
763 | dev_dbg(fe->dev, "BE %s disconnect check for %s\n", | 766 | dev_dbg(fe->dev, "ASoC: BE %s disconnect check for %s\n", |
764 | stream ? "capture" : "playback", | 767 | stream ? "capture" : "playback", |
765 | dpcm->be->dai_link->name); | 768 | dpcm->be->dai_link->name); |
766 | 769 | ||
@@ -815,7 +818,7 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card, | |||
815 | } | 818 | } |
816 | } | 819 | } |
817 | 820 | ||
818 | dev_err(card->dev, "can't get %s BE for %s\n", | 821 | dev_err(card->dev, "ASoC: can't get %s BE for %s\n", |
819 | stream ? "capture" : "playback", widget->name); | 822 | stream ? "capture" : "playback", widget->name); |
820 | return NULL; | 823 | return NULL; |
821 | } | 824 | } |
@@ -866,7 +869,7 @@ static int dpcm_path_get(struct snd_soc_pcm_runtime *fe, | |||
866 | /* get number of valid DAI paths and their widgets */ | 869 | /* get number of valid DAI paths and their widgets */ |
867 | paths = snd_soc_dapm_dai_get_connected_widgets(cpu_dai, stream, &list); | 870 | paths = snd_soc_dapm_dai_get_connected_widgets(cpu_dai, stream, &list); |
868 | 871 | ||
869 | dev_dbg(fe->dev, "found %d audio %s paths\n", paths, | 872 | dev_dbg(fe->dev, "ASoC: found %d audio %s paths\n", paths, |
870 | stream ? "capture" : "playback"); | 873 | stream ? "capture" : "playback"); |
871 | 874 | ||
872 | *list_ = list; | 875 | *list_ = list; |
@@ -903,7 +906,7 @@ static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream, | |||
903 | if (widget && widget_in_list(list, widget)) | 906 | if (widget && widget_in_list(list, widget)) |
904 | continue; | 907 | continue; |
905 | 908 | ||
906 | dev_dbg(fe->dev, "pruning %s BE %s for %s\n", | 909 | dev_dbg(fe->dev, "ASoC: pruning %s BE %s for %s\n", |
907 | stream ? "capture" : "playback", | 910 | stream ? "capture" : "playback", |
908 | dpcm->be->dai_link->name, fe->dai_link->name); | 911 | dpcm->be->dai_link->name, fe->dai_link->name); |
909 | dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; | 912 | dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; |
@@ -911,7 +914,7 @@ static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream, | |||
911 | prune++; | 914 | prune++; |
912 | } | 915 | } |
913 | 916 | ||
914 | dev_dbg(fe->dev, "found %d old BE paths for pruning\n", prune); | 917 | dev_dbg(fe->dev, "ASoC: found %d old BE paths for pruning\n", prune); |
915 | return prune; | 918 | return prune; |
916 | } | 919 | } |
917 | 920 | ||
@@ -932,7 +935,7 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream, | |||
932 | /* is there a valid BE rtd for this widget */ | 935 | /* is there a valid BE rtd for this widget */ |
933 | be = dpcm_get_be(card, list->widgets[i], stream); | 936 | be = dpcm_get_be(card, list->widgets[i], stream); |
934 | if (!be) { | 937 | if (!be) { |
935 | dev_err(fe->dev, "no BE found for %s\n", | 938 | dev_err(fe->dev, "ASoC: no BE found for %s\n", |
936 | list->widgets[i]->name); | 939 | list->widgets[i]->name); |
937 | continue; | 940 | continue; |
938 | } | 941 | } |
@@ -948,7 +951,7 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream, | |||
948 | /* newly connected FE and BE */ | 951 | /* newly connected FE and BE */ |
949 | err = dpcm_be_connect(fe, be, stream); | 952 | err = dpcm_be_connect(fe, be, stream); |
950 | if (err < 0) { | 953 | if (err < 0) { |
951 | dev_err(fe->dev, "can't connect %s\n", | 954 | dev_err(fe->dev, "ASoC: can't connect %s\n", |
952 | list->widgets[i]->name); | 955 | list->widgets[i]->name); |
953 | break; | 956 | break; |
954 | } else if (err == 0) /* already connected */ | 957 | } else if (err == 0) /* already connected */ |
@@ -959,7 +962,7 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream, | |||
959 | new++; | 962 | new++; |
960 | } | 963 | } |
961 | 964 | ||
962 | dev_dbg(fe->dev, "found %d new BE paths\n", new); | 965 | dev_dbg(fe->dev, "ASoC: found %d new BE paths\n", new); |
963 | return new; | 966 | return new; |
964 | } | 967 | } |
965 | 968 | ||
@@ -998,7 +1001,7 @@ static void dpcm_be_dai_startup_unwind(struct snd_soc_pcm_runtime *fe, | |||
998 | snd_soc_dpcm_get_substream(be, stream); | 1001 | snd_soc_dpcm_get_substream(be, stream); |
999 | 1002 | ||
1000 | if (be->dpcm[stream].users == 0) | 1003 | if (be->dpcm[stream].users == 0) |
1001 | dev_err(be->dev, "no users %s at close - state %d\n", | 1004 | dev_err(be->dev, "ASoC: no users %s at close - state %d\n", |
1002 | stream ? "capture" : "playback", | 1005 | stream ? "capture" : "playback", |
1003 | be->dpcm[stream].state); | 1006 | be->dpcm[stream].state); |
1004 | 1007 | ||
@@ -1032,7 +1035,7 @@ static int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream) | |||
1032 | 1035 | ||
1033 | /* first time the dpcm is open ? */ | 1036 | /* first time the dpcm is open ? */ |
1034 | if (be->dpcm[stream].users == DPCM_MAX_BE_USERS) | 1037 | if (be->dpcm[stream].users == DPCM_MAX_BE_USERS) |
1035 | dev_err(be->dev, "too many users %s at open %d\n", | 1038 | dev_err(be->dev, "ASoC: too many users %s at open %d\n", |
1036 | stream ? "capture" : "playback", | 1039 | stream ? "capture" : "playback", |
1037 | be->dpcm[stream].state); | 1040 | be->dpcm[stream].state); |
1038 | 1041 | ||
@@ -1043,15 +1046,15 @@ static int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream) | |||
1043 | (be->dpcm[stream].state != SND_SOC_DPCM_STATE_CLOSE)) | 1046 | (be->dpcm[stream].state != SND_SOC_DPCM_STATE_CLOSE)) |
1044 | continue; | 1047 | continue; |
1045 | 1048 | ||
1046 | dev_dbg(be->dev, "dpcm: open BE %s\n", be->dai_link->name); | 1049 | dev_dbg(be->dev, "ASoC: open BE %s\n", be->dai_link->name); |
1047 | 1050 | ||
1048 | be_substream->runtime = be->dpcm[stream].runtime; | 1051 | be_substream->runtime = be->dpcm[stream].runtime; |
1049 | err = soc_pcm_open(be_substream); | 1052 | err = soc_pcm_open(be_substream); |
1050 | if (err < 0) { | 1053 | if (err < 0) { |
1051 | dev_err(be->dev, "BE open failed %d\n", err); | 1054 | dev_err(be->dev, "ASoC: BE open failed %d\n", err); |
1052 | be->dpcm[stream].users--; | 1055 | be->dpcm[stream].users--; |
1053 | if (be->dpcm[stream].users < 0) | 1056 | if (be->dpcm[stream].users < 0) |
1054 | dev_err(be->dev, "no users %s at unwind %d\n", | 1057 | dev_err(be->dev, "ASoC: no users %s at unwind %d\n", |
1055 | stream ? "capture" : "playback", | 1058 | stream ? "capture" : "playback", |
1056 | be->dpcm[stream].state); | 1059 | be->dpcm[stream].state); |
1057 | 1060 | ||
@@ -1076,7 +1079,7 @@ unwind: | |||
1076 | continue; | 1079 | continue; |
1077 | 1080 | ||
1078 | if (be->dpcm[stream].users == 0) | 1081 | if (be->dpcm[stream].users == 0) |
1079 | dev_err(be->dev, "no users %s at close %d\n", | 1082 | dev_err(be->dev, "ASoC: no users %s at close %d\n", |
1080 | stream ? "capture" : "playback", | 1083 | stream ? "capture" : "playback", |
1081 | be->dpcm[stream].state); | 1084 | be->dpcm[stream].state); |
1082 | 1085 | ||
@@ -1128,16 +1131,16 @@ static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream) | |||
1128 | 1131 | ||
1129 | ret = dpcm_be_dai_startup(fe, fe_substream->stream); | 1132 | ret = dpcm_be_dai_startup(fe, fe_substream->stream); |
1130 | if (ret < 0) { | 1133 | if (ret < 0) { |
1131 | dev_err(fe->dev,"dpcm: failed to start some BEs %d\n", ret); | 1134 | dev_err(fe->dev,"ASoC: failed to start some BEs %d\n", ret); |
1132 | goto be_err; | 1135 | goto be_err; |
1133 | } | 1136 | } |
1134 | 1137 | ||
1135 | dev_dbg(fe->dev, "dpcm: open FE %s\n", fe->dai_link->name); | 1138 | dev_dbg(fe->dev, "ASoC: open FE %s\n", fe->dai_link->name); |
1136 | 1139 | ||
1137 | /* start the DAI frontend */ | 1140 | /* start the DAI frontend */ |
1138 | ret = soc_pcm_open(fe_substream); | 1141 | ret = soc_pcm_open(fe_substream); |
1139 | if (ret < 0) { | 1142 | if (ret < 0) { |
1140 | dev_err(fe->dev,"dpcm: failed to start FE %d\n", ret); | 1143 | dev_err(fe->dev,"ASoC: failed to start FE %d\n", ret); |
1141 | goto unwind; | 1144 | goto unwind; |
1142 | } | 1145 | } |
1143 | 1146 | ||
@@ -1172,7 +1175,7 @@ static int dpcm_be_dai_shutdown(struct snd_soc_pcm_runtime *fe, int stream) | |||
1172 | continue; | 1175 | continue; |
1173 | 1176 | ||
1174 | if (be->dpcm[stream].users == 0) | 1177 | if (be->dpcm[stream].users == 0) |
1175 | dev_err(be->dev, "no users %s at close - state %d\n", | 1178 | dev_err(be->dev, "ASoC: no users %s at close - state %d\n", |
1176 | stream ? "capture" : "playback", | 1179 | stream ? "capture" : "playback", |
1177 | be->dpcm[stream].state); | 1180 | be->dpcm[stream].state); |
1178 | 1181 | ||
@@ -1183,7 +1186,7 @@ static int dpcm_be_dai_shutdown(struct snd_soc_pcm_runtime *fe, int stream) | |||
1183 | (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN)) | 1186 | (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN)) |
1184 | continue; | 1187 | continue; |
1185 | 1188 | ||
1186 | dev_dbg(be->dev, "dpcm: close BE %s\n", | 1189 | dev_dbg(be->dev, "ASoC: close BE %s\n", |
1187 | dpcm->fe->dai_link->name); | 1190 | dpcm->fe->dai_link->name); |
1188 | 1191 | ||
1189 | soc_pcm_close(be_substream); | 1192 | soc_pcm_close(be_substream); |
@@ -1204,7 +1207,7 @@ static int dpcm_fe_dai_shutdown(struct snd_pcm_substream *substream) | |||
1204 | /* shutdown the BEs */ | 1207 | /* shutdown the BEs */ |
1205 | dpcm_be_dai_shutdown(fe, substream->stream); | 1208 | dpcm_be_dai_shutdown(fe, substream->stream); |
1206 | 1209 | ||
1207 | dev_dbg(fe->dev, "dpcm: close FE %s\n", fe->dai_link->name); | 1210 | dev_dbg(fe->dev, "ASoC: close FE %s\n", fe->dai_link->name); |
1208 | 1211 | ||
1209 | /* now shutdown the frontend */ | 1212 | /* now shutdown the frontend */ |
1210 | soc_pcm_close(substream); | 1213 | soc_pcm_close(substream); |
@@ -1243,7 +1246,7 @@ static int dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream) | |||
1243 | (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) | 1246 | (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) |
1244 | continue; | 1247 | continue; |
1245 | 1248 | ||
1246 | dev_dbg(be->dev, "dpcm: hw_free BE %s\n", | 1249 | dev_dbg(be->dev, "ASoC: hw_free BE %s\n", |
1247 | dpcm->fe->dai_link->name); | 1250 | dpcm->fe->dai_link->name); |
1248 | 1251 | ||
1249 | soc_pcm_hw_free(be_substream); | 1252 | soc_pcm_hw_free(be_substream); |
@@ -1262,12 +1265,12 @@ static int dpcm_fe_dai_hw_free(struct snd_pcm_substream *substream) | |||
1262 | mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); | 1265 | mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); |
1263 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; | 1266 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; |
1264 | 1267 | ||
1265 | dev_dbg(fe->dev, "dpcm: hw_free FE %s\n", fe->dai_link->name); | 1268 | dev_dbg(fe->dev, "ASoC: hw_free FE %s\n", fe->dai_link->name); |
1266 | 1269 | ||
1267 | /* call hw_free on the frontend */ | 1270 | /* call hw_free on the frontend */ |
1268 | err = soc_pcm_hw_free(substream); | 1271 | err = soc_pcm_hw_free(substream); |
1269 | if (err < 0) | 1272 | if (err < 0) |
1270 | dev_err(fe->dev,"dpcm: hw_free FE %s failed\n", | 1273 | dev_err(fe->dev,"ASoC: hw_free FE %s failed\n", |
1271 | fe->dai_link->name); | 1274 | fe->dai_link->name); |
1272 | 1275 | ||
1273 | /* only hw_params backends that are either sinks or sources | 1276 | /* only hw_params backends that are either sinks or sources |
@@ -1305,7 +1308,7 @@ static int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream) | |||
1305 | (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE)) | 1308 | (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE)) |
1306 | continue; | 1309 | continue; |
1307 | 1310 | ||
1308 | dev_dbg(be->dev, "dpcm: hw_params BE %s\n", | 1311 | dev_dbg(be->dev, "ASoC: hw_params BE %s\n", |
1309 | dpcm->fe->dai_link->name); | 1312 | dpcm->fe->dai_link->name); |
1310 | 1313 | ||
1311 | /* copy params for each dpcm */ | 1314 | /* copy params for each dpcm */ |
@@ -1318,7 +1321,7 @@ static int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream) | |||
1318 | &dpcm->hw_params); | 1321 | &dpcm->hw_params); |
1319 | if (ret < 0) { | 1322 | if (ret < 0) { |
1320 | dev_err(be->dev, | 1323 | dev_err(be->dev, |
1321 | "dpcm: hw_params BE fixup failed %d\n", | 1324 | "ASoC: hw_params BE fixup failed %d\n", |
1322 | ret); | 1325 | ret); |
1323 | goto unwind; | 1326 | goto unwind; |
1324 | } | 1327 | } |
@@ -1327,7 +1330,7 @@ static int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream) | |||
1327 | ret = soc_pcm_hw_params(be_substream, &dpcm->hw_params); | 1330 | ret = soc_pcm_hw_params(be_substream, &dpcm->hw_params); |
1328 | if (ret < 0) { | 1331 | if (ret < 0) { |
1329 | dev_err(dpcm->be->dev, | 1332 | dev_err(dpcm->be->dev, |
1330 | "dpcm: hw_params BE failed %d\n", ret); | 1333 | "ASoC: hw_params BE failed %d\n", ret); |
1331 | goto unwind; | 1334 | goto unwind; |
1332 | } | 1335 | } |
1333 | 1336 | ||
@@ -1374,18 +1377,18 @@ static int dpcm_fe_dai_hw_params(struct snd_pcm_substream *substream, | |||
1374 | sizeof(struct snd_pcm_hw_params)); | 1377 | sizeof(struct snd_pcm_hw_params)); |
1375 | ret = dpcm_be_dai_hw_params(fe, substream->stream); | 1378 | ret = dpcm_be_dai_hw_params(fe, substream->stream); |
1376 | if (ret < 0) { | 1379 | if (ret < 0) { |
1377 | dev_err(fe->dev,"dpcm: hw_params BE failed %d\n", ret); | 1380 | dev_err(fe->dev,"ASoC: hw_params BE failed %d\n", ret); |
1378 | goto out; | 1381 | goto out; |
1379 | } | 1382 | } |
1380 | 1383 | ||
1381 | dev_dbg(fe->dev, "dpcm: hw_params FE %s rate %d chan %x fmt %d\n", | 1384 | dev_dbg(fe->dev, "ASoC: hw_params FE %s rate %d chan %x fmt %d\n", |
1382 | fe->dai_link->name, params_rate(params), | 1385 | fe->dai_link->name, params_rate(params), |
1383 | params_channels(params), params_format(params)); | 1386 | params_channels(params), params_format(params)); |
1384 | 1387 | ||
1385 | /* call hw_params on the frontend */ | 1388 | /* call hw_params on the frontend */ |
1386 | ret = soc_pcm_hw_params(substream, params); | 1389 | ret = soc_pcm_hw_params(substream, params); |
1387 | if (ret < 0) { | 1390 | if (ret < 0) { |
1388 | dev_err(fe->dev,"dpcm: hw_params FE failed %d\n", ret); | 1391 | dev_err(fe->dev,"ASoC: hw_params FE failed %d\n", ret); |
1389 | dpcm_be_dai_hw_free(fe, stream); | 1392 | dpcm_be_dai_hw_free(fe, stream); |
1390 | } else | 1393 | } else |
1391 | fe->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_PARAMS; | 1394 | fe->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_PARAMS; |
@@ -1401,12 +1404,12 @@ static int dpcm_do_trigger(struct snd_soc_dpcm *dpcm, | |||
1401 | { | 1404 | { |
1402 | int ret; | 1405 | int ret; |
1403 | 1406 | ||
1404 | dev_dbg(dpcm->be->dev, "dpcm: trigger BE %s cmd %d\n", | 1407 | dev_dbg(dpcm->be->dev, "ASoC: trigger BE %s cmd %d\n", |
1405 | dpcm->fe->dai_link->name, cmd); | 1408 | dpcm->fe->dai_link->name, cmd); |
1406 | 1409 | ||
1407 | ret = soc_pcm_trigger(substream, cmd); | 1410 | ret = soc_pcm_trigger(substream, cmd); |
1408 | if (ret < 0) | 1411 | if (ret < 0) |
1409 | dev_err(dpcm->be->dev,"dpcm: trigger BE failed %d\n", ret); | 1412 | dev_err(dpcm->be->dev,"ASoC: trigger BE failed %d\n", ret); |
1410 | 1413 | ||
1411 | return ret; | 1414 | return ret; |
1412 | } | 1415 | } |
@@ -1517,12 +1520,12 @@ static int dpcm_fe_dai_trigger(struct snd_pcm_substream *substream, int cmd) | |||
1517 | case SND_SOC_DPCM_TRIGGER_PRE: | 1520 | case SND_SOC_DPCM_TRIGGER_PRE: |
1518 | /* call trigger on the frontend before the backend. */ | 1521 | /* call trigger on the frontend before the backend. */ |
1519 | 1522 | ||
1520 | dev_dbg(fe->dev, "dpcm: pre trigger FE %s cmd %d\n", | 1523 | dev_dbg(fe->dev, "ASoC: pre trigger FE %s cmd %d\n", |
1521 | fe->dai_link->name, cmd); | 1524 | fe->dai_link->name, cmd); |
1522 | 1525 | ||
1523 | ret = soc_pcm_trigger(substream, cmd); | 1526 | ret = soc_pcm_trigger(substream, cmd); |
1524 | if (ret < 0) { | 1527 | if (ret < 0) { |
1525 | dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret); | 1528 | dev_err(fe->dev,"ASoC: trigger FE failed %d\n", ret); |
1526 | goto out; | 1529 | goto out; |
1527 | } | 1530 | } |
1528 | 1531 | ||
@@ -1533,11 +1536,11 @@ static int dpcm_fe_dai_trigger(struct snd_pcm_substream *substream, int cmd) | |||
1533 | 1536 | ||
1534 | ret = dpcm_be_dai_trigger(fe, substream->stream, cmd); | 1537 | ret = dpcm_be_dai_trigger(fe, substream->stream, cmd); |
1535 | if (ret < 0) { | 1538 | if (ret < 0) { |
1536 | dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret); | 1539 | dev_err(fe->dev,"ASoC: trigger FE failed %d\n", ret); |
1537 | goto out; | 1540 | goto out; |
1538 | } | 1541 | } |
1539 | 1542 | ||
1540 | dev_dbg(fe->dev, "dpcm: post trigger FE %s cmd %d\n", | 1543 | dev_dbg(fe->dev, "ASoC: post trigger FE %s cmd %d\n", |
1541 | fe->dai_link->name, cmd); | 1544 | fe->dai_link->name, cmd); |
1542 | 1545 | ||
1543 | ret = soc_pcm_trigger(substream, cmd); | 1546 | ret = soc_pcm_trigger(substream, cmd); |
@@ -1545,17 +1548,17 @@ static int dpcm_fe_dai_trigger(struct snd_pcm_substream *substream, int cmd) | |||
1545 | case SND_SOC_DPCM_TRIGGER_BESPOKE: | 1548 | case SND_SOC_DPCM_TRIGGER_BESPOKE: |
1546 | /* bespoke trigger() - handles both FE and BEs */ | 1549 | /* bespoke trigger() - handles both FE and BEs */ |
1547 | 1550 | ||
1548 | dev_dbg(fe->dev, "dpcm: bespoke trigger FE %s cmd %d\n", | 1551 | dev_dbg(fe->dev, "ASoC: bespoke trigger FE %s cmd %d\n", |
1549 | fe->dai_link->name, cmd); | 1552 | fe->dai_link->name, cmd); |
1550 | 1553 | ||
1551 | ret = soc_pcm_bespoke_trigger(substream, cmd); | 1554 | ret = soc_pcm_bespoke_trigger(substream, cmd); |
1552 | if (ret < 0) { | 1555 | if (ret < 0) { |
1553 | dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret); | 1556 | dev_err(fe->dev,"ASoC: trigger FE failed %d\n", ret); |
1554 | goto out; | 1557 | goto out; |
1555 | } | 1558 | } |
1556 | break; | 1559 | break; |
1557 | default: | 1560 | default: |
1558 | dev_err(fe->dev, "dpcm: invalid trigger cmd %d for %s\n", cmd, | 1561 | dev_err(fe->dev, "ASoC: invalid trigger cmd %d for %s\n", cmd, |
1559 | fe->dai_link->name); | 1562 | fe->dai_link->name); |
1560 | ret = -EINVAL; | 1563 | ret = -EINVAL; |
1561 | goto out; | 1564 | goto out; |
@@ -1598,12 +1601,12 @@ static int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream) | |||
1598 | (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) | 1601 | (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) |
1599 | continue; | 1602 | continue; |
1600 | 1603 | ||
1601 | dev_dbg(be->dev, "dpcm: prepare BE %s\n", | 1604 | dev_dbg(be->dev, "ASoC: prepare BE %s\n", |
1602 | dpcm->fe->dai_link->name); | 1605 | dpcm->fe->dai_link->name); |
1603 | 1606 | ||
1604 | ret = soc_pcm_prepare(be_substream); | 1607 | ret = soc_pcm_prepare(be_substream); |
1605 | if (ret < 0) { | 1608 | if (ret < 0) { |
1606 | dev_err(be->dev, "dpcm: backend prepare failed %d\n", | 1609 | dev_err(be->dev, "ASoC: backend prepare failed %d\n", |
1607 | ret); | 1610 | ret); |
1608 | break; | 1611 | break; |
1609 | } | 1612 | } |
@@ -1620,13 +1623,13 @@ static int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream) | |||
1620 | 1623 | ||
1621 | mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); | 1624 | mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); |
1622 | 1625 | ||
1623 | dev_dbg(fe->dev, "dpcm: prepare FE %s\n", fe->dai_link->name); | 1626 | dev_dbg(fe->dev, "ASoC: prepare FE %s\n", fe->dai_link->name); |
1624 | 1627 | ||
1625 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; | 1628 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; |
1626 | 1629 | ||
1627 | /* there is no point preparing this FE if there are no BEs */ | 1630 | /* there is no point preparing this FE if there are no BEs */ |
1628 | if (list_empty(&fe->dpcm[stream].be_clients)) { | 1631 | if (list_empty(&fe->dpcm[stream].be_clients)) { |
1629 | dev_err(fe->dev, "dpcm: no backend DAIs enabled for %s\n", | 1632 | dev_err(fe->dev, "ASoC: no backend DAIs enabled for %s\n", |
1630 | fe->dai_link->name); | 1633 | fe->dai_link->name); |
1631 | ret = -EINVAL; | 1634 | ret = -EINVAL; |
1632 | goto out; | 1635 | goto out; |
@@ -1639,7 +1642,7 @@ static int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream) | |||
1639 | /* call prepare on the frontend */ | 1642 | /* call prepare on the frontend */ |
1640 | ret = soc_pcm_prepare(substream); | 1643 | ret = soc_pcm_prepare(substream); |
1641 | if (ret < 0) { | 1644 | if (ret < 0) { |
1642 | dev_err(fe->dev,"dpcm: prepare FE %s failed\n", | 1645 | dev_err(fe->dev,"ASoC: prepare FE %s failed\n", |
1643 | fe->dai_link->name); | 1646 | fe->dai_link->name); |
1644 | goto out; | 1647 | goto out; |
1645 | } | 1648 | } |
@@ -1673,33 +1676,33 @@ static int dpcm_run_update_shutdown(struct snd_soc_pcm_runtime *fe, int stream) | |||
1673 | enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream]; | 1676 | enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream]; |
1674 | int err; | 1677 | int err; |
1675 | 1678 | ||
1676 | dev_dbg(fe->dev, "runtime %s close on FE %s\n", | 1679 | dev_dbg(fe->dev, "ASoC: runtime %s close on FE %s\n", |
1677 | stream ? "capture" : "playback", fe->dai_link->name); | 1680 | stream ? "capture" : "playback", fe->dai_link->name); |
1678 | 1681 | ||
1679 | if (trigger == SND_SOC_DPCM_TRIGGER_BESPOKE) { | 1682 | if (trigger == SND_SOC_DPCM_TRIGGER_BESPOKE) { |
1680 | /* call bespoke trigger - FE takes care of all BE triggers */ | 1683 | /* call bespoke trigger - FE takes care of all BE triggers */ |
1681 | dev_dbg(fe->dev, "dpcm: bespoke trigger FE %s cmd stop\n", | 1684 | dev_dbg(fe->dev, "ASoC: bespoke trigger FE %s cmd stop\n", |
1682 | fe->dai_link->name); | 1685 | fe->dai_link->name); |
1683 | 1686 | ||
1684 | err = soc_pcm_bespoke_trigger(substream, SNDRV_PCM_TRIGGER_STOP); | 1687 | err = soc_pcm_bespoke_trigger(substream, SNDRV_PCM_TRIGGER_STOP); |
1685 | if (err < 0) | 1688 | if (err < 0) |
1686 | dev_err(fe->dev,"dpcm: trigger FE failed %d\n", err); | 1689 | dev_err(fe->dev,"ASoC: trigger FE failed %d\n", err); |
1687 | } else { | 1690 | } else { |
1688 | dev_dbg(fe->dev, "dpcm: trigger FE %s cmd stop\n", | 1691 | dev_dbg(fe->dev, "ASoC: trigger FE %s cmd stop\n", |
1689 | fe->dai_link->name); | 1692 | fe->dai_link->name); |
1690 | 1693 | ||
1691 | err = dpcm_be_dai_trigger(fe, stream, SNDRV_PCM_TRIGGER_STOP); | 1694 | err = dpcm_be_dai_trigger(fe, stream, SNDRV_PCM_TRIGGER_STOP); |
1692 | if (err < 0) | 1695 | if (err < 0) |
1693 | dev_err(fe->dev,"dpcm: trigger FE failed %d\n", err); | 1696 | dev_err(fe->dev,"ASoC: trigger FE failed %d\n", err); |
1694 | } | 1697 | } |
1695 | 1698 | ||
1696 | err = dpcm_be_dai_hw_free(fe, stream); | 1699 | err = dpcm_be_dai_hw_free(fe, stream); |
1697 | if (err < 0) | 1700 | if (err < 0) |
1698 | dev_err(fe->dev,"dpcm: hw_free FE failed %d\n", err); | 1701 | dev_err(fe->dev,"ASoC: hw_free FE failed %d\n", err); |
1699 | 1702 | ||
1700 | err = dpcm_be_dai_shutdown(fe, stream); | 1703 | err = dpcm_be_dai_shutdown(fe, stream); |
1701 | if (err < 0) | 1704 | if (err < 0) |
1702 | dev_err(fe->dev,"dpcm: shutdown FE failed %d\n", err); | 1705 | dev_err(fe->dev,"ASoC: shutdown FE failed %d\n", err); |
1703 | 1706 | ||
1704 | /* run the stream event for each BE */ | 1707 | /* run the stream event for each BE */ |
1705 | dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_NOP); | 1708 | dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_NOP); |
@@ -1715,7 +1718,7 @@ static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream) | |||
1715 | enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream]; | 1718 | enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream]; |
1716 | int ret; | 1719 | int ret; |
1717 | 1720 | ||
1718 | dev_dbg(fe->dev, "runtime %s open on FE %s\n", | 1721 | dev_dbg(fe->dev, "ASoC: runtime %s open on FE %s\n", |
1719 | stream ? "capture" : "playback", fe->dai_link->name); | 1722 | stream ? "capture" : "playback", fe->dai_link->name); |
1720 | 1723 | ||
1721 | /* Only start the BE if the FE is ready */ | 1724 | /* Only start the BE if the FE is ready */ |
@@ -1761,22 +1764,22 @@ static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream) | |||
1761 | 1764 | ||
1762 | if (trigger == SND_SOC_DPCM_TRIGGER_BESPOKE) { | 1765 | if (trigger == SND_SOC_DPCM_TRIGGER_BESPOKE) { |
1763 | /* call trigger on the frontend - FE takes care of all BE triggers */ | 1766 | /* call trigger on the frontend - FE takes care of all BE triggers */ |
1764 | dev_dbg(fe->dev, "dpcm: bespoke trigger FE %s cmd start\n", | 1767 | dev_dbg(fe->dev, "ASoC: bespoke trigger FE %s cmd start\n", |
1765 | fe->dai_link->name); | 1768 | fe->dai_link->name); |
1766 | 1769 | ||
1767 | ret = soc_pcm_bespoke_trigger(substream, SNDRV_PCM_TRIGGER_START); | 1770 | ret = soc_pcm_bespoke_trigger(substream, SNDRV_PCM_TRIGGER_START); |
1768 | if (ret < 0) { | 1771 | if (ret < 0) { |
1769 | dev_err(fe->dev,"dpcm: bespoke trigger FE failed %d\n", ret); | 1772 | dev_err(fe->dev,"ASoC: bespoke trigger FE failed %d\n", ret); |
1770 | goto hw_free; | 1773 | goto hw_free; |
1771 | } | 1774 | } |
1772 | } else { | 1775 | } else { |
1773 | dev_dbg(fe->dev, "dpcm: trigger FE %s cmd start\n", | 1776 | dev_dbg(fe->dev, "ASoC: trigger FE %s cmd start\n", |
1774 | fe->dai_link->name); | 1777 | fe->dai_link->name); |
1775 | 1778 | ||
1776 | ret = dpcm_be_dai_trigger(fe, stream, | 1779 | ret = dpcm_be_dai_trigger(fe, stream, |
1777 | SNDRV_PCM_TRIGGER_START); | 1780 | SNDRV_PCM_TRIGGER_START); |
1778 | if (ret < 0) { | 1781 | if (ret < 0) { |
1779 | dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret); | 1782 | dev_err(fe->dev,"ASoC: trigger FE failed %d\n", ret); |
1780 | goto hw_free; | 1783 | goto hw_free; |
1781 | } | 1784 | } |
1782 | } | 1785 | } |
@@ -1805,7 +1808,7 @@ static int dpcm_run_new_update(struct snd_soc_pcm_runtime *fe, int stream) | |||
1805 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE; | 1808 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE; |
1806 | ret = dpcm_run_update_startup(fe, stream); | 1809 | ret = dpcm_run_update_startup(fe, stream); |
1807 | if (ret < 0) | 1810 | if (ret < 0) |
1808 | dev_err(fe->dev, "failed to startup some BEs\n"); | 1811 | dev_err(fe->dev, "ASoC: failed to startup some BEs\n"); |
1809 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; | 1812 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; |
1810 | 1813 | ||
1811 | return ret; | 1814 | return ret; |
@@ -1818,7 +1821,7 @@ static int dpcm_run_old_update(struct snd_soc_pcm_runtime *fe, int stream) | |||
1818 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE; | 1821 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE; |
1819 | ret = dpcm_run_update_shutdown(fe, stream); | 1822 | ret = dpcm_run_update_shutdown(fe, stream); |
1820 | if (ret < 0) | 1823 | if (ret < 0) |
1821 | dev_err(fe->dev, "failed to shutdown some BEs\n"); | 1824 | dev_err(fe->dev, "ASoC: failed to shutdown some BEs\n"); |
1822 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; | 1825 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; |
1823 | 1826 | ||
1824 | return ret; | 1827 | return ret; |
@@ -1853,7 +1856,7 @@ int soc_dpcm_runtime_update(struct snd_soc_dapm_widget *widget) | |||
1853 | continue; | 1856 | continue; |
1854 | 1857 | ||
1855 | /* DAPM sync will call this to update DSP paths */ | 1858 | /* DAPM sync will call this to update DSP paths */ |
1856 | dev_dbg(fe->dev, "DPCM runtime update for FE %s\n", | 1859 | dev_dbg(fe->dev, "ASoC: DPCM runtime update for FE %s\n", |
1857 | fe->dai_link->name); | 1860 | fe->dai_link->name); |
1858 | 1861 | ||
1859 | /* skip if FE doesn't have playback capability */ | 1862 | /* skip if FE doesn't have playback capability */ |
@@ -1862,7 +1865,7 @@ int soc_dpcm_runtime_update(struct snd_soc_dapm_widget *widget) | |||
1862 | 1865 | ||
1863 | paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_PLAYBACK, &list); | 1866 | paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_PLAYBACK, &list); |
1864 | if (paths < 0) { | 1867 | if (paths < 0) { |
1865 | dev_warn(fe->dev, "%s no valid %s path\n", | 1868 | dev_warn(fe->dev, "ASoC: %s no valid %s path\n", |
1866 | fe->dai_link->name, "playback"); | 1869 | fe->dai_link->name, "playback"); |
1867 | mutex_unlock(&card->mutex); | 1870 | mutex_unlock(&card->mutex); |
1868 | return paths; | 1871 | return paths; |
@@ -1891,7 +1894,7 @@ capture: | |||
1891 | 1894 | ||
1892 | paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_CAPTURE, &list); | 1895 | paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_CAPTURE, &list); |
1893 | if (paths < 0) { | 1896 | if (paths < 0) { |
1894 | dev_warn(fe->dev, "%s no valid %s path\n", | 1897 | dev_warn(fe->dev, "ASoC: %s no valid %s path\n", |
1895 | fe->dai_link->name, "capture"); | 1898 | fe->dai_link->name, "capture"); |
1896 | mutex_unlock(&card->mutex); | 1899 | mutex_unlock(&card->mutex); |
1897 | return paths; | 1900 | return paths; |
@@ -1934,7 +1937,7 @@ int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute) | |||
1934 | if (be->dai_link->ignore_suspend) | 1937 | if (be->dai_link->ignore_suspend) |
1935 | continue; | 1938 | continue; |
1936 | 1939 | ||
1937 | dev_dbg(be->dev, "BE digital mute %s\n", be->dai_link->name); | 1940 | dev_dbg(be->dev, "ASoC: BE digital mute %s\n", be->dai_link->name); |
1938 | 1941 | ||
1939 | if (drv->ops->digital_mute && dai->playback_active) | 1942 | if (drv->ops->digital_mute && dai->playback_active) |
1940 | drv->ops->digital_mute(dai, mute); | 1943 | drv->ops->digital_mute(dai, mute); |
@@ -1955,7 +1958,7 @@ static int dpcm_fe_dai_open(struct snd_pcm_substream *fe_substream) | |||
1955 | fe->dpcm[stream].runtime = fe_substream->runtime; | 1958 | fe->dpcm[stream].runtime = fe_substream->runtime; |
1956 | 1959 | ||
1957 | if (dpcm_path_get(fe, stream, &list) <= 0) { | 1960 | if (dpcm_path_get(fe, stream, &list) <= 0) { |
1958 | dev_dbg(fe->dev, "asoc: %s no valid %s route\n", | 1961 | dev_dbg(fe->dev, "ASoC: %s no valid %s route\n", |
1959 | fe->dai_link->name, stream ? "capture" : "playback"); | 1962 | fe->dai_link->name, stream ? "capture" : "playback"); |
1960 | } | 1963 | } |
1961 | 1964 | ||
@@ -2039,11 +2042,11 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) | |||
2039 | capture, &pcm); | 2042 | capture, &pcm); |
2040 | } | 2043 | } |
2041 | if (ret < 0) { | 2044 | if (ret < 0) { |
2042 | dev_err(rtd->card->dev, "can't create pcm for %s\n", | 2045 | dev_err(rtd->card->dev, "ASoC: can't create pcm for %s\n", |
2043 | rtd->dai_link->name); | 2046 | rtd->dai_link->name); |
2044 | return ret; | 2047 | return ret; |
2045 | } | 2048 | } |
2046 | dev_dbg(rtd->card->dev, "registered pcm #%d %s\n",num, new_name); | 2049 | dev_dbg(rtd->card->dev, "ASoC: registered pcm #%d %s\n",num, new_name); |
2047 | 2050 | ||
2048 | /* DAPM dai link stream work */ | 2051 | /* DAPM dai link stream work */ |
2049 | INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work); | 2052 | INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work); |
@@ -2097,7 +2100,9 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) | |||
2097 | if (platform->driver->pcm_new) { | 2100 | if (platform->driver->pcm_new) { |
2098 | ret = platform->driver->pcm_new(rtd); | 2101 | ret = platform->driver->pcm_new(rtd); |
2099 | if (ret < 0) { | 2102 | if (ret < 0) { |
2100 | dev_err(platform->dev, "pcm constructor failed\n"); | 2103 | dev_err(platform->dev, |
2104 | "ASoC: pcm constructor failed: %d\n", | ||
2105 | ret); | ||
2101 | return ret; | 2106 | return ret; |
2102 | } | 2107 | } |
2103 | } | 2108 | } |
diff --git a/sound/soc/tegra/tegra20_das.c b/sound/soc/tegra/tegra20_das.c index bf99296bce95..49653375970b 100644 --- a/sound/soc/tegra/tegra20_das.c +++ b/sound/soc/tegra/tegra20_das.c | |||
@@ -210,7 +210,7 @@ static int __devexit tegra20_das_remove(struct platform_device *pdev) | |||
210 | return 0; | 210 | return 0; |
211 | } | 211 | } |
212 | 212 | ||
213 | static const struct of_device_id tegra20_das_of_match[] __devinitconst = { | 213 | static const struct of_device_id tegra20_das_of_match[] = { |
214 | { .compatible = "nvidia,tegra20-das", }, | 214 | { .compatible = "nvidia,tegra20-das", }, |
215 | {}, | 215 | {}, |
216 | }; | 216 | }; |
diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c index 0832e8afd73c..2ae8af86edbd 100644 --- a/sound/soc/tegra/tegra20_i2s.c +++ b/sound/soc/tegra/tegra20_i2s.c | |||
@@ -463,12 +463,12 @@ static int __devexit tegra20_i2s_platform_remove(struct platform_device *pdev) | |||
463 | return 0; | 463 | return 0; |
464 | } | 464 | } |
465 | 465 | ||
466 | static const struct of_device_id tegra20_i2s_of_match[] __devinitconst = { | 466 | static const struct of_device_id tegra20_i2s_of_match[] = { |
467 | { .compatible = "nvidia,tegra20-i2s", }, | 467 | { .compatible = "nvidia,tegra20-i2s", }, |
468 | {}, | 468 | {}, |
469 | }; | 469 | }; |
470 | 470 | ||
471 | static const struct dev_pm_ops tegra20_i2s_pm_ops __devinitconst = { | 471 | static const struct dev_pm_ops tegra20_i2s_pm_ops = { |
472 | SET_RUNTIME_PM_OPS(tegra20_i2s_runtime_suspend, | 472 | SET_RUNTIME_PM_OPS(tegra20_i2s_runtime_suspend, |
473 | tegra20_i2s_runtime_resume, NULL) | 473 | tegra20_i2s_runtime_resume, NULL) |
474 | }; | 474 | }; |
diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c index 3ebc8670ba00..d9641ef7b1ee 100644 --- a/sound/soc/tegra/tegra20_spdif.c +++ b/sound/soc/tegra/tegra20_spdif.c | |||
@@ -373,7 +373,7 @@ static int __devexit tegra20_spdif_platform_remove(struct platform_device *pdev) | |||
373 | return 0; | 373 | return 0; |
374 | } | 374 | } |
375 | 375 | ||
376 | static const struct dev_pm_ops tegra20_spdif_pm_ops __devinitconst = { | 376 | static const struct dev_pm_ops tegra20_spdif_pm_ops = { |
377 | SET_RUNTIME_PM_OPS(tegra20_spdif_runtime_suspend, | 377 | SET_RUNTIME_PM_OPS(tegra20_spdif_runtime_suspend, |
378 | tegra20_spdif_runtime_resume, NULL) | 378 | tegra20_spdif_runtime_resume, NULL) |
379 | }; | 379 | }; |
diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c index bf5610122c76..2269170b0df4 100644 --- a/sound/soc/tegra/tegra30_ahub.c +++ b/sound/soc/tegra/tegra30_ahub.c | |||
@@ -288,7 +288,7 @@ int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif) | |||
288 | } | 288 | } |
289 | EXPORT_SYMBOL_GPL(tegra30_ahub_unset_rx_cif_source); | 289 | EXPORT_SYMBOL_GPL(tegra30_ahub_unset_rx_cif_source); |
290 | 290 | ||
291 | static const char * const configlink_clocks[] __devinitconst = { | 291 | static const char * const configlink_clocks[] = { |
292 | "i2s0", | 292 | "i2s0", |
293 | "i2s1", | 293 | "i2s1", |
294 | "i2s2", | 294 | "i2s2", |
@@ -603,12 +603,12 @@ static int __devexit tegra30_ahub_remove(struct platform_device *pdev) | |||
603 | return 0; | 603 | return 0; |
604 | } | 604 | } |
605 | 605 | ||
606 | static const struct of_device_id tegra30_ahub_of_match[] __devinitconst = { | 606 | static const struct of_device_id tegra30_ahub_of_match[] = { |
607 | { .compatible = "nvidia,tegra30-ahub", }, | 607 | { .compatible = "nvidia,tegra30-ahub", }, |
608 | {}, | 608 | {}, |
609 | }; | 609 | }; |
610 | 610 | ||
611 | static const struct dev_pm_ops tegra30_ahub_pm_ops __devinitconst = { | 611 | static const struct dev_pm_ops tegra30_ahub_pm_ops = { |
612 | SET_RUNTIME_PM_OPS(tegra30_ahub_runtime_suspend, | 612 | SET_RUNTIME_PM_OPS(tegra30_ahub_runtime_suspend, |
613 | tegra30_ahub_runtime_resume, NULL) | 613 | tegra30_ahub_runtime_resume, NULL) |
614 | }; | 614 | }; |
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index 44184228d1f0..bf0e089e7997 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c | |||
@@ -508,12 +508,12 @@ static int __devexit tegra30_i2s_platform_remove(struct platform_device *pdev) | |||
508 | return 0; | 508 | return 0; |
509 | } | 509 | } |
510 | 510 | ||
511 | static const struct of_device_id tegra30_i2s_of_match[] __devinitconst = { | 511 | static const struct of_device_id tegra30_i2s_of_match[] = { |
512 | { .compatible = "nvidia,tegra30-i2s", }, | 512 | { .compatible = "nvidia,tegra30-i2s", }, |
513 | {}, | 513 | {}, |
514 | }; | 514 | }; |
515 | 515 | ||
516 | static const struct dev_pm_ops tegra30_i2s_pm_ops __devinitconst = { | 516 | static const struct dev_pm_ops tegra30_i2s_pm_ops = { |
517 | SET_RUNTIME_PM_OPS(tegra30_i2s_runtime_suspend, | 517 | SET_RUNTIME_PM_OPS(tegra30_i2s_runtime_suspend, |
518 | tegra30_i2s_runtime_resume, NULL) | 518 | tegra30_i2s_runtime_resume, NULL) |
519 | }; | 519 | }; |
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c index 76cb1b363b71..523795a6e83e 100644 --- a/sound/soc/tegra/tegra_alc5632.c +++ b/sound/soc/tegra/tegra_alc5632.c | |||
@@ -242,7 +242,7 @@ static int __devexit tegra_alc5632_remove(struct platform_device *pdev) | |||
242 | return 0; | 242 | return 0; |
243 | } | 243 | } |
244 | 244 | ||
245 | static const struct of_device_id tegra_alc5632_of_match[] __devinitconst = { | 245 | static const struct of_device_id tegra_alc5632_of_match[] = { |
246 | { .compatible = "nvidia,tegra-audio-alc5632", }, | 246 | { .compatible = "nvidia,tegra-audio-alc5632", }, |
247 | {}, | 247 | {}, |
248 | }; | 248 | }; |
diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c index ea9166d5c4eb..effe5b41b5f9 100644 --- a/sound/soc/tegra/tegra_wm8753.c +++ b/sound/soc/tegra/tegra_wm8753.c | |||
@@ -200,7 +200,7 @@ static int __devexit tegra_wm8753_driver_remove(struct platform_device *pdev) | |||
200 | return 0; | 200 | return 0; |
201 | } | 201 | } |
202 | 202 | ||
203 | static const struct of_device_id tegra_wm8753_of_match[] __devinitconst = { | 203 | static const struct of_device_id tegra_wm8753_of_match[] = { |
204 | { .compatible = "nvidia,tegra-audio-wm8753", }, | 204 | { .compatible = "nvidia,tegra-audio-wm8753", }, |
205 | {}, | 205 | {}, |
206 | }; | 206 | }; |
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index cee13b7bfb94..0f794126fbe4 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c | |||
@@ -417,7 +417,7 @@ static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev) | |||
417 | return 0; | 417 | return 0; |
418 | } | 418 | } |
419 | 419 | ||
420 | static const struct of_device_id tegra_wm8903_of_match[] __devinitconst = { | 420 | static const struct of_device_id tegra_wm8903_of_match[] = { |
421 | { .compatible = "nvidia,tegra-audio-wm8903", }, | 421 | { .compatible = "nvidia,tegra-audio-wm8903", }, |
422 | {}, | 422 | {}, |
423 | }; | 423 | }; |
diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c index e69a4f7000d6..4a255a4d0c47 100644 --- a/sound/soc/tegra/trimslice.c +++ b/sound/soc/tegra/trimslice.c | |||
@@ -195,7 +195,7 @@ static int __devexit tegra_snd_trimslice_remove(struct platform_device *pdev) | |||
195 | return 0; | 195 | return 0; |
196 | } | 196 | } |
197 | 197 | ||
198 | static const struct of_device_id trimslice_of_match[] __devinitconst = { | 198 | static const struct of_device_id trimslice_of_match[] = { |
199 | { .compatible = "nvidia,tegra-audio-trimslice", }, | 199 | { .compatible = "nvidia,tegra-audio-trimslice", }, |
200 | {}, | 200 | {}, |
201 | }; | 201 | }; |
diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c index 54f7e25b6f7d..651a52a95fd7 100644 --- a/sound/soc/ux500/mop500.c +++ b/sound/soc/ux500/mop500.c | |||
@@ -33,7 +33,7 @@ struct snd_soc_dai_link mop500_dai_links[] = { | |||
33 | .stream_name = "ab8500_0", | 33 | .stream_name = "ab8500_0", |
34 | .cpu_dai_name = "ux500-msp-i2s.1", | 34 | .cpu_dai_name = "ux500-msp-i2s.1", |
35 | .codec_dai_name = "ab8500-codec-dai.0", | 35 | .codec_dai_name = "ab8500-codec-dai.0", |
36 | .platform_name = "ux500-pcm.0", | 36 | .platform_name = "ux500-msp-i2s.1", |
37 | .codec_name = "ab8500-codec.0", | 37 | .codec_name = "ab8500-codec.0", |
38 | .init = mop500_ab8500_machine_init, | 38 | .init = mop500_ab8500_machine_init, |
39 | .ops = mop500_ab8500_ops, | 39 | .ops = mop500_ab8500_ops, |
@@ -43,7 +43,7 @@ struct snd_soc_dai_link mop500_dai_links[] = { | |||
43 | .stream_name = "ab8500_1", | 43 | .stream_name = "ab8500_1", |
44 | .cpu_dai_name = "ux500-msp-i2s.3", | 44 | .cpu_dai_name = "ux500-msp-i2s.3", |
45 | .codec_dai_name = "ab8500-codec-dai.1", | 45 | .codec_dai_name = "ab8500-codec-dai.1", |
46 | .platform_name = "ux500-pcm.0", | 46 | .platform_name = "ux500-msp-i2s.3", |
47 | .codec_name = "ab8500-codec.0", | 47 | .codec_name = "ab8500-codec.0", |
48 | .init = NULL, | 48 | .init = NULL, |
49 | .ops = mop500_ab8500_ops, | 49 | .ops = mop500_ab8500_ops, |
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c index be94bf9bf94f..478b4b60e0cc 100644 --- a/sound/soc/ux500/ux500_msp_dai.c +++ b/sound/soc/ux500/ux500_msp_dai.c | |||
@@ -28,6 +28,7 @@ | |||
28 | 28 | ||
29 | #include "ux500_msp_i2s.h" | 29 | #include "ux500_msp_i2s.h" |
30 | #include "ux500_msp_dai.h" | 30 | #include "ux500_msp_dai.h" |
31 | #include "ux500_pcm.h" | ||
31 | 32 | ||
32 | static int setup_pcm_multichan(struct snd_soc_dai *dai, | 33 | static int setup_pcm_multichan(struct snd_soc_dai *dai, |
33 | struct ux500_msp_config *msp_config) | 34 | struct ux500_msp_config *msp_config) |
@@ -398,11 +399,28 @@ static int ux500_msp_dai_startup(struct snd_pcm_substream *substream, | |||
398 | return ret; | 399 | return ret; |
399 | } | 400 | } |
400 | 401 | ||
401 | /* Enable clock */ | 402 | /* Prepare and enable clocks */ |
402 | dev_dbg(dai->dev, "%s: Enabling MSP-clock.\n", __func__); | 403 | dev_dbg(dai->dev, "%s: Enabling MSP-clocks.\n", __func__); |
403 | clk_enable(drvdata->clk); | 404 | ret = clk_prepare_enable(drvdata->pclk); |
405 | if (ret) { | ||
406 | dev_err(drvdata->msp->dev, | ||
407 | "%s: Failed to prepare/enable pclk!\n", __func__); | ||
408 | goto err_pclk; | ||
409 | } | ||
404 | 410 | ||
405 | return 0; | 411 | ret = clk_prepare_enable(drvdata->clk); |
412 | if (ret) { | ||
413 | dev_err(drvdata->msp->dev, | ||
414 | "%s: Failed to prepare/enable clk!\n", __func__); | ||
415 | goto err_clk; | ||
416 | } | ||
417 | |||
418 | return ret; | ||
419 | err_clk: | ||
420 | clk_disable_unprepare(drvdata->pclk); | ||
421 | err_pclk: | ||
422 | regulator_disable(drvdata->reg_vape); | ||
423 | return ret; | ||
406 | } | 424 | } |
407 | 425 | ||
408 | static void ux500_msp_dai_shutdown(struct snd_pcm_substream *substream, | 426 | static void ux500_msp_dai_shutdown(struct snd_pcm_substream *substream, |
@@ -428,8 +446,9 @@ static void ux500_msp_dai_shutdown(struct snd_pcm_substream *substream, | |||
428 | __func__, dai->id, snd_pcm_stream_str(substream)); | 446 | __func__, dai->id, snd_pcm_stream_str(substream)); |
429 | } | 447 | } |
430 | 448 | ||
431 | /* Disable clock */ | 449 | /* Disable and unprepare clocks */ |
432 | clk_disable(drvdata->clk); | 450 | clk_disable_unprepare(drvdata->clk); |
451 | clk_disable_unprepare(drvdata->pclk); | ||
433 | 452 | ||
434 | /* Disable regulator */ | 453 | /* Disable regulator */ |
435 | ret = regulator_disable(drvdata->reg_vape); | 454 | ret = regulator_disable(drvdata->reg_vape); |
@@ -780,6 +799,14 @@ static int __devinit ux500_msp_drv_probe(struct platform_device *pdev) | |||
780 | } | 799 | } |
781 | prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP, (char *)pdev->name, 50); | 800 | prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP, (char *)pdev->name, 50); |
782 | 801 | ||
802 | drvdata->pclk = clk_get(&pdev->dev, "apb_pclk"); | ||
803 | if (IS_ERR(drvdata->pclk)) { | ||
804 | ret = (int)PTR_ERR(drvdata->pclk); | ||
805 | dev_err(&pdev->dev, "%s: ERROR: clk_get of pclk failed (%d)!\n", | ||
806 | __func__, ret); | ||
807 | goto err_pclk; | ||
808 | } | ||
809 | |||
783 | drvdata->clk = clk_get(&pdev->dev, NULL); | 810 | drvdata->clk = clk_get(&pdev->dev, NULL); |
784 | if (IS_ERR(drvdata->clk)) { | 811 | if (IS_ERR(drvdata->clk)) { |
785 | ret = (int)PTR_ERR(drvdata->clk); | 812 | ret = (int)PTR_ERR(drvdata->clk); |
@@ -806,12 +833,23 @@ static int __devinit ux500_msp_drv_probe(struct platform_device *pdev) | |||
806 | goto err_init_msp; | 833 | goto err_init_msp; |
807 | } | 834 | } |
808 | 835 | ||
836 | ret = ux500_pcm_register_platform(pdev); | ||
837 | if (ret < 0) { | ||
838 | dev_err(&pdev->dev, | ||
839 | "Error: %s: Failed to register PCM platform device!\n", | ||
840 | __func__); | ||
841 | goto err_reg_plat; | ||
842 | } | ||
843 | |||
809 | return 0; | 844 | return 0; |
810 | 845 | ||
846 | err_reg_plat: | ||
847 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(ux500_msp_dai_drv)); | ||
811 | err_init_msp: | 848 | err_init_msp: |
812 | clk_put(drvdata->clk); | 849 | clk_put(drvdata->clk); |
813 | |||
814 | err_clk: | 850 | err_clk: |
851 | clk_put(drvdata->pclk); | ||
852 | err_pclk: | ||
815 | devm_regulator_put(drvdata->reg_vape); | 853 | devm_regulator_put(drvdata->reg_vape); |
816 | 854 | ||
817 | return ret; | 855 | return ret; |
@@ -821,12 +859,15 @@ static int __devexit ux500_msp_drv_remove(struct platform_device *pdev) | |||
821 | { | 859 | { |
822 | struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(&pdev->dev); | 860 | struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(&pdev->dev); |
823 | 861 | ||
862 | ux500_pcm_unregister_platform(pdev); | ||
863 | |||
824 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(ux500_msp_dai_drv)); | 864 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(ux500_msp_dai_drv)); |
825 | 865 | ||
826 | devm_regulator_put(drvdata->reg_vape); | 866 | devm_regulator_put(drvdata->reg_vape); |
827 | prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, "ux500_msp_i2s"); | 867 | prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, "ux500_msp_i2s"); |
828 | 868 | ||
829 | clk_put(drvdata->clk); | 869 | clk_put(drvdata->clk); |
870 | clk_put(drvdata->pclk); | ||
830 | 871 | ||
831 | ux500_msp_i2s_cleanup_msp(pdev, drvdata->msp); | 872 | ux500_msp_i2s_cleanup_msp(pdev, drvdata->msp); |
832 | 873 | ||
diff --git a/sound/soc/ux500/ux500_msp_dai.h b/sound/soc/ux500/ux500_msp_dai.h index 98202a34a5dd..9c778d9c3838 100644 --- a/sound/soc/ux500/ux500_msp_dai.h +++ b/sound/soc/ux500/ux500_msp_dai.h | |||
@@ -69,6 +69,7 @@ struct ux500_msp_i2s_drvdata { | |||
69 | /* Clocks */ | 69 | /* Clocks */ |
70 | unsigned int master_clk; | 70 | unsigned int master_clk; |
71 | struct clk *clk; | 71 | struct clk *clk; |
72 | struct clk *pclk; | ||
72 | 73 | ||
73 | /* Regulators */ | 74 | /* Regulators */ |
74 | int vape_opp_constraint; | 75 | int vape_opp_constraint; |
diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c index 1a04e248453c..894c9f4bb9f6 100644 --- a/sound/soc/ux500/ux500_pcm.c +++ b/sound/soc/ux500/ux500_pcm.c | |||
@@ -282,7 +282,7 @@ static struct snd_soc_platform_driver ux500_pcm_soc_drv = { | |||
282 | .pcm_new = ux500_pcm_new, | 282 | .pcm_new = ux500_pcm_new, |
283 | }; | 283 | }; |
284 | 284 | ||
285 | static int __devexit ux500_pcm_drv_probe(struct platform_device *pdev) | 285 | int __devinit ux500_pcm_register_platform(struct platform_device *pdev) |
286 | { | 286 | { |
287 | int ret; | 287 | int ret; |
288 | 288 | ||
@@ -296,23 +296,12 @@ static int __devexit ux500_pcm_drv_probe(struct platform_device *pdev) | |||
296 | 296 | ||
297 | return 0; | 297 | return 0; |
298 | } | 298 | } |
299 | EXPORT_SYMBOL_GPL(ux500_pcm_register_platform); | ||
299 | 300 | ||
300 | static int __devinit ux500_pcm_drv_remove(struct platform_device *pdev) | 301 | int __devexit ux500_pcm_unregister_platform(struct platform_device *pdev) |
301 | { | 302 | { |
302 | snd_soc_unregister_platform(&pdev->dev); | 303 | snd_soc_unregister_platform(&pdev->dev); |
303 | 304 | ||
304 | return 0; | 305 | return 0; |
305 | } | 306 | } |
306 | 307 | EXPORT_SYMBOL_GPL(ux500_pcm_unregister_platform); | |
307 | static struct platform_driver ux500_pcm_driver = { | ||
308 | .driver = { | ||
309 | .name = "ux500-pcm", | ||
310 | .owner = THIS_MODULE, | ||
311 | }, | ||
312 | |||
313 | .probe = ux500_pcm_drv_probe, | ||
314 | .remove = __devexit_p(ux500_pcm_drv_remove), | ||
315 | }; | ||
316 | module_platform_driver(ux500_pcm_driver); | ||
317 | |||
318 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/ux500/ux500_pcm.h b/sound/soc/ux500/ux500_pcm.h index 77ed44d371e9..76d344476afc 100644 --- a/sound/soc/ux500/ux500_pcm.h +++ b/sound/soc/ux500/ux500_pcm.h | |||
@@ -32,4 +32,7 @@ | |||
32 | #define UX500_PLATFORM_PERIODS_MAX 48 | 32 | #define UX500_PLATFORM_PERIODS_MAX 48 |
33 | #define UX500_PLATFORM_BUFFER_BYTES_MAX (2048 * PAGE_SIZE) | 33 | #define UX500_PLATFORM_BUFFER_BYTES_MAX (2048 * PAGE_SIZE) |
34 | 34 | ||
35 | int ux500_pcm_register_platform(struct platform_device *pdev); | ||
36 | int ux500_pcm_unregister_platform(struct platform_device *pdev); | ||
37 | |||
35 | #endif | 38 | #endif |