diff options
342 files changed, 7562 insertions, 3236 deletions
diff --git a/Documentation/devicetree/bindings/misc/atmel-ssc.txt b/Documentation/devicetree/bindings/misc/atmel-ssc.txt new file mode 100644 index 00000000000..38e51ad2e07 --- /dev/null +++ b/Documentation/devicetree/bindings/misc/atmel-ssc.txt @@ -0,0 +1,15 @@ +* Atmel SSC driver. + +Required properties: +- compatible: "atmel,at91rm9200-ssc" or "atmel,at91sam9g45-ssc" + - atmel,at91rm9200-ssc: support pdc transfer + - atmel,at91sam9g45-ssc: support dma transfer +- reg: Should contain SSC registers location and length +- interrupts: Should contain SSC interrupt + +Example: +ssc0: ssc@fffbc000 { + compatible = "atmel,at91rm9200-ssc"; + reg = <0xfffbc000 0x4000>; + interrupts = <14 4 5>; +}; diff --git a/Documentation/devicetree/bindings/sound/ak4104.txt b/Documentation/devicetree/bindings/sound/ak4104.txt new file mode 100644 index 00000000000..b902ee39cf8 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/ak4104.txt @@ -0,0 +1,22 @@ +AK4104 S/PDIF transmitter + +This device supports SPI mode only. + +Required properties: + + - compatible : "asahi-kasei,ak4104" + + - reg : The chip select number on the SPI bus + +Optional properties: + + - reset-gpio : a GPIO spec for the reset pin. If specified, it will be + deasserted before communication to the device starts. + +Example: + +spdif: ak4104@0 { + compatible = "asahi-kasei,ak4104"; + reg = <0>; + spi-max-frequency = <5000000>; +}; 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 00000000000..9c5a9947b64 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/atmel-at91sam9g20ek-wm8731-audio.txt @@ -0,0 +1,26 @@ +* Atmel at91sam9g20ek wm8731 audio complex + +Required properties: + - compatible: "atmel,at91sam9g20ek-wm8731-audio" + - atmel,model: The user-visible name of this sound complex. + - atmel,audio-routing: A list of the connections between audio components. + - atmel,ssc-controller: The phandle of the SSC controller + - atmel,audio-codec: The phandle of the WM8731 audio codec +Optional properties: + - pinctrl-names, pinctrl-0: Please refer to pinctrl-bindings.txt + +Example: +sound { + compatible = "atmel,at91sam9g20ek-wm8731-audio"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pck0_as_mck>; + + atmel,model = "wm8731 @ AT91SAMG20EK"; + + atmel,audio-routing = + "Ext Spk", "LHPOUT", + "Int MIC", "MICIN"; + + atmel,ssc-controller = <&ssc0>; + atmel,audio-codec = <&wm8731>; +}; diff --git a/Documentation/devicetree/bindings/sound/cs4271.txt b/Documentation/devicetree/bindings/sound/cs4271.txt index c81b5fd5a5b..a850fb9c88e 100644 --- a/Documentation/devicetree/bindings/sound/cs4271.txt +++ b/Documentation/devicetree/bindings/sound/cs4271.txt @@ -18,6 +18,8 @@ Optional properties: - reset-gpio: a GPIO spec to define which pin is connected to the chip's !RESET pin + - cirrus,amuteb-eq-bmutec: When given, the Codec's AMUTEB=BMUTEC flag + is enabled. Examples: diff --git a/Documentation/devicetree/bindings/sound/omap-abe-twl6040.txt b/Documentation/devicetree/bindings/sound/omap-abe-twl6040.txt index 65dec876cb2..fd40c852d7c 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: Optional properties: - ti,dmic: phandle for the OMAP dmic node if the machine have it connected -- ti,jack_detection: Need to be set to <1> if the board capable to detect jack +- ti,jack_detection: Need to be present if the board capable to detect jack insertion, removal. Available audio endpoints for the audio-routing table: @@ -59,7 +59,7 @@ sound { compatible = "ti,abe-twl6040"; ti,model = "SDP4430"; - ti,jack-detection = <1>; + ti,jack-detection; ti,mclk-freq = <38400000>; ti,mcpdm = <&mcpdm>; diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi index d410581a5a8..aaa42d8d4f8 100644 --- a/arch/arm/boot/dts/at91sam9260.dtsi +++ b/arch/arm/boot/dts/at91sam9260.dtsi @@ -29,6 +29,7 @@ tcb0 = &tcb0; tcb1 = &tcb1; i2c0 = &i2c0; + ssc0 = &ssc0; }; cpus { cpu@0 { @@ -212,6 +213,13 @@ status = "disabled"; }; + ssc0: ssc@fffbc000 { + compatible = "atmel,at91rm9200-ssc"; + reg = <0xfffbc000 0x4000>; + interrupts = <14 4 5>; + status = "disable"; + }; + adc0: adc@fffe0000 { compatible = "atmel,at91sam9260-adc"; reg = <0xfffe0000 0x100>; diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi index 3e6e5c1abbf..3b721ee59b1 100644 --- a/arch/arm/boot/dts/at91sam9263.dtsi +++ b/arch/arm/boot/dts/at91sam9263.dtsi @@ -25,6 +25,8 @@ gpio4 = &pioE; tcb0 = &tcb0; i2c0 = &i2c0; + ssc0 = &ssc0; + ssc1 = &ssc1; }; cpus { cpu@0 { @@ -173,6 +175,20 @@ status = "disabled"; }; + ssc0: ssc@fff98000 { + compatible = "atmel,at91rm9200-ssc"; + reg = <0xfff98000 0x4000>; + interrupts = <16 4 5>; + status = "disable"; + }; + + ssc1: ssc@fff9c000 { + compatible = "atmel,at91rm9200-ssc"; + reg = <0xfff9c000 0x4000>; + interrupts = <17 4 5>; + status = "disable"; + }; + macb0: ethernet@fffbc000 { compatible = "cdns,at32ap7000-macb", "cdns,macb"; reg = <0xfffbc000 0x100>; diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi index e6391a4e664..2dcec8de759 100644 --- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi +++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi @@ -30,6 +30,16 @@ ahb { apb { + pinctrl@fffff400 { + board { + pinctrl_pck0_as_mck: pck0_as_mck { + atmel,pins = + <2 1 0x2 0x0>; /* PC1 periph B */ + }; + + }; + }; + dbgu: serial@fffff200 { status = "okay"; }; @@ -51,6 +61,11 @@ atmel,vbus-gpio = <&pioC 5 0>; status = "okay"; }; + + ssc0: ssc@fffbc000 { + status = "okay"; + pinctrl-0 = <&pinctrl_ssc0_tx>; + }; }; nand0: nand@40000000 { @@ -114,7 +129,7 @@ reg = <0x50>; }; - wm8731@1b { + wm8731: wm8731@1b { compatible = "wm8731"; reg = <0x1b>; }; @@ -139,4 +154,19 @@ gpio-key,wakeup; }; }; + + sound { + compatible = "atmel,at91sam9g20ek-wm8731-audio"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pck0_as_mck>; + + atmel,model = "wm8731 @ AT91SAMG20EK"; + + atmel,audio-routing = + "Ext Spk", "LHPOUT", + "Int Mic", "MICIN"; + + atmel,ssc-controller = <&ssc0>; + atmel,audio-codec = <&wm8731>; + }; }; diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index 3add030d61f..acfa207162f 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -31,6 +31,8 @@ tcb1 = &tcb1; i2c0 = &i2c0; i2c1 = &i2c1; + ssc0 = &ssc0; + ssc1 = &ssc1; }; cpus { cpu@0 { @@ -226,6 +228,20 @@ status = "disabled"; }; + ssc0: ssc@fff9c000 { + compatible = "atmel,at91sam9g45-ssc"; + reg = <0xfff9c000 0x4000>; + interrupts = <16 4 5>; + status = "disable"; + }; + + ssc1: ssc@fffa0000 { + compatible = "atmel,at91sam9g45-ssc"; + reg = <0xfffa0000 0x4000>; + interrupts = <17 4 5>; + status = "disable"; + }; + adc0: adc@fffb0000 { compatible = "atmel,at91sam9260-adc"; reg = <0xfffb0000 0x100>; diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index 03fc136421c..69667d0ac34 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi @@ -30,6 +30,7 @@ i2c0 = &i2c0; i2c1 = &i2c1; i2c2 = &i2c2; + ssc0 = &ssc0; }; cpus { cpu@0 { @@ -87,6 +88,13 @@ interrupts = <1 4 7>; }; + ssc0: ssc@f0010000 { + compatible = "atmel,at91sam9g45-ssc"; + reg = <0xf0010000 0x4000>; + interrupts = <28 4 5>; + status = "disable"; + }; + tcb0: timer@f8008000 { compatible = "atmel,at91sam9x5-tcb"; reg = <0xf8008000 0x100>; diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c index 5269825194a..af47c75db51 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[] = { CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tc3_clk), CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk), CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk), - CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), - CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), - CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk), + CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.0", &ssc0_clk), + CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.1", &ssc1_clk), + CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.2", &ssc2_clk), + CLKDEV_CON_DEV_ID("pclk", "fffd0000.ssc", &ssc0_clk), + CLKDEV_CON_DEV_ID("pclk", "fffd4000.ssc", &ssc1_clk), + CLKDEV_CON_DEV_ID("pclk", "fffd8000.ssc", &ssc2_clk), CLKDEV_CON_DEV_ID(NULL, "i2c-at91rm9200.0", &twi_clk), /* fake hclk clock */ 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 3cee0e6ea7c..9e76427aaec 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[] = { }; static struct platform_device at91rm9200_ssc0_device = { - .name = "ssc", + .name = "at91rm9200_ssc", .id = 0, .dev = { .dma_mask = &ssc0_dmamask, @@ -794,7 +794,7 @@ static struct resource ssc1_resources[] = { }; static struct platform_device at91rm9200_ssc1_device = { - .name = "ssc", + .name = "at91rm9200_ssc", .id = 1, .dev = { .dma_mask = &ssc1_dmamask, @@ -836,7 +836,7 @@ static struct resource ssc2_resources[] = { }; static struct platform_device at91rm9200_ssc2_device = { - .name = "ssc", + .name = "at91rm9200_ssc", .id = 2, .dev = { .dma_mask = &ssc2_dmamask, diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index f8202615f4a..a41eb3d23f6 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[] = { CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tc3_clk), CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk), CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk), - CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc_clk), + CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.0", &ssc_clk), + CLKDEV_CON_DEV_ID("pclk", "fffbc000.ssc", &ssc_clk), CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260.0", &twi_clk), CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.0", &twi_clk), /* 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 414bd855fb0..e67cfa2acbe 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[] = { }; static struct platform_device at91sam9260_ssc_device = { - .name = "ssc", + .name = "at91rm9200_ssc", .id = 0, .dev = { .dma_mask = &ssc_dmamask, diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index 04295c04b3e..7fcbe058334 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[] = { CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk), CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), - CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), - CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), - CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk), + CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.0", &ssc0_clk), + CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.1", &ssc1_clk), + CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.2", &ssc2_clk), + CLKDEV_CON_DEV_ID("pclk", "fffbc000.ssc", &ssc0_clk), + CLKDEV_CON_DEV_ID("pclk", "fffc0000.ssc", &ssc1_clk), + CLKDEV_CON_DEV_ID("pclk", "fffc4000.ssc", &ssc2_clk), CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &hck0), CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9261.0", &twi_clk), 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 cd604aad8e9..a27d9dd0faa 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[] = { }; static struct platform_device at91sam9261_ssc0_device = { - .name = "ssc", + .name = "at91rm9200_ssc", .id = 0, .dev = { .dma_mask = &ssc0_dmamask, @@ -748,7 +748,7 @@ static struct resource ssc1_resources[] = { }; static struct platform_device at91sam9261_ssc1_device = { - .name = "ssc", + .name = "at91rm9200_ssc", .id = 1, .dev = { .dma_mask = &ssc1_dmamask, @@ -790,7 +790,7 @@ static struct resource ssc2_resources[] = { }; static struct platform_device at91sam9261_ssc2_device = { - .name = "ssc", + .name = "at91rm9200_ssc", .id = 2, .dev = { .dma_mask = &ssc2_dmamask, diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index d6f9c23927c..c0f4c8c1f4e 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 = { static struct clk_lookup periph_clocks_lookups[] = { /* One additional fake clock for macb_hclk */ CLKDEV_CON_ID("hclk", &macb_clk), - CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), - CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), + CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.0", &ssc0_clk), + CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.1", &ssc1_clk), + CLKDEV_CON_DEV_ID("pclk", "fff98000.ssc", &ssc0_clk), + CLKDEV_CON_DEV_ID("pclk", "fff9c000.ssc", &ssc1_clk), CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.0", &mmc0_clk), CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.1", &mmc1_clk), 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 9c61e59a210..8215839f2d5 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[] = { }; static struct platform_device at91sam9263_ssc0_device = { - .name = "ssc", + .name = "at91rm9200_ssc", .id = 0, .dev = { .dma_mask = &ssc0_dmamask, @@ -1241,7 +1241,7 @@ static struct resource ssc1_resources[] = { }; static struct platform_device at91sam9263_ssc1_device = { - .name = "ssc", + .name = "at91rm9200_ssc", .id = 1, .dev = { .dma_mask = &ssc1_dmamask, diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index 84af1b506d9..a4282d3742b 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[] = { CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tcb0_clk), CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10.0", &twi0_clk), CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10.1", &twi1_clk), - CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), - CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), + CLKDEV_CON_DEV_ID("pclk", "at91sam9g45_ssc.0", &ssc0_clk), + CLKDEV_CON_DEV_ID("pclk", "at91sam9g45_ssc.1", &ssc1_clk), + CLKDEV_CON_DEV_ID("pclk", "fff9c000.ssc", &ssc0_clk), + CLKDEV_CON_DEV_ID("pclk", "fffa0000.ssc", &ssc1_clk), CLKDEV_CON_DEV_ID(NULL, "atmel-trng", &trng_clk), CLKDEV_CON_DEV_ID(NULL, "atmel_sha", &aestdessha_clk), 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 fcd233cb33d..d26474a97fe 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[] = { }; static struct platform_device at91sam9g45_ssc0_device = { - .name = "ssc", + .name = "at91sam9g45_ssc", .id = 0, .dev = { .dma_mask = &ssc0_dmamask, @@ -1501,7 +1501,7 @@ static struct resource ssc1_resources[] = { }; static struct platform_device at91sam9g45_ssc1_device = { - .name = "ssc", + .name = "at91sam9g45_ssc", .id = 1, .dev = { .dma_mask = &ssc1_dmamask, diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index 72e90841222..b683fdc699f 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[] = { CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk), CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), - CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), - CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), + CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.0", &ssc0_clk), + CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.1", &ssc1_clk), + CLKDEV_CON_DEV_ID("pclk", "fffc0000.ssc", &ssc0_clk), + CLKDEV_CON_DEV_ID("pclk", "fffc4000.ssc", &ssc1_clk), CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.0", &twi0_clk), CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.1", &twi1_clk), 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 5047bdc92ad..b656110e8af 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[] = { }; static struct platform_device at91sam9rl_ssc0_device = { - .name = "ssc", + .name = "at91rm9200_ssc", .id = 0, .dev = { .dma_mask = &ssc0_dmamask, @@ -874,7 +874,7 @@ static struct resource ssc1_resources[] = { }; static struct platform_device at91sam9rl_ssc1_device = { - .name = "ssc", + .name = "at91rm9200_ssc", .id = 1, .dev = { .dma_mask = &ssc1_dmamask, diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c index e5035380dcb..18fbbb27f97 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[] = { CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb0_clk), CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma0_clk), CLKDEV_CON_DEV_ID("dma_clk", "ffffee00.dma-controller", &dma1_clk), + CLKDEV_CON_DEV_ID("pclk", "f0010000.ssc", &ssc_clk), CLKDEV_CON_DEV_ID(NULL, "f8010000.i2c", &twi0_clk), CLKDEV_CON_DEV_ID(NULL, "f8014000.i2c", &twi1_clk), 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 3ab2b86a376..ebdbf42c02c 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[] = { }, }; +static struct platform_device sam9g20ek_audio_device = { + .name = "at91sam9g20ek-audio", + .id = -1, +}; + +static void __init ek_add_device_audio(void) +{ + platform_device_register(&sam9g20ek_audio_device); +} + static void __init ek_board_init(void) { @@ -394,6 +404,7 @@ static void __init ek_board_init(void) at91_set_B_periph(AT91_PIN_PC1, 0); /* SSC (for WM8731) */ at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX); + ek_add_device_audio(); } 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 32ee3f89596..d9bc3fa7bb2 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[] = { }; static struct snd_platform_data da850_evm_snd_data = { - .tx_dma_offset = 0x2000, - .rx_dma_offset = 0x2000, - .op_mode = DAVINCI_MCASP_IIS_MODE, - .num_serializer = ARRAY_SIZE(da850_iis_serializer_direction), - .tdm_slots = 2, - .serial_dir = da850_iis_serializer_direction, - .asp_chan_q = EVENTQ_0, - .version = MCASP_VERSION_2, - .txnumevt = 1, - .rxnumevt = 1, + .tx_dma_offset = 0x2000, + .rx_dma_offset = 0x2000, + .op_mode = DAVINCI_MCASP_IIS_MODE, + .num_serializer = ARRAY_SIZE(da850_iis_serializer_direction), + .tdm_slots = 2, + .serial_dir = da850_iis_serializer_direction, + .asp_chan_q = EVENTQ_0, + .ram_chan_q = EVENTQ_1, + .version = MCASP_VERSION_2, + .txnumevt = 1, + .rxnumevt = 1, + .sram_size_playback = SZ_8K, + .sram_size_capture = SZ_8K, }; static const short da850_evm_mcasp_pins[] __initconst = { @@ -1509,6 +1512,7 @@ static __init void da850_evm_init(void) pr_warning("da850_evm_init: mcasp mux setup failed: %d\n", ret); + da850_evm_snd_data.sram_pool = sram_get_gen_pool(); da8xx_register_mcasp(0, &da850_evm_snd_data); ret = davinci_cfg_reg_list(da850_lcdcntl_pins); diff --git a/arch/arm/mach-exynos/mach-armlex4210.c b/arch/arm/mach-exynos/mach-armlex4210.c index 3f37a5e8a1f..b938f9fc1dd 100644 --- a/arch/arm/mach-exynos/mach-armlex4210.c +++ b/arch/arm/mach-exynos/mach-armlex4210.c @@ -147,7 +147,6 @@ static struct platform_device *armlex4210_devices[] __initdata = { &s3c_device_hsmmc3, &s3c_device_rtc, &s3c_device_wdt, - &samsung_asoc_dma, &armlex4210_smsc911x, &exynos4_device_ahci, }; diff --git a/arch/arm/mach-exynos/mach-smdkv310.c b/arch/arm/mach-exynos/mach-smdkv310.c index ee4fb1a9cb7..5de9ee28a50 100644 --- a/arch/arm/mach-exynos/mach-smdkv310.c +++ b/arch/arm/mach-exynos/mach-smdkv310.c @@ -311,7 +311,6 @@ static struct platform_device *smdkv310_devices[] __initdata = { &s5p_device_mfc_l, &s5p_device_mfc_r, &exynos4_device_spdif, - &samsung_asoc_dma, &samsung_asoc_idma, &s5p_device_fimd0, &smdkv310_device_audio, diff --git a/arch/arm/mach-s3c24xx/mach-gta02.c b/arch/arm/mach-s3c24xx/mach-gta02.c index 4a963467b7e..973b87ca87f 100644 --- a/arch/arm/mach-s3c24xx/mach-gta02.c +++ b/arch/arm/mach-s3c24xx/mach-gta02.c @@ -521,7 +521,6 @@ static struct platform_device *gta02_devices[] __initdata = { >a02_nor_flash, &s3c24xx_pwm_device, &s3c_device_iis, - &samsung_asoc_dma, &s3c_device_i2c0, >a02_dfbmcs320_device, >a02_buttons_device, diff --git a/arch/arm/mach-s3c24xx/mach-h1940.c b/arch/arm/mach-s3c24xx/mach-h1940.c index 63aaf076f61..b23dd1b106e 100644 --- a/arch/arm/mach-s3c24xx/mach-h1940.c +++ b/arch/arm/mach-s3c24xx/mach-h1940.c @@ -632,7 +632,6 @@ static struct platform_device *h1940_devices[] __initdata = { &s3c_device_wdt, &s3c_device_i2c0, &s3c_device_iis, - &samsung_asoc_dma, &s3c_device_usbgadget, &h1940_device_leds, &h1940_device_bluetooth, diff --git a/arch/arm/mach-s3c24xx/mach-mini2440.c b/arch/arm/mach-s3c24xx/mach-mini2440.c index 393c0f1ac11..a31d5b83e5f 100644 --- a/arch/arm/mach-s3c24xx/mach-mini2440.c +++ b/arch/arm/mach-s3c24xx/mach-mini2440.c @@ -519,7 +519,6 @@ static struct platform_device *mini2440_devices[] __initdata = { &s3c_device_iis, &uda1340_codec, &mini2440_audio, - &samsung_asoc_dma, }; static void __init mini2440_map_io(void) diff --git a/arch/arm/mach-s3c24xx/mach-rx1950.c b/arch/arm/mach-s3c24xx/mach-rx1950.c index 379fde521d3..0606f2faaa5 100644 --- a/arch/arm/mach-s3c24xx/mach-rx1950.c +++ b/arch/arm/mach-s3c24xx/mach-rx1950.c @@ -712,7 +712,6 @@ static struct platform_device *rx1950_devices[] __initdata = { &s3c_device_wdt, &s3c_device_i2c0, &s3c_device_iis, - &samsung_asoc_dma, &s3c_device_usbgadget, &s3c_device_rtc, &s3c_device_nand, diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c index 13b7eaa45fd..ef2117d7391 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410.c @@ -357,7 +357,6 @@ static struct platform_device *crag6410_devices[] __initdata = { &s3c_device_timer[0], &s3c64xx_device_iis0, &s3c64xx_device_iis1, - &samsung_asoc_dma, &samsung_device_keypad, &crag6410_gpio_keydev, &crag6410_dm9k_device, diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c index da1a771a29e..574a9eef588 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6410.c +++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c @@ -275,7 +275,6 @@ static struct platform_device *smdk6410_devices[] __initdata = { &s3c_device_fb, &s3c_device_ohci, &s3c_device_usb_hsotg, - &samsung_asoc_dma, &s3c64xx_device_iisv4, &samsung_device_keypad, diff --git a/arch/arm/mach-s5p64x0/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c index 96ea1fe0ec9..1af823558c6 100644 --- a/arch/arm/mach-s5p64x0/mach-smdk6440.c +++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c @@ -165,7 +165,6 @@ static struct platform_device *smdk6440_devices[] __initdata = { &s3c_device_i2c1, &s3c_device_ts, &s3c_device_wdt, - &samsung_asoc_dma, &s5p6440_device_iis, &s3c_device_fb, &smdk6440_lcd_lte480wv, diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c index 12748b6eaa7..62526ccf6b7 100644 --- a/arch/arm/mach-s5p64x0/mach-smdk6450.c +++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c @@ -183,7 +183,6 @@ static struct platform_device *smdk6450_devices[] __initdata = { &s3c_device_i2c1, &s3c_device_ts, &s3c_device_wdt, - &samsung_asoc_dma, &s5p6450_device_iis0, &s3c_device_fb, &smdk6450_lcd_lte480wv, diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c index dba7384a87b..9abe95e806a 100644 --- a/arch/arm/mach-s5pc100/mach-smdkc100.c +++ b/arch/arm/mach-s5pc100/mach-smdkc100.c @@ -197,7 +197,6 @@ static struct platform_device *smdkc100_devices[] __initdata = { &s3c_device_ts, &s3c_device_wdt, &smdkc100_lcd_powerdev, - &samsung_asoc_dma, &s5pc100_device_iis0, &samsung_device_keypad, &s5pc100_device_ac97, diff --git a/arch/arm/mach-s5pv210/mach-smdkc110.c b/arch/arm/mach-s5pv210/mach-smdkc110.c index d9c99fcc1aa..f1f3bd37ecd 100644 --- a/arch/arm/mach-s5pv210/mach-smdkc110.c +++ b/arch/arm/mach-s5pv210/mach-smdkc110.c @@ -85,7 +85,6 @@ static struct s3c_ide_platdata smdkc110_ide_pdata __initdata = { }; static struct platform_device *smdkc110_devices[] __initdata = { - &samsung_asoc_dma, &s5pv210_device_iis0, &s5pv210_device_ac97, &s5pv210_device_spdif, diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c index 4cdb5bb7bbc..6bc8404bf67 100644 --- a/arch/arm/mach-s5pv210/mach-smdkv210.c +++ b/arch/arm/mach-s5pv210/mach-smdkv210.c @@ -234,7 +234,6 @@ static struct platform_device *smdkv210_devices[] __initdata = { &s5pv210_device_ac97, &s5pv210_device_iis0, &s5pv210_device_spdif, - &samsung_asoc_dma, &samsung_asoc_idma, &samsung_device_keypad, &smdkv210_dm9000, diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c index 03f654d55ef..7d27a241f98 100644 --- a/arch/arm/plat-samsung/devs.c +++ b/arch/arm/plat-samsung/devs.c @@ -146,15 +146,6 @@ struct platform_device s3c_device_camif = { /* ASOC DMA */ -struct platform_device samsung_asoc_dma = { - .name = "samsung-audio", - .id = -1, - .dev = { - .dma_mask = &samsung_device_dma_mask, - .coherent_dma_mask = DMA_BIT_MASK(32), - } -}; - struct platform_device samsung_asoc_idma = { .name = "samsung-idma", .id = -1, diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h index 5da4b4f38f4..c45f70cbbfb 100644 --- a/arch/arm/plat-samsung/include/plat/devs.h +++ b/arch/arm/plat-samsung/include/plat/devs.h @@ -135,7 +135,6 @@ extern struct platform_device exynos4_device_spdif; extern struct platform_device exynos_device_drm; -extern struct platform_device samsung_asoc_dma; extern struct platform_device samsung_asoc_idma; extern struct platform_device samsung_device_keypad; diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index 80f9ab9c3aa..ac869d28d5b 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, struct regmap_range_node { struct rb_node node; + const char *name; + struct regmap *map; unsigned int range_min; unsigned int range_max; diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c index bb1ff175b96..f4b9dd01c98 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 = { .llseek = default_llseek, }; -static ssize_t regmap_map_read_file(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) +static ssize_t regmap_read_debugfs(struct regmap *map, unsigned int from, + unsigned int to, char __user *user_buf, + size_t count, loff_t *ppos) { int reg_len, val_len, tot_len; size_t buf_pos = 0; loff_t p = 0; ssize_t ret; int i; - struct regmap *map = file->private_data; char *buf; unsigned int val; @@ -80,7 +80,7 @@ static ssize_t regmap_map_read_file(struct file *file, char __user *user_buf, val_len = 2 * map->format.val_bytes; tot_len = reg_len + val_len + 3; /* : \n */ - for (i = 0; i <= map->max_register; i += map->reg_stride) { + for (i = from; i <= to; i += map->reg_stride) { if (!regmap_readable(map, i)) continue; @@ -95,7 +95,7 @@ static ssize_t regmap_map_read_file(struct file *file, char __user *user_buf, /* Format the register */ snprintf(buf + buf_pos, count - buf_pos, "%.*x: ", - reg_len, i); + reg_len, i - from); buf_pos += reg_len + 2; /* Format the value, write all X if we can't read */ @@ -126,6 +126,15 @@ out: return ret; } +static ssize_t regmap_map_read_file(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct regmap *map = file->private_data; + + return regmap_read_debugfs(map, 0, map->max_register, user_buf, + count, ppos); +} + #undef REGMAP_ALLOW_WRITE_DEBUGFS #ifdef REGMAP_ALLOW_WRITE_DEBUGFS /* @@ -174,6 +183,22 @@ static const struct file_operations regmap_map_fops = { .llseek = default_llseek, }; +static ssize_t regmap_range_read_file(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct regmap_range_node *range = file->private_data; + struct regmap *map = range->map; + + return regmap_read_debugfs(map, range->range_min, range->range_max, + user_buf, count, ppos); +} + +static const struct file_operations regmap_range_fops = { + .open = simple_open, + .read = regmap_range_read_file, + .llseek = default_llseek, +}; + static ssize_t regmap_access_read_file(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -244,6 +269,9 @@ static const struct file_operations regmap_access_fops = { void regmap_debugfs_init(struct regmap *map, const char *name) { + struct rb_node *next; + struct regmap_range_node *range_node; + if (name) { map->debugfs_name = kasprintf(GFP_KERNEL, "%s-%s", dev_name(map->dev), name); @@ -276,6 +304,18 @@ void regmap_debugfs_init(struct regmap *map, const char *name) debugfs_create_bool("cache_bypass", 0400, map->debugfs, &map->cache_bypass); } + + next = rb_first(&map->range_tree); + while (next) { + range_node = rb_entry(next, struct regmap_range_node, node); + + if (range_node->name) + debugfs_create_file(range_node->name, 0400, + map->debugfs, range_node, + ®map_range_fops); + + next = rb_next(&range_node->node); + } } void regmap_debugfs_exit(struct regmap *map) diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 52069d29ff1..96253cd949e 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -519,20 +519,38 @@ struct regmap *regmap_init(struct device *dev, } map->range_tree = RB_ROOT; - for (i = 0; i < config->n_ranges; i++) { + for (i = 0; i < config->num_ranges; i++) { const struct regmap_range_cfg *range_cfg = &config->ranges[i]; struct regmap_range_node *new; /* Sanity check */ - if (range_cfg->range_max < range_cfg->range_min || - range_cfg->range_max > map->max_register || - range_cfg->selector_reg > map->max_register || - range_cfg->window_len == 0) + if (range_cfg->range_max < range_cfg->range_min) { + dev_err(map->dev, "Invalid range %d: %d < %d\n", i, + range_cfg->range_max, range_cfg->range_min); goto err_range; + } + + if (range_cfg->range_max > map->max_register) { + dev_err(map->dev, "Invalid range %d: %d > %d\n", i, + range_cfg->range_max, map->max_register); + goto err_range; + } + + if (range_cfg->selector_reg > map->max_register) { + dev_err(map->dev, + "Invalid range %d: selector out of map\n", i); + goto err_range; + } + + if (range_cfg->window_len == 0) { + dev_err(map->dev, "Invalid range %d: window_len 0\n", + i); + goto err_range; + } /* Make sure, that this register range has no selector or data window within its boundary */ - for (j = 0; j < config->n_ranges; j++) { + for (j = 0; j < config->num_ranges; j++) { unsigned sel_reg = config->ranges[j].selector_reg; unsigned win_min = config->ranges[j].window_start; unsigned win_max = win_min + @@ -540,11 +558,17 @@ struct regmap *regmap_init(struct device *dev, if (range_cfg->range_min <= sel_reg && sel_reg <= range_cfg->range_max) { + dev_err(map->dev, + "Range %d: selector for %d in window\n", + i, j); goto err_range; } if (!(win_max < range_cfg->range_min || win_min > range_cfg->range_max)) { + dev_err(map->dev, + "Range %d: window for %d in window\n", + i, j); goto err_range; } } @@ -555,6 +579,8 @@ struct regmap *regmap_init(struct device *dev, goto err_range; } + new->map = map; + new->name = range_cfg->name; new->range_min = range_cfg->range_min; new->range_max = range_cfg->range_max; new->selector_reg = range_cfg->selector_reg; @@ -564,6 +590,7 @@ struct regmap *regmap_init(struct device *dev, new->window_len = range_cfg->window_len; if (_regmap_range_add(map, new) == false) { + dev_err(map->dev, "Failed to add range %d\n", i); kfree(new); goto err_range; } @@ -579,7 +606,7 @@ struct regmap *regmap_init(struct device *dev, } ret = regcache_init(map, config); - if (ret < 0) + if (ret != 0) goto err_range; regmap_debugfs_init(map, config->name); @@ -738,59 +765,57 @@ struct regmap *dev_get_regmap(struct device *dev, const char *name) EXPORT_SYMBOL_GPL(dev_get_regmap); static int _regmap_select_page(struct regmap *map, unsigned int *reg, + struct regmap_range_node *range, unsigned int val_num) { - struct regmap_range_node *range; void *orig_work_buf; unsigned int win_offset; unsigned int win_page; bool page_chg; int ret; - range = _regmap_range_lookup(map, *reg); - if (range) { - win_offset = (*reg - range->range_min) % range->window_len; - win_page = (*reg - range->range_min) / range->window_len; - - if (val_num > 1) { - /* Bulk write shouldn't cross range boundary */ - if (*reg + val_num - 1 > range->range_max) - return -EINVAL; + win_offset = (*reg - range->range_min) % range->window_len; + win_page = (*reg - range->range_min) / range->window_len; - /* ... or single page boundary */ - if (val_num > range->window_len - win_offset) - return -EINVAL; - } + if (val_num > 1) { + /* Bulk write shouldn't cross range boundary */ + if (*reg + val_num - 1 > range->range_max) + return -EINVAL; - /* It is possible to have selector register inside data window. - In that case, selector register is located on every page and - it needs no page switching, when accessed alone. */ - if (val_num > 1 || - range->window_start + win_offset != range->selector_reg) { - /* Use separate work_buf during page switching */ - orig_work_buf = map->work_buf; - map->work_buf = map->selector_work_buf; + /* ... or single page boundary */ + if (val_num > range->window_len - win_offset) + return -EINVAL; + } - ret = _regmap_update_bits(map, range->selector_reg, - range->selector_mask, - win_page << range->selector_shift, - &page_chg); + /* It is possible to have selector register inside data window. + In that case, selector register is located on every page and + it needs no page switching, when accessed alone. */ + if (val_num > 1 || + range->window_start + win_offset != range->selector_reg) { + /* Use separate work_buf during page switching */ + orig_work_buf = map->work_buf; + map->work_buf = map->selector_work_buf; - map->work_buf = orig_work_buf; + ret = _regmap_update_bits(map, range->selector_reg, + range->selector_mask, + win_page << range->selector_shift, + &page_chg); - if (ret < 0) - return ret; - } + map->work_buf = orig_work_buf; - *reg = range->window_start + win_offset; + if (ret != 0) + return ret; } + *reg = range->window_start + win_offset; + return 0; } static int _regmap_raw_write(struct regmap *map, unsigned int reg, const void *val, size_t val_len) { + struct regmap_range_node *range; u8 *u8 = map->work_buf; void *buf; int ret = -ENOTSUPP; @@ -825,9 +850,35 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, } } - ret = _regmap_select_page(map, ®, val_len / map->format.val_bytes); - if (ret < 0) - return ret; + range = _regmap_range_lookup(map, reg); + if (range) { + int val_num = val_len / map->format.val_bytes; + int win_offset = (reg - range->range_min) % range->window_len; + int win_residue = range->window_len - win_offset; + + /* If the write goes beyond the end of the window split it */ + while (val_num > win_residue) { + dev_dbg(map->dev, "Writing window %d/%d\n", + win_residue, val_len / map->format.val_bytes); + ret = _regmap_raw_write(map, reg, val, win_residue * + map->format.val_bytes); + if (ret != 0) + return ret; + + reg += win_residue; + val_num -= win_residue; + val += win_residue * map->format.val_bytes; + val_len -= win_residue * map->format.val_bytes; + + win_offset = (reg - range->range_min) % + range->window_len; + win_residue = range->window_len - win_offset; + } + + ret = _regmap_select_page(map, ®, range, val_num); + if (ret != 0) + return ret; + } map->format.format_reg(map->work_buf, reg, map->reg_shift); @@ -876,6 +927,7 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, int _regmap_write(struct regmap *map, unsigned int reg, unsigned int val) { + struct regmap_range_node *range; int ret; BUG_ON(!map->format.format_write && !map->format.format_val); @@ -897,9 +949,12 @@ int _regmap_write(struct regmap *map, unsigned int reg, trace_regmap_reg_write(map->dev, reg, val); if (map->format.format_write) { - ret = _regmap_select_page(map, ®, 1); - if (ret < 0) - return ret; + range = _regmap_range_lookup(map, reg); + if (range) { + ret = _regmap_select_page(map, ®, range, 1); + if (ret != 0) + return ret; + } map->format.format_write(map, reg, val); @@ -1055,12 +1110,17 @@ EXPORT_SYMBOL_GPL(regmap_bulk_write); static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, unsigned int val_len) { + struct regmap_range_node *range; u8 *u8 = map->work_buf; int ret; - ret = _regmap_select_page(map, ®, val_len / map->format.val_bytes); - if (ret < 0) - return ret; + range = _regmap_range_lookup(map, reg); + if (range) { + ret = _regmap_select_page(map, ®, range, + val_len / map->format.val_bytes); + if (ret != 0) + return ret; + } map->format.format_reg(map->work_buf, reg, map->reg_shift); diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 7c0f1ecfdd7..104a7c3153c 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -72,6 +72,16 @@ config INPUT_AD714X_SPI To compile this driver as a module, choose M here: the module will be called ad714x-spi. +config INPUT_ARIZONA_HAPTICS + tristate "Arizona haptics support" + depends on MFD_ARIZONA && SND_SOC + select INPUT_FF_MEMLESS + help + Say Y to enable support for the haptics module in Arizona CODECs. + + To compile this driver as a module, choose M here: the + module will be called arizona-haptics. + config INPUT_BMA150 tristate "BMA150/SMB380 acceleration sensor support" depends on I2C diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 83fe6f5b77d..5ea769eda99 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_INPUT_ADXL34X) += adxl34x.o obj-$(CONFIG_INPUT_ADXL34X_I2C) += adxl34x-i2c.o obj-$(CONFIG_INPUT_ADXL34X_SPI) += adxl34x-spi.o obj-$(CONFIG_INPUT_APANEL) += apanel.o +obj-$(CONFIG_INPUT_ARIZONA_HAPTICS) += arizona-haptics.o obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o 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 00000000000..7a04f54ef96 --- /dev/null +++ b/drivers/input/misc/arizona-haptics.c @@ -0,0 +1,255 @@ +/* + * Arizona haptics driver + * + * Copyright 2012 Wolfson Microelectronics plc + * + * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/input.h> +#include <linux/slab.h> + +#include <sound/soc.h> +#include <sound/soc-dapm.h> + +#include <linux/mfd/arizona/core.h> +#include <linux/mfd/arizona/pdata.h> +#include <linux/mfd/arizona/registers.h> + +struct arizona_haptics { + struct arizona *arizona; + struct input_dev *input_dev; + struct work_struct work; + + struct mutex mutex; + u8 intensity; +}; + +static void arizona_haptics_work(struct work_struct *work) +{ + struct arizona_haptics *haptics = container_of(work, + struct arizona_haptics, + work); + struct arizona *arizona = haptics->arizona; + struct mutex *dapm_mutex = &arizona->dapm->card->dapm_mutex; + int ret; + + if (!haptics->arizona->dapm) { + dev_err(arizona->dev, "No DAPM context\n"); + return; + } + + if (haptics->intensity) { + ret = regmap_update_bits(arizona->regmap, + ARIZONA_HAPTICS_PHASE_2_INTENSITY, + ARIZONA_PHASE2_INTENSITY_MASK, + haptics->intensity); + if (ret != 0) { + dev_err(arizona->dev, "Failed to set intensity: %d\n", + ret); + return; + } + + /* This enable sequence will be a noop if already enabled */ + ret = regmap_update_bits(arizona->regmap, + ARIZONA_HAPTICS_CONTROL_1, + ARIZONA_HAP_CTRL_MASK, + 1 << ARIZONA_HAP_CTRL_SHIFT); + if (ret != 0) { + dev_err(arizona->dev, "Failed to start haptics: %d\n", + ret); + return; + } + + mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); + + ret = snd_soc_dapm_enable_pin(arizona->dapm, "HAPTICS"); + if (ret != 0) { + dev_err(arizona->dev, "Failed to start HAPTICS: %d\n", + ret); + mutex_unlock(dapm_mutex); + return; + } + + ret = snd_soc_dapm_sync(arizona->dapm); + if (ret != 0) { + dev_err(arizona->dev, "Failed to sync DAPM: %d\n", + ret); + mutex_unlock(dapm_mutex); + return; + } + + mutex_unlock(dapm_mutex); + + } else { + /* This disable sequence will be a noop if already enabled */ + mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); + + ret = snd_soc_dapm_disable_pin(arizona->dapm, "HAPTICS"); + if (ret != 0) { + dev_err(arizona->dev, "Failed to disable HAPTICS: %d\n", + ret); + mutex_unlock(dapm_mutex); + return; + } + + ret = snd_soc_dapm_sync(arizona->dapm); + if (ret != 0) { + dev_err(arizona->dev, "Failed to sync DAPM: %d\n", + ret); + mutex_unlock(dapm_mutex); + return; + } + + mutex_unlock(dapm_mutex); + + ret = regmap_update_bits(arizona->regmap, + ARIZONA_HAPTICS_CONTROL_1, + ARIZONA_HAP_CTRL_MASK, + 1 << ARIZONA_HAP_CTRL_SHIFT); + if (ret != 0) { + dev_err(arizona->dev, "Failed to stop haptics: %d\n", + ret); + return; + } + } +} + +static int arizona_haptics_play(struct input_dev *input, void *data, + struct ff_effect *effect) +{ + struct arizona_haptics *haptics = input_get_drvdata(input); + struct arizona *arizona = haptics->arizona; + + if (!arizona->dapm) { + dev_err(arizona->dev, "No DAPM context\n"); + return -EBUSY; + } + + if (effect->u.rumble.strong_magnitude) { + /* Scale the magnitude into the range the device supports */ + if (arizona->pdata.hap_act) { + haptics->intensity = + effect->u.rumble.strong_magnitude >> 9; + if (effect->direction < 0x8000) + haptics->intensity += 0x7f; + } else { + haptics->intensity = + effect->u.rumble.strong_magnitude >> 8; + } + } else { + haptics->intensity = 0; + } + + schedule_work(&haptics->work); + + return 0; +} + +static void arizona_haptics_close(struct input_dev *input) +{ + struct arizona_haptics *haptics = input_get_drvdata(input); + struct mutex *dapm_mutex = &haptics->arizona->dapm->card->dapm_mutex; + + cancel_work_sync(&haptics->work); + + mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); + + if (haptics->arizona->dapm) + snd_soc_dapm_disable_pin(haptics->arizona->dapm, "HAPTICS"); + + mutex_unlock(dapm_mutex); +} + +static int arizona_haptics_probe(struct platform_device *pdev) +{ + struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); + struct arizona_haptics *haptics; + int ret; + + haptics = devm_kzalloc(&pdev->dev, sizeof(*haptics), GFP_KERNEL); + if (!haptics) + return -ENOMEM; + + haptics->arizona = arizona; + + ret = regmap_update_bits(arizona->regmap, ARIZONA_HAPTICS_CONTROL_1, + ARIZONA_HAP_ACT, arizona->pdata.hap_act); + if (ret != 0) { + dev_err(arizona->dev, "Failed to set haptics actuator: %d\n", + ret); + return ret; + } + + INIT_WORK(&haptics->work, arizona_haptics_work); + + haptics->input_dev = input_allocate_device(); + if (haptics->input_dev == NULL) { + dev_err(arizona->dev, "Failed to allocate input device\n"); + return -ENOMEM; + } + + input_set_drvdata(haptics->input_dev, haptics); + + haptics->input_dev->name = "arizona:haptics"; + haptics->input_dev->dev.parent = pdev->dev.parent; + haptics->input_dev->close = arizona_haptics_close; + __set_bit(FF_RUMBLE, haptics->input_dev->ffbit); + + ret = input_ff_create_memless(haptics->input_dev, NULL, + arizona_haptics_play); + if (ret < 0) { + dev_err(arizona->dev, "input_ff_create_memless() failed: %d\n", + ret); + goto err_ialloc; + } + + ret = input_register_device(haptics->input_dev); + if (ret < 0) { + dev_err(arizona->dev, "couldn't register input device: %d\n", + ret); + goto err_iff; + } + + platform_set_drvdata(pdev, haptics); + + return 0; + +err_iff: + if (haptics->input_dev) + input_ff_destroy(haptics->input_dev); +err_ialloc: + input_free_device(haptics->input_dev); + + return ret; +} + +static int arizona_haptics_remove(struct platform_device *pdev) +{ + struct arizona_haptics *haptics = platform_get_drvdata(pdev); + + input_unregister_device(haptics->input_dev); + + return 0; +} + +static struct platform_driver arizona_haptics_driver = { + .probe = arizona_haptics_probe, + .remove = arizona_haptics_remove, + .driver = { + .name = "arizona-haptics", + .owner = THIS_MODULE, + }, +}; +module_platform_driver(arizona_haptics_driver); + +MODULE_ALIAS("platform:arizona-haptics"); +MODULE_DESCRIPTION("Arizona haptics driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index 1b48f209480..75619711a9e 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c @@ -272,6 +272,7 @@ static struct mfd_cell early_devs[] = { static struct mfd_cell wm5102_devs[] = { { .name = "arizona-extcon" }, { .name = "arizona-gpio" }, + { .name = "arizona-haptics" }, { .name = "arizona-micsupp" }, { .name = "arizona-pwm" }, { .name = "wm5102-codec" }, @@ -280,6 +281,7 @@ static struct mfd_cell wm5102_devs[] = { static struct mfd_cell wm5110_devs[] = { { .name = "arizona-extcon" }, { .name = "arizona-gpio" }, + { .name = "arizona-haptics" }, { .name = "arizona-micsupp" }, { .name = "arizona-pwm" }, { .name = "wm5110-codec" }, diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index 8fefc961ec0..45a20c573aa 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[] = { */ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) { - struct wm8994_pdata *pdata = wm8994->dev->platform_data; + struct wm8994_pdata *pdata; struct regmap_config *regmap_config; const struct reg_default *regmap_patch = NULL; const char *devname; int ret, i, patch_regs; int pulls = 0; + if (dev_get_platdata(wm8994->dev)) { + pdata = dev_get_platdata(wm8994->dev); + wm8994->pdata = *pdata; + } + pdata = &wm8994->pdata; + dev_set_drvdata(wm8994->dev, wm8994); /* Add the on-chip regulators first for bootstrapping */ @@ -604,24 +610,21 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) } } - if (pdata) { - wm8994->irq_base = pdata->irq_base; - wm8994->gpio_base = pdata->gpio_base; - - /* GPIO configuration is only applied if it's non-zero */ - for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) { - if (pdata->gpio_defaults[i]) { - wm8994_set_bits(wm8994, WM8994_GPIO_1 + i, - 0xffff, - pdata->gpio_defaults[i]); - } + wm8994->irq_base = pdata->irq_base; + wm8994->gpio_base = pdata->gpio_base; + + /* GPIO configuration is only applied if it's non-zero */ + for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) { + if (pdata->gpio_defaults[i]) { + wm8994_set_bits(wm8994, WM8994_GPIO_1 + i, + 0xffff, pdata->gpio_defaults[i]); } + } - wm8994->ldo_ena_always_driven = pdata->ldo_ena_always_driven; + wm8994->ldo_ena_always_driven = pdata->ldo_ena_always_driven; - if (pdata->spkmode_pu) - pulls |= WM8994_SPKMODE_PU; - } + if (pdata->spkmode_pu) + pulls |= WM8994_SPKMODE_PU; /* Disable unneeded pulls */ wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2, diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c index 5bb18778107..d07a9eda7ff 100644 --- a/drivers/misc/atmel-ssc.c +++ b/drivers/misc/atmel-ssc.c @@ -18,6 +18,8 @@ #include <linux/slab.h> #include <linux/module.h> +#include <linux/of.h> + /* Serialize access to ssc_list and user count */ static DEFINE_SPINLOCK(user_lock); static LIST_HEAD(ssc_list); @@ -29,7 +31,13 @@ struct ssc_device *ssc_request(unsigned int ssc_num) spin_lock(&user_lock); list_for_each_entry(ssc, &ssc_list, list) { - if (ssc->pdev->id == ssc_num) { + if (ssc->pdev->dev.of_node) { + if (of_alias_get_id(ssc->pdev->dev.of_node, "ssc") + == ssc_num) { + ssc_valid = 1; + break; + } + } else if (ssc->pdev->id == ssc_num) { ssc_valid = 1; break; } @@ -68,39 +76,93 @@ void ssc_free(struct ssc_device *ssc) } EXPORT_SYMBOL(ssc_free); -static int __init ssc_probe(struct platform_device *pdev) +static struct atmel_ssc_platform_data at91rm9200_config = { + .use_dma = 0, +}; + +static struct atmel_ssc_platform_data at91sam9g45_config = { + .use_dma = 1, +}; + +static const struct platform_device_id atmel_ssc_devtypes[] = { + { + .name = "at91rm9200_ssc", + .driver_data = (unsigned long) &at91rm9200_config, + }, { + .name = "at91sam9g45_ssc", + .driver_data = (unsigned long) &at91sam9g45_config, + }, { + /* sentinel */ + } +}; + +#ifdef CONFIG_OF +static const struct of_device_id atmel_ssc_dt_ids[] = { + { + .compatible = "atmel,at91rm9200-ssc", + .data = &at91rm9200_config, + }, { + .compatible = "atmel,at91sam9g45-ssc", + .data = &at91sam9g45_config, + }, { + /* sentinel */ + } +}; +MODULE_DEVICE_TABLE(of, atmel_ssc_dt_ids); +#endif + +static inline const struct atmel_ssc_platform_data * __init + atmel_ssc_get_driver_data(struct platform_device *pdev) +{ + if (pdev->dev.of_node) { + const struct of_device_id *match; + match = of_match_node(atmel_ssc_dt_ids, pdev->dev.of_node); + if (match == NULL) + return NULL; + return match->data; + } + + return (struct atmel_ssc_platform_data *) + platform_get_device_id(pdev)->driver_data; +} + +static int ssc_probe(struct platform_device *pdev) { - int retval = 0; struct resource *regs; struct ssc_device *ssc; + const struct atmel_ssc_platform_data *plat_dat; - ssc = kzalloc(sizeof(struct ssc_device), GFP_KERNEL); + ssc = devm_kzalloc(&pdev->dev, sizeof(struct ssc_device), GFP_KERNEL); if (!ssc) { dev_dbg(&pdev->dev, "out of memory\n"); - retval = -ENOMEM; - goto out; + return -ENOMEM; } + ssc->pdev = pdev; + + plat_dat = atmel_ssc_get_driver_data(pdev); + if (!plat_dat) + return -ENODEV; + ssc->pdata = (struct atmel_ssc_platform_data *)plat_dat; + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!regs) { dev_dbg(&pdev->dev, "no mmio resource defined\n"); - retval = -ENXIO; - goto out_free; + return -ENXIO; } - ssc->clk = clk_get(&pdev->dev, "pclk"); - if (IS_ERR(ssc->clk)) { - dev_dbg(&pdev->dev, "no pclk clock defined\n"); - retval = -ENXIO; - goto out_free; - } - - ssc->pdev = pdev; - ssc->regs = ioremap(regs->start, resource_size(regs)); + ssc->regs = devm_request_and_ioremap(&pdev->dev, regs); if (!ssc->regs) { dev_dbg(&pdev->dev, "ioremap failed\n"); - retval = -EINVAL; - goto out_clk; + return -EINVAL; + } + + ssc->phybase = regs->start; + + ssc->clk = devm_clk_get(&pdev->dev, "pclk"); + if (IS_ERR(ssc->clk)) { + dev_dbg(&pdev->dev, "no pclk clock defined\n"); + return -ENXIO; } /* disable all interrupts */ @@ -112,8 +174,7 @@ static int __init ssc_probe(struct platform_device *pdev) ssc->irq = platform_get_irq(pdev, 0); if (!ssc->irq) { dev_dbg(&pdev->dev, "could not get irq\n"); - retval = -ENXIO; - goto out_unmap; + return -ENXIO; } spin_lock(&user_lock); @@ -125,16 +186,7 @@ static int __init ssc_probe(struct platform_device *pdev) dev_info(&pdev->dev, "Atmel SSC device at 0x%p (irq %d)\n", ssc->regs, ssc->irq); - goto out; - -out_unmap: - iounmap(ssc->regs); -out_clk: - clk_put(ssc->clk); -out_free: - kfree(ssc); -out: - return retval; + return 0; } static int __devexit ssc_remove(struct platform_device *pdev) @@ -142,34 +194,23 @@ static int __devexit ssc_remove(struct platform_device *pdev) struct ssc_device *ssc = platform_get_drvdata(pdev); spin_lock(&user_lock); - iounmap(ssc->regs); - clk_put(ssc->clk); list_del(&ssc->list); - kfree(ssc); spin_unlock(&user_lock); return 0; } static struct platform_driver ssc_driver = { - .remove = __devexit_p(ssc_remove), .driver = { .name = "ssc", .owner = THIS_MODULE, + .of_match_table = of_match_ptr(atmel_ssc_dt_ids), }, + .id_table = atmel_ssc_devtypes, + .probe = ssc_probe, + .remove = __devexit_p(ssc_remove), }; - -static int __init ssc_init(void) -{ - return platform_driver_probe(&ssc_driver, ssc_probe); -} -module_init(ssc_init); - -static void __exit ssc_exit(void) -{ - platform_driver_unregister(&ssc_driver); -} -module_exit(ssc_exit); +module_platform_driver(ssc_driver); MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>"); MODULE_DESCRIPTION("SSC driver for Atmel AVR32 and AT91"); diff --git a/include/linux/atmel-ssc.h b/include/linux/atmel-ssc.h index 4eb31752e2b..deb0ae58b99 100644 --- a/include/linux/atmel-ssc.h +++ b/include/linux/atmel-ssc.h @@ -5,10 +5,16 @@ #include <linux/list.h> #include <linux/io.h> +struct atmel_ssc_platform_data { + int use_dma; +}; + struct ssc_device { struct list_head list; + resource_size_t phybase; void __iomem *regs; struct platform_device *pdev; + struct atmel_ssc_platform_data *pdata; struct clk *clk; int user; int irq; diff --git a/include/linux/mfd/arizona/core.h b/include/linux/mfd/arizona/core.h index dd231ac0bb1..a580363a7d2 100644 --- a/include/linux/mfd/arizona/core.h +++ b/include/linux/mfd/arizona/core.h @@ -78,6 +78,8 @@ enum arizona_type { #define ARIZONA_NUM_IRQ 50 +struct snd_soc_dapm_context; + struct arizona { struct regmap *regmap; struct device *dev; @@ -98,6 +100,8 @@ struct arizona { struct mutex clk_lock; int clk32k_ref; + + struct snd_soc_dapm_context *dapm; }; int arizona_clk32k_enable(struct arizona *arizona); diff --git a/include/linux/mfd/arizona/pdata.h b/include/linux/mfd/arizona/pdata.h index 7ab442905a5..8b1d1daaae1 100644 --- a/include/linux/mfd/arizona/pdata.h +++ b/include/linux/mfd/arizona/pdata.h @@ -62,6 +62,9 @@ #define ARIZONA_MAX_OUTPUT 6 +#define ARIZONA_HAP_ACT_ERM 0 +#define ARIZONA_HAP_ACT_LRA 2 + #define ARIZONA_MAX_PDM_SPK 2 struct regulator_init_data; @@ -114,6 +117,9 @@ struct arizona_pdata { /** PDM speaker format */ unsigned int spk_fmt[ARIZONA_MAX_PDM_SPK]; + + /** Haptic actuator type */ + unsigned int hap_act; }; #endif diff --git a/include/linux/mfd/wm8994/core.h b/include/linux/mfd/wm8994/core.h index 1f173306bf0..ae5c249530b 100644 --- a/include/linux/mfd/wm8994/core.h +++ b/include/linux/mfd/wm8994/core.h @@ -19,6 +19,8 @@ #include <linux/interrupt.h> #include <linux/regmap.h> +#include <linux/mfd/wm8994/pdata.h> + enum wm8994_type { WM8994 = 0, WM8958 = 1, @@ -55,6 +57,8 @@ struct regulator_bulk_data; struct wm8994 { struct mutex irq_lock; + struct wm8994_pdata pdata; + enum wm8994_type type; int revision; int cust_id; diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h index fc87be4fdc2..8e21a094836 100644 --- a/include/linux/mfd/wm8994/pdata.h +++ b/include/linux/mfd/wm8994/pdata.h @@ -176,6 +176,11 @@ struct wm8994_pdata { unsigned int lineout1fb:1; unsigned int lineout2fb:1; + /* Delay between detecting a jack and starting microphone + * detect (specified in ms) + */ + int micdet_delay; + /* IRQ for microphone detection if brought out directly as a * signal. */ diff --git a/include/linux/platform_data/asoc-s3c.h b/include/linux/platform_data/asoc-s3c.h index aa9875f77c4..88272591a89 100644 --- a/include/linux/platform_data/asoc-s3c.h +++ b/include/linux/platform_data/asoc-s3c.h @@ -38,12 +38,6 @@ struct samsung_i2s { #define QUIRK_NEED_RSTCLR (1 << 3) /* Quirks of the I2S controller */ u32 quirks; - - /* - * Array of clock names that can be used to generate I2S signals. - * Also corresponds to clocks of I2SMOD[10] - */ - const char **src_clk; dma_addr_t idma_addr; }; diff --git a/include/linux/platform_data/davinci_asp.h b/include/linux/platform_data/davinci_asp.h index d0c5825876f..8db5ae03b6e 100644 --- a/include/linux/platform_data/davinci_asp.h +++ b/include/linux/platform_data/davinci_asp.h @@ -16,12 +16,13 @@ #ifndef __DAVINCI_ASP_H #define __DAVINCI_ASP_H +#include <linux/genalloc.h> + struct snd_platform_data { u32 tx_dma_offset; u32 rx_dma_offset; int asp_chan_q; /* event queue number for ASP channel */ int ram_chan_q; /* event queue number for RAM channel */ - unsigned int codec_fmt; /* * Allowing this is more efficient and eliminates left and right swaps * caused by underruns, but will swap the left and right channels @@ -30,6 +31,7 @@ struct snd_platform_data { unsigned enable_channel_combine:1; unsigned sram_size_playback; unsigned sram_size_capture; + struct gen_pool *sram_pool; /* * If McBSP peripheral gets the clock from an external pin, diff --git a/include/linux/platform_data/omap-twl4030.h b/include/linux/platform_data/omap-twl4030.h index c7bef788daa..ee60ef79d79 100644 --- a/include/linux/platform_data/omap-twl4030.h +++ b/include/linux/platform_data/omap-twl4030.h @@ -25,8 +25,34 @@ #ifndef _OMAP_TWL4030_H_ #define _OMAP_TWL4030_H_ +/* To select if only one channel is connected in a stereo port */ +#define OMAP_TWL4030_LEFT (1 << 0) +#define OMAP_TWL4030_RIGHT (1 << 1) + struct omap_tw4030_pdata { const char *card_name; + /* Voice port is connected to McBSP3 */ + bool voice_connected; + + /* The driver will parse the connection flags if this flag is set */ + bool custom_routing; + /* Flags to indicate connected audio ports. */ + u8 has_hs; + u8 has_hf; + u8 has_predriv; + u8 has_carkit; + bool has_ear; + + bool has_mainmic; + bool has_submic; + bool has_hsmic; + bool has_carkitmic; + bool has_digimic0; + bool has_digimic1; + u8 has_linein; + + /* Jack detect GPIO or <= 0 if it is not implemented */ + int jack_detect; }; #endif /* _OMAP_TWL4030_H_ */ diff --git a/include/linux/regmap.h b/include/linux/regmap.h index e3bcc3f4dcb..9f228d7f7ac 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -133,7 +133,7 @@ struct regmap_config { enum regmap_endian val_format_endian; const struct regmap_range_cfg *ranges; - unsigned int n_ranges; + unsigned int num_ranges; }; /** @@ -142,6 +142,8 @@ struct regmap_config { * 1. page selector register update; * 2. access through data window registers. * + * @name: Descriptive name for diagnostics + * * @range_min: Address of the lowest register address in virtual range. * @range_max: Address of the highest register in virtual range. * @@ -153,6 +155,8 @@ struct regmap_config { * @window_len: Number of registers in data window. */ struct regmap_range_cfg { + const char *name; + /* Registers of virtual address range */ unsigned int range_min; unsigned int range_max; diff --git a/include/sound/cs4271.h b/include/sound/cs4271.h index 50a059e7d11..6d9e15ed1dc 100644 --- a/include/sound/cs4271.h +++ b/include/sound/cs4271.h @@ -19,6 +19,7 @@ struct cs4271_platform_data { int gpio_nreset; /* GPIO driving Reset pin, if any */ + int amutec_eq_bmutec:1; /* flag to enable AMUTEC=BMUTEC */ }; #endif /* __CS4271_H */ diff --git a/include/sound/sh_fsi.h b/include/sound/sh_fsi.h index 906010344dd..cc1c919c643 100644 --- a/include/sound/sh_fsi.h +++ b/include/sound/sh_fsi.h @@ -26,6 +26,7 @@ * A: inversion * B: format mode * C: chip specific + * D: clock selecter if master mode */ /* A: clock inversion */ @@ -44,6 +45,11 @@ #define SH_FSI_OPTION_MASK 0x00000F00 #define SH_FSI_ENABLE_STREAM_MODE (1 << 8) /* for 16bit data */ +/* D: clock selecter if master mode */ +#define SH_FSI_CLK_MASK 0x0000F000 +#define SH_FSI_CLK_EXTERNAL (0 << 12) +#define SH_FSI_CLK_CPG (1 << 12) /* FSIxCK + FSI-DIV */ + /* * set_rate return value * diff --git a/include/sound/tlv320aic32x4.h b/include/sound/tlv320aic32x4.h index c009f70b402..24e5d991f14 100644 --- a/include/sound/tlv320aic32x4.h +++ b/include/sound/tlv320aic32x4.h @@ -26,6 +26,7 @@ struct aic32x4_pdata { u32 power_cfg; u32 micpga_routing; bool swapdacs; + int rstn_gpio; }; #endif diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig index 72b09cfd3dc..d1b691bf8e2 100644 --- a/sound/soc/atmel/Kconfig +++ b/sound/soc/atmel/Kconfig @@ -6,6 +6,14 @@ config SND_ATMEL_SOC the ATMEL SSC interface. You will also need to select the audio interfaces to support below. +config SND_ATMEL_SOC_PDC + tristate + depends on SND_ATMEL_SOC + +config SND_ATMEL_SOC_DMA + tristate + depends on SND_ATMEL_SOC + config SND_ATMEL_SOC_SSC tristate depends on SND_ATMEL_SOC @@ -16,8 +24,8 @@ config SND_ATMEL_SOC_SSC config SND_AT91_SOC_SAM9G20_WM8731 tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board" - depends on ATMEL_SSC && ARCH_AT91SAM9G20 && SND_ATMEL_SOC && \ - AT91_PROGRAMMABLE_CLOCKS + depends on ATMEL_SSC && SND_ATMEL_SOC && AT91_PROGRAMMABLE_CLOCKS + select SND_ATMEL_SOC_PDC select SND_ATMEL_SOC_SSC select SND_SOC_WM8731 help @@ -27,6 +35,7 @@ config SND_AT91_SOC_SAM9G20_WM8731 config SND_AT91_SOC_AFEB9260 tristate "SoC Audio support for AFEB9260 board" depends on ATMEL_SSC && ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC + select SND_ATMEL_SOC_PDC select SND_ATMEL_SOC_SSC select SND_SOC_TLV320AIC23 help diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile index a5c0bf19da7..41967ccb6f4 100644 --- a/sound/soc/atmel/Makefile +++ b/sound/soc/atmel/Makefile @@ -1,8 +1,12 @@ # AT91 Platform Support snd-soc-atmel-pcm-objs := atmel-pcm.o +snd-soc-atmel-pcm-pdc-objs := atmel-pcm-pdc.o +snd-soc-atmel-pcm-dma-objs := atmel-pcm-dma.o snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o obj-$(CONFIG_SND_ATMEL_SOC) += snd-soc-atmel-pcm.o +obj-$(CONFIG_SND_ATMEL_SOC_PDC) += snd-soc-atmel-pcm-pdc.o +obj-$(CONFIG_SND_ATMEL_SOC_DMA) += snd-soc-atmel-pcm-dma.o obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o # 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 00000000000..30184a4a147 --- /dev/null +++ b/sound/soc/atmel/atmel-pcm-dma.c @@ -0,0 +1,240 @@ +/* + * atmel-pcm-dma.c -- ALSA PCM DMA support for the Atmel SoC. + * + * Copyright (C) 2012 Atmel + * + * Author: Bo Shen <voice.shen@atmel.com> + * + * Based on atmel-pcm by: + * Sedji Gaouaou <sedji.gaouaou@atmel.com> + * Copyright 2008 Atmel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/dma-mapping.h> +#include <linux/dmaengine.h> +#include <linux/atmel-ssc.h> +#include <linux/platform_data/dma-atmel.h> + +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/soc.h> +#include <sound/dmaengine_pcm.h> + +#include "atmel-pcm.h" + +/*--------------------------------------------------------------------------*\ + * Hardware definition +\*--------------------------------------------------------------------------*/ +static const struct snd_pcm_hardware atmel_pcm_dma_hardware = { + .info = SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_RESUME | + SNDRV_PCM_INFO_PAUSE, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .period_bytes_min = 256, /* lighting DMA overhead */ + .period_bytes_max = 2 * 0xffff, /* if 2 bytes format */ + .periods_min = 8, + .periods_max = 1024, /* no limit */ + .buffer_bytes_max = ATMEL_SSC_DMABUF_SIZE, +}; + +/** + * atmel_pcm_dma_irq: SSC interrupt handler for DMAENGINE enabled SSC + * + * We use DMAENGINE to send/receive data to/from SSC so this ISR is only to + * check if any overrun occured. + */ +static void atmel_pcm_dma_irq(u32 ssc_sr, + struct snd_pcm_substream *substream) +{ + struct atmel_pcm_dma_params *prtd; + + prtd = snd_dmaengine_pcm_get_data(substream); + + if (ssc_sr & prtd->mask->ssc_error) { + if (snd_pcm_running(substream)) + pr_warn("atmel-pcm: buffer %s on %s (SSC_SR=%#x)\n", + substream->stream == SNDRV_PCM_STREAM_PLAYBACK + ? "underrun" : "overrun", prtd->name, + ssc_sr); + + /* stop RX and capture: will be enabled again at restart */ + ssc_writex(prtd->ssc->regs, SSC_CR, prtd->mask->ssc_disable); + snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); + + /* now drain RHR and read status to remove xrun condition */ + ssc_readx(prtd->ssc->regs, SSC_RHR); + ssc_readx(prtd->ssc->regs, SSC_SR); + } +} + +/*--------------------------------------------------------------------------*\ + * DMAENGINE operations +\*--------------------------------------------------------------------------*/ +static bool filter(struct dma_chan *chan, void *slave) +{ + struct at_dma_slave *sl = slave; + + if (sl->dma_dev == chan->device->dev) { + chan->private = sl; + return true; + } else { + return false; + } +} + +static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct atmel_pcm_dma_params *prtd; + struct ssc_device *ssc; + struct dma_chan *dma_chan; + struct dma_slave_config slave_config; + int ret; + + prtd = snd_dmaengine_pcm_get_data(substream); + ssc = prtd->ssc; + + ret = snd_hwparams_to_dma_slave_config(substream, params, + &slave_config); + if (ret) { + pr_err("atmel-pcm: hwparams to dma slave configure failed\n"); + return ret; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + slave_config.dst_addr = (dma_addr_t)ssc->phybase + SSC_THR; + slave_config.dst_maxburst = 1; + } else { + slave_config.src_addr = (dma_addr_t)ssc->phybase + SSC_RHR; + slave_config.src_maxburst = 1; + } + + slave_config.device_fc = false; + + dma_chan = snd_dmaengine_pcm_get_chan(substream); + if (dmaengine_slave_config(dma_chan, &slave_config)) { + pr_err("atmel-pcm: failed to configure dma channel\n"); + ret = -EBUSY; + return ret; + } + + return 0; +} + +static int atmel_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct atmel_pcm_dma_params *prtd; + struct ssc_device *ssc; + struct at_dma_slave *sdata = NULL; + int ret; + + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); + + prtd = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); + ssc = prtd->ssc; + if (ssc->pdev) + sdata = ssc->pdev->dev.platform_data; + + ret = snd_dmaengine_pcm_open(substream, filter, sdata); + if (ret) { + pr_err("atmel-pcm: dmaengine pcm open failed\n"); + return -EINVAL; + } + + snd_dmaengine_pcm_set_data(substream, prtd); + + ret = atmel_pcm_configure_dma(substream, params); + if (ret) { + pr_err("atmel-pcm: failed to configure dmai\n"); + goto err; + } + + prtd->dma_intr_handler = atmel_pcm_dma_irq; + + return 0; +err: + snd_dmaengine_pcm_close(substream); + return ret; +} + +static int atmel_pcm_dma_prepare(struct snd_pcm_substream *substream) +{ + struct atmel_pcm_dma_params *prtd; + + prtd = snd_dmaengine_pcm_get_data(substream); + + ssc_writex(prtd->ssc->regs, SSC_IER, prtd->mask->ssc_error); + ssc_writex(prtd->ssc->regs, SSC_CR, prtd->mask->ssc_enable); + + return 0; +} + +static int atmel_pcm_open(struct snd_pcm_substream *substream) +{ + snd_soc_set_runtime_hwparams(substream, &atmel_pcm_dma_hardware); + + return 0; +} + +static int atmel_pcm_close(struct snd_pcm_substream *substream) +{ + snd_dmaengine_pcm_close(substream); + + return 0; +} + +static struct snd_pcm_ops atmel_pcm_ops = { + .open = atmel_pcm_open, + .close = atmel_pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = atmel_pcm_hw_params, + .prepare = atmel_pcm_dma_prepare, + .trigger = snd_dmaengine_pcm_trigger, + .pointer = snd_dmaengine_pcm_pointer_no_residue, + .mmap = atmel_pcm_mmap, +}; + +static struct snd_soc_platform_driver atmel_soc_platform = { + .ops = &atmel_pcm_ops, + .pcm_new = atmel_pcm_new, + .pcm_free = atmel_pcm_free, +}; + +int atmel_pcm_dma_platform_register(struct device *dev) +{ + return snd_soc_register_platform(dev, &atmel_soc_platform); +} +EXPORT_SYMBOL(atmel_pcm_dma_platform_register); + +void atmel_pcm_dma_platform_unregister(struct device *dev) +{ + snd_soc_unregister_platform(dev); +} +EXPORT_SYMBOL(atmel_pcm_dma_platform_unregister); + +MODULE_AUTHOR("Bo Shen <voice.shen@atmel.com>"); +MODULE_DESCRIPTION("Atmel DMA based PCM module"); +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 00000000000..6a293c713a3 --- /dev/null +++ b/sound/soc/atmel/atmel-pcm-pdc.c @@ -0,0 +1,401 @@ +/* + * atmel-pcm.c -- ALSA PCM interface for the Atmel atmel SoC. + * + * Copyright (C) 2005 SAN People + * Copyright (C) 2008 Atmel + * + * Authors: Sedji Gaouaou <sedji.gaouaou@atmel.com> + * + * Based on at91-pcm. by: + * Frank Mandarino <fmandarino@endrelia.com> + * Copyright 2006 Endrelia Technologies Inc. + * + * Based on pxa2xx-pcm.c by: + * + * Author: Nicolas Pitre + * Created: Nov 30, 2004 + * Copyright: (C) 2004 MontaVista Software, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/dma-mapping.h> +#include <linux/atmel_pdc.h> +#include <linux/atmel-ssc.h> + +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/soc.h> + +#include "atmel-pcm.h" + + +/*--------------------------------------------------------------------------*\ + * Hardware definition +\*--------------------------------------------------------------------------*/ +/* TODO: These values were taken from the AT91 platform driver, check + * them against real values for AT32 + */ +static const struct snd_pcm_hardware atmel_pcm_hardware = { + .info = SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_PAUSE, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .period_bytes_min = 32, + .period_bytes_max = 8192, + .periods_min = 2, + .periods_max = 1024, + .buffer_bytes_max = ATMEL_SSC_DMABUF_SIZE, +}; + + +/*--------------------------------------------------------------------------*\ + * Data types +\*--------------------------------------------------------------------------*/ +struct atmel_runtime_data { + struct atmel_pcm_dma_params *params; + dma_addr_t dma_buffer; /* physical address of dma buffer */ + dma_addr_t dma_buffer_end; /* first address beyond DMA buffer */ + size_t period_size; + + dma_addr_t period_ptr; /* physical address of next period */ + + /* PDC register save */ + u32 pdc_xpr_save; + u32 pdc_xcr_save; + u32 pdc_xnpr_save; + u32 pdc_xncr_save; +}; + +/*--------------------------------------------------------------------------*\ + * ISR +\*--------------------------------------------------------------------------*/ +static void atmel_pcm_dma_irq(u32 ssc_sr, + struct snd_pcm_substream *substream) +{ + struct atmel_runtime_data *prtd = substream->runtime->private_data; + struct atmel_pcm_dma_params *params = prtd->params; + static int count; + + count++; + + if (ssc_sr & params->mask->ssc_endbuf) { + pr_warn("atmel-pcm: buffer %s on %s (SSC_SR=%#x, count=%d)\n", + substream->stream == SNDRV_PCM_STREAM_PLAYBACK + ? "underrun" : "overrun", + params->name, ssc_sr, count); + + /* re-start the PDC */ + ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, + params->mask->pdc_disable); + prtd->period_ptr += prtd->period_size; + if (prtd->period_ptr >= prtd->dma_buffer_end) + prtd->period_ptr = prtd->dma_buffer; + + ssc_writex(params->ssc->regs, params->pdc->xpr, + prtd->period_ptr); + ssc_writex(params->ssc->regs, params->pdc->xcr, + prtd->period_size / params->pdc_xfer_size); + ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, + params->mask->pdc_enable); + } + + if (ssc_sr & params->mask->ssc_endx) { + /* Load the PDC next pointer and counter registers */ + prtd->period_ptr += prtd->period_size; + if (prtd->period_ptr >= prtd->dma_buffer_end) + prtd->period_ptr = prtd->dma_buffer; + + ssc_writex(params->ssc->regs, params->pdc->xnpr, + prtd->period_ptr); + ssc_writex(params->ssc->regs, params->pdc->xncr, + prtd->period_size / params->pdc_xfer_size); + } + + snd_pcm_period_elapsed(substream); +} + + +/*--------------------------------------------------------------------------*\ + * PCM operations +\*--------------------------------------------------------------------------*/ +static int atmel_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct atmel_runtime_data *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + + /* this may get called several times by oss emulation + * with different params */ + + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); + runtime->dma_bytes = params_buffer_bytes(params); + + prtd->params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); + prtd->params->dma_intr_handler = atmel_pcm_dma_irq; + + prtd->dma_buffer = runtime->dma_addr; + prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes; + prtd->period_size = params_period_bytes(params); + + pr_debug("atmel-pcm: " + "hw_params: DMA for %s initialized " + "(dma_bytes=%u, period_size=%u)\n", + prtd->params->name, + runtime->dma_bytes, + prtd->period_size); + return 0; +} + +static int atmel_pcm_hw_free(struct snd_pcm_substream *substream) +{ + struct atmel_runtime_data *prtd = substream->runtime->private_data; + struct atmel_pcm_dma_params *params = prtd->params; + + if (params != NULL) { + ssc_writex(params->ssc->regs, SSC_PDC_PTCR, + params->mask->pdc_disable); + prtd->params->dma_intr_handler = NULL; + } + + return 0; +} + +static int atmel_pcm_prepare(struct snd_pcm_substream *substream) +{ + struct atmel_runtime_data *prtd = substream->runtime->private_data; + struct atmel_pcm_dma_params *params = prtd->params; + + ssc_writex(params->ssc->regs, SSC_IDR, + params->mask->ssc_endx | params->mask->ssc_endbuf); + ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, + params->mask->pdc_disable); + return 0; +} + +static int atmel_pcm_trigger(struct snd_pcm_substream *substream, + int cmd) +{ + struct snd_pcm_runtime *rtd = substream->runtime; + struct atmel_runtime_data *prtd = rtd->private_data; + struct atmel_pcm_dma_params *params = prtd->params; + int ret = 0; + + pr_debug("atmel-pcm:buffer_size = %ld," + "dma_area = %p, dma_bytes = %u\n", + rtd->buffer_size, rtd->dma_area, rtd->dma_bytes); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + prtd->period_ptr = prtd->dma_buffer; + + ssc_writex(params->ssc->regs, params->pdc->xpr, + prtd->period_ptr); + ssc_writex(params->ssc->regs, params->pdc->xcr, + prtd->period_size / params->pdc_xfer_size); + + prtd->period_ptr += prtd->period_size; + ssc_writex(params->ssc->regs, params->pdc->xnpr, + prtd->period_ptr); + ssc_writex(params->ssc->regs, params->pdc->xncr, + prtd->period_size / params->pdc_xfer_size); + + pr_debug("atmel-pcm: trigger: " + "period_ptr=%lx, xpr=%u, " + "xcr=%u, xnpr=%u, xncr=%u\n", + (unsigned long)prtd->period_ptr, + ssc_readx(params->ssc->regs, params->pdc->xpr), + ssc_readx(params->ssc->regs, params->pdc->xcr), + ssc_readx(params->ssc->regs, params->pdc->xnpr), + ssc_readx(params->ssc->regs, params->pdc->xncr)); + + ssc_writex(params->ssc->regs, SSC_IER, + params->mask->ssc_endx | params->mask->ssc_endbuf); + ssc_writex(params->ssc->regs, SSC_PDC_PTCR, + params->mask->pdc_enable); + + pr_debug("sr=%u imr=%u\n", + ssc_readx(params->ssc->regs, SSC_SR), + ssc_readx(params->ssc->regs, SSC_IER)); + break; /* SNDRV_PCM_TRIGGER_START */ + + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, + params->mask->pdc_disable); + break; + + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, + params->mask->pdc_enable); + break; + + default: + ret = -EINVAL; + } + + return ret; +} + +static snd_pcm_uframes_t atmel_pcm_pointer( + struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct atmel_runtime_data *prtd = runtime->private_data; + struct atmel_pcm_dma_params *params = prtd->params; + dma_addr_t ptr; + snd_pcm_uframes_t x; + + ptr = (dma_addr_t) ssc_readx(params->ssc->regs, params->pdc->xpr); + x = bytes_to_frames(runtime, ptr - prtd->dma_buffer); + + if (x == runtime->buffer_size) + x = 0; + + return x; +} + +static int atmel_pcm_open(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct atmel_runtime_data *prtd; + int ret = 0; + + snd_soc_set_runtime_hwparams(substream, &atmel_pcm_hardware); + + /* ensure that buffer size is a multiple of period size */ + ret = snd_pcm_hw_constraint_integer(runtime, + SNDRV_PCM_HW_PARAM_PERIODS); + if (ret < 0) + goto out; + + prtd = kzalloc(sizeof(struct atmel_runtime_data), GFP_KERNEL); + if (prtd == NULL) { + ret = -ENOMEM; + goto out; + } + runtime->private_data = prtd; + + out: + return ret; +} + +static int atmel_pcm_close(struct snd_pcm_substream *substream) +{ + struct atmel_runtime_data *prtd = substream->runtime->private_data; + + kfree(prtd); + return 0; +} + +static struct snd_pcm_ops atmel_pcm_ops = { + .open = atmel_pcm_open, + .close = atmel_pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = atmel_pcm_hw_params, + .hw_free = atmel_pcm_hw_free, + .prepare = atmel_pcm_prepare, + .trigger = atmel_pcm_trigger, + .pointer = atmel_pcm_pointer, + .mmap = atmel_pcm_mmap, +}; + + +/*--------------------------------------------------------------------------*\ + * ASoC platform driver +\*--------------------------------------------------------------------------*/ +#ifdef CONFIG_PM +static int atmel_pcm_suspend(struct snd_soc_dai *dai) +{ + struct snd_pcm_runtime *runtime = dai->runtime; + struct atmel_runtime_data *prtd; + struct atmel_pcm_dma_params *params; + + if (!runtime) + return 0; + + prtd = runtime->private_data; + params = prtd->params; + + /* disable the PDC and save the PDC registers */ + + ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_disable); + + prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr); + prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr); + prtd->pdc_xnpr_save = ssc_readx(params->ssc->regs, params->pdc->xnpr); + prtd->pdc_xncr_save = ssc_readx(params->ssc->regs, params->pdc->xncr); + + return 0; +} + +static int atmel_pcm_resume(struct snd_soc_dai *dai) +{ + struct snd_pcm_runtime *runtime = dai->runtime; + struct atmel_runtime_data *prtd; + struct atmel_pcm_dma_params *params; + + if (!runtime) + return 0; + + prtd = runtime->private_data; + params = prtd->params; + + /* restore the PDC registers and enable the PDC */ + ssc_writex(params->ssc->regs, params->pdc->xpr, prtd->pdc_xpr_save); + ssc_writex(params->ssc->regs, params->pdc->xcr, prtd->pdc_xcr_save); + ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save); + ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save); + + ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_enable); + return 0; +} +#else +#define atmel_pcm_suspend NULL +#define atmel_pcm_resume NULL +#endif + +static struct snd_soc_platform_driver atmel_soc_platform = { + .ops = &atmel_pcm_ops, + .pcm_new = atmel_pcm_new, + .pcm_free = atmel_pcm_free, + .suspend = atmel_pcm_suspend, + .resume = atmel_pcm_resume, +}; + +int atmel_pcm_pdc_platform_register(struct device *dev) +{ + return snd_soc_register_platform(dev, &atmel_soc_platform); +} +EXPORT_SYMBOL(atmel_pcm_pdc_platform_register); + +void atmel_pcm_pdc_platform_unregister(struct device *dev) +{ + snd_soc_unregister_platform(dev); +} +EXPORT_SYMBOL(atmel_pcm_pdc_platform_unregister); + +MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>"); +MODULE_DESCRIPTION("Atmel PCM module"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c index 9b84f985770..e99f1811300 100644 --- a/sound/soc/atmel/atmel-pcm.c +++ b/sound/soc/atmel/atmel-pcm.c @@ -32,80 +32,25 @@ */ #include <linux/module.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/slab.h> #include <linux/dma-mapping.h> -#include <linux/atmel_pdc.h> -#include <linux/atmel-ssc.h> - -#include <sound/core.h> #include <sound/pcm.h> -#include <sound/pcm_params.h> #include <sound/soc.h> - #include "atmel-pcm.h" - -/*--------------------------------------------------------------------------*\ - * Hardware definition -\*--------------------------------------------------------------------------*/ -/* TODO: These values were taken from the AT91 platform driver, check - * them against real values for AT32 - */ -static const struct snd_pcm_hardware atmel_pcm_hardware = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_PAUSE, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .period_bytes_min = 32, - .period_bytes_max = 8192, - .periods_min = 2, - .periods_max = 1024, - .buffer_bytes_max = 32 * 1024, -}; - - -/*--------------------------------------------------------------------------*\ - * Data types -\*--------------------------------------------------------------------------*/ -struct atmel_runtime_data { - struct atmel_pcm_dma_params *params; - dma_addr_t dma_buffer; /* physical address of dma buffer */ - dma_addr_t dma_buffer_end; /* first address beyond DMA buffer */ - size_t period_size; - - dma_addr_t period_ptr; /* physical address of next period */ - - /* PDC register save */ - u32 pdc_xpr_save; - u32 pdc_xcr_save; - u32 pdc_xnpr_save; - u32 pdc_xncr_save; -}; - - -/*--------------------------------------------------------------------------*\ - * Helper functions -\*--------------------------------------------------------------------------*/ static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) { struct snd_pcm_substream *substream = pcm->streams[stream].substream; struct snd_dma_buffer *buf = &substream->dma_buffer; - size_t size = atmel_pcm_hardware.buffer_bytes_max; + size_t size = ATMEL_SSC_DMABUF_SIZE; buf->dev.type = SNDRV_DMA_TYPE_DEV; buf->dev.dev = pcm->card->dev; buf->private_data = NULL; buf->area = dma_alloc_coherent(pcm->card->dev, size, - &buf->addr, GFP_KERNEL); - pr_debug("atmel-pcm:" - "preallocate_dma_buffer: area=%p, addr=%p, size=%d\n", - (void *) buf->area, - (void *) buf->addr, - size); + &buf->addr, GFP_KERNEL); + pr_debug("atmel-pcm: alloc dma buffer: area=%p, addr=%p, size=%d\n", + (void *)buf->area, (void *)buf->addr, size); if (!buf->area) return -ENOMEM; @@ -113,258 +58,19 @@ static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, buf->bytes = size; return 0; } -/*--------------------------------------------------------------------------*\ - * ISR -\*--------------------------------------------------------------------------*/ -static void atmel_pcm_dma_irq(u32 ssc_sr, - struct snd_pcm_substream *substream) -{ - struct atmel_runtime_data *prtd = substream->runtime->private_data; - struct atmel_pcm_dma_params *params = prtd->params; - static int count; - - count++; - - if (ssc_sr & params->mask->ssc_endbuf) { - pr_warning("atmel-pcm: buffer %s on %s" - " (SSC_SR=%#x, count=%d)\n", - substream->stream == SNDRV_PCM_STREAM_PLAYBACK - ? "underrun" : "overrun", - params->name, ssc_sr, count); - - /* re-start the PDC */ - ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, - params->mask->pdc_disable); - prtd->period_ptr += prtd->period_size; - if (prtd->period_ptr >= prtd->dma_buffer_end) - prtd->period_ptr = prtd->dma_buffer; - - ssc_writex(params->ssc->regs, params->pdc->xpr, - prtd->period_ptr); - ssc_writex(params->ssc->regs, params->pdc->xcr, - prtd->period_size / params->pdc_xfer_size); - ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, - params->mask->pdc_enable); - } - - if (ssc_sr & params->mask->ssc_endx) { - /* Load the PDC next pointer and counter registers */ - prtd->period_ptr += prtd->period_size; - if (prtd->period_ptr >= prtd->dma_buffer_end) - prtd->period_ptr = prtd->dma_buffer; - - ssc_writex(params->ssc->regs, params->pdc->xnpr, - prtd->period_ptr); - ssc_writex(params->ssc->regs, params->pdc->xncr, - prtd->period_size / params->pdc_xfer_size); - } - - snd_pcm_period_elapsed(substream); -} - - -/*--------------------------------------------------------------------------*\ - * PCM operations -\*--------------------------------------------------------------------------*/ -static int atmel_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct atmel_runtime_data *prtd = runtime->private_data; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - - /* this may get called several times by oss emulation - * with different params */ - - snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); - runtime->dma_bytes = params_buffer_bytes(params); - - prtd->params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - prtd->params->dma_intr_handler = atmel_pcm_dma_irq; - - prtd->dma_buffer = runtime->dma_addr; - prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes; - prtd->period_size = params_period_bytes(params); - - pr_debug("atmel-pcm: " - "hw_params: DMA for %s initialized " - "(dma_bytes=%u, period_size=%u)\n", - prtd->params->name, - runtime->dma_bytes, - prtd->period_size); - return 0; -} - -static int atmel_pcm_hw_free(struct snd_pcm_substream *substream) -{ - struct atmel_runtime_data *prtd = substream->runtime->private_data; - struct atmel_pcm_dma_params *params = prtd->params; - - if (params != NULL) { - ssc_writex(params->ssc->regs, SSC_PDC_PTCR, - params->mask->pdc_disable); - prtd->params->dma_intr_handler = NULL; - } - - return 0; -} - -static int atmel_pcm_prepare(struct snd_pcm_substream *substream) -{ - struct atmel_runtime_data *prtd = substream->runtime->private_data; - struct atmel_pcm_dma_params *params = prtd->params; - - ssc_writex(params->ssc->regs, SSC_IDR, - params->mask->ssc_endx | params->mask->ssc_endbuf); - ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, - params->mask->pdc_disable); - return 0; -} - -static int atmel_pcm_trigger(struct snd_pcm_substream *substream, - int cmd) -{ - struct snd_pcm_runtime *rtd = substream->runtime; - struct atmel_runtime_data *prtd = rtd->private_data; - struct atmel_pcm_dma_params *params = prtd->params; - int ret = 0; - - pr_debug("atmel-pcm:buffer_size = %ld," - "dma_area = %p, dma_bytes = %u\n", - rtd->buffer_size, rtd->dma_area, rtd->dma_bytes); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - prtd->period_ptr = prtd->dma_buffer; - - ssc_writex(params->ssc->regs, params->pdc->xpr, - prtd->period_ptr); - ssc_writex(params->ssc->regs, params->pdc->xcr, - prtd->period_size / params->pdc_xfer_size); - - prtd->period_ptr += prtd->period_size; - ssc_writex(params->ssc->regs, params->pdc->xnpr, - prtd->period_ptr); - ssc_writex(params->ssc->regs, params->pdc->xncr, - prtd->period_size / params->pdc_xfer_size); - - pr_debug("atmel-pcm: trigger: " - "period_ptr=%lx, xpr=%u, " - "xcr=%u, xnpr=%u, xncr=%u\n", - (unsigned long)prtd->period_ptr, - ssc_readx(params->ssc->regs, params->pdc->xpr), - ssc_readx(params->ssc->regs, params->pdc->xcr), - ssc_readx(params->ssc->regs, params->pdc->xnpr), - ssc_readx(params->ssc->regs, params->pdc->xncr)); - - ssc_writex(params->ssc->regs, SSC_IER, - params->mask->ssc_endx | params->mask->ssc_endbuf); - ssc_writex(params->ssc->regs, SSC_PDC_PTCR, - params->mask->pdc_enable); - - pr_debug("sr=%u imr=%u\n", - ssc_readx(params->ssc->regs, SSC_SR), - ssc_readx(params->ssc->regs, SSC_IER)); - break; /* SNDRV_PCM_TRIGGER_START */ - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, - params->mask->pdc_disable); - break; - - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, - params->mask->pdc_enable); - break; - - default: - ret = -EINVAL; - } - return ret; -} - -static snd_pcm_uframes_t atmel_pcm_pointer( - struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct atmel_runtime_data *prtd = runtime->private_data; - struct atmel_pcm_dma_params *params = prtd->params; - dma_addr_t ptr; - snd_pcm_uframes_t x; - - ptr = (dma_addr_t) ssc_readx(params->ssc->regs, params->pdc->xpr); - x = bytes_to_frames(runtime, ptr - prtd->dma_buffer); - - if (x == runtime->buffer_size) - x = 0; - - return x; -} - -static int atmel_pcm_open(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct atmel_runtime_data *prtd; - int ret = 0; - - snd_soc_set_runtime_hwparams(substream, &atmel_pcm_hardware); - - /* ensure that buffer size is a multiple of period size */ - ret = snd_pcm_hw_constraint_integer(runtime, - SNDRV_PCM_HW_PARAM_PERIODS); - if (ret < 0) - goto out; - - prtd = kzalloc(sizeof(struct atmel_runtime_data), GFP_KERNEL); - if (prtd == NULL) { - ret = -ENOMEM; - goto out; - } - runtime->private_data = prtd; - - out: - return ret; -} - -static int atmel_pcm_close(struct snd_pcm_substream *substream) -{ - struct atmel_runtime_data *prtd = substream->runtime->private_data; - - kfree(prtd); - return 0; -} - -static int atmel_pcm_mmap(struct snd_pcm_substream *substream, +int atmel_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma) { return remap_pfn_range(vma, vma->vm_start, substream->dma_buffer.addr >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot); } +EXPORT_SYMBOL_GPL(atmel_pcm_mmap); -static struct snd_pcm_ops atmel_pcm_ops = { - .open = atmel_pcm_open, - .close = atmel_pcm_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = atmel_pcm_hw_params, - .hw_free = atmel_pcm_hw_free, - .prepare = atmel_pcm_prepare, - .trigger = atmel_pcm_trigger, - .pointer = atmel_pcm_pointer, - .mmap = atmel_pcm_mmap, -}; - - -/*--------------------------------------------------------------------------*\ - * ASoC platform driver -\*--------------------------------------------------------------------------*/ static u64 atmel_pcm_dmamask = DMA_BIT_MASK(32); -static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd) +int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd) { struct snd_card *card = rtd->card->snd_card; struct snd_pcm *pcm = rtd->pcm; @@ -376,6 +82,7 @@ static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd) card->dev->coherent_dma_mask = DMA_BIT_MASK(32); if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { + pr_debug("atmel-pcm: allocating PCM playback DMA buffer\n"); ret = atmel_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); if (ret) @@ -383,8 +90,7 @@ static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd) } if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { - pr_debug("atmel-pcm:" - "Allocating PCM capture DMA buffer\n"); + pr_debug("atmel-pcm: allocating PCM capture DMA buffer\n"); ret = atmel_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE); if (ret) @@ -393,8 +99,9 @@ static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd) out: return ret; } +EXPORT_SYMBOL_GPL(atmel_pcm_new); -static void atmel_pcm_free_dma_buffers(struct snd_pcm *pcm) +void atmel_pcm_free(struct snd_pcm *pcm) { struct snd_pcm_substream *substream; struct snd_dma_buffer *buf; @@ -413,89 +120,5 @@ static void atmel_pcm_free_dma_buffers(struct snd_pcm *pcm) buf->area = NULL; } } +EXPORT_SYMBOL_GPL(atmel_pcm_free); -#ifdef CONFIG_PM -static int atmel_pcm_suspend(struct snd_soc_dai *dai) -{ - struct snd_pcm_runtime *runtime = dai->runtime; - struct atmel_runtime_data *prtd; - struct atmel_pcm_dma_params *params; - - if (!runtime) - return 0; - - prtd = runtime->private_data; - params = prtd->params; - - /* disable the PDC and save the PDC registers */ - - ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_disable); - - prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr); - prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr); - prtd->pdc_xnpr_save = ssc_readx(params->ssc->regs, params->pdc->xnpr); - prtd->pdc_xncr_save = ssc_readx(params->ssc->regs, params->pdc->xncr); - - return 0; -} - -static int atmel_pcm_resume(struct snd_soc_dai *dai) -{ - struct snd_pcm_runtime *runtime = dai->runtime; - struct atmel_runtime_data *prtd; - struct atmel_pcm_dma_params *params; - - if (!runtime) - return 0; - - prtd = runtime->private_data; - params = prtd->params; - - /* restore the PDC registers and enable the PDC */ - ssc_writex(params->ssc->regs, params->pdc->xpr, prtd->pdc_xpr_save); - ssc_writex(params->ssc->regs, params->pdc->xcr, prtd->pdc_xcr_save); - ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save); - ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save); - - ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_enable); - return 0; -} -#else -#define atmel_pcm_suspend NULL -#define atmel_pcm_resume NULL -#endif - -static struct snd_soc_platform_driver atmel_soc_platform = { - .ops = &atmel_pcm_ops, - .pcm_new = atmel_pcm_new, - .pcm_free = atmel_pcm_free_dma_buffers, - .suspend = atmel_pcm_suspend, - .resume = atmel_pcm_resume, -}; - -static int __devinit atmel_soc_platform_probe(struct platform_device *pdev) -{ - return snd_soc_register_platform(&pdev->dev, &atmel_soc_platform); -} - -static int __devexit atmel_soc_platform_remove(struct platform_device *pdev) -{ - snd_soc_unregister_platform(&pdev->dev); - return 0; -} - -static struct platform_driver atmel_pcm_driver = { - .driver = { - .name = "atmel-pcm-audio", - .owner = THIS_MODULE, - }, - - .probe = atmel_soc_platform_probe, - .remove = __devexit_p(atmel_soc_platform_remove), -}; - -module_platform_driver(atmel_pcm_driver); - -MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>"); -MODULE_DESCRIPTION("Atmel PCM module"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/atmel/atmel-pcm.h b/sound/soc/atmel/atmel-pcm.h index 5e0a95e6432..bb45d20e725 100644 --- a/sound/soc/atmel/atmel-pcm.h +++ b/sound/soc/atmel/atmel-pcm.h @@ -36,6 +36,8 @@ #include <linux/atmel-ssc.h> +#define ATMEL_SSC_DMABUF_SIZE (64 * 1024) + /* * Registers and status bits that are required by the PCM driver. */ @@ -50,6 +52,7 @@ struct atmel_pdc_regs { struct atmel_ssc_mask { u32 ssc_enable; /* SSC recv/trans enable */ u32 ssc_disable; /* SSC recv/trans disable */ + u32 ssc_error; /* SSC error conditions */ u32 ssc_endx; /* SSC ENDTX or ENDRX */ u32 ssc_endbuf; /* SSC TXBUFE or RXBUFF */ u32 pdc_enable; /* PDC recv/trans enable */ @@ -80,4 +83,35 @@ struct atmel_pcm_dma_params { #define ssc_readx(base, reg) (__raw_readl((base) + (reg))) #define ssc_writex(base, reg, value) __raw_writel((value), (base) + (reg)) +int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd); +void atmel_pcm_free(struct snd_pcm *pcm); +int atmel_pcm_mmap(struct snd_pcm_substream *substream, + struct vm_area_struct *vma); + +#ifdef CONFIG_SND_ATMEL_SOC_PDC +int atmel_pcm_pdc_platform_register(struct device *dev); +void atmel_pcm_pdc_platform_unregister(struct device *dev); +#else +static inline int atmel_pcm_pdc_platform_register(struct device *dev) +{ + return 0; +} +static inline void atmel_pcm_pdc_platform_unregister(struct device *dev) +{ +} +#endif + +#ifdef CONFIG_SND_ATMEL_SOC_DMA +int atmel_pcm_dma_platform_register(struct device *dev); +void atmel_pcm_dma_platform_unregister(struct device *dev); +#else +static inline int atmel_pcm_dma_platform_register(struct device *dev) +{ + return 0; +} +static inline void atmel_pcm_dma_platform_unregister(struct device *dev) +{ +} +#endif + #endif /* _ATMEL_PCM_H */ diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c index 354341ec0f4..1c766342205 100644 --- a/sound/soc/atmel/atmel_ssc_dai.c +++ b/sound/soc/atmel/atmel_ssc_dai.c @@ -48,11 +48,7 @@ #include "atmel_ssc_dai.h" -#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20) -#define NUM_SSC_DEVICES 1 -#else #define NUM_SSC_DEVICES 3 -#endif /* * 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] = { .pdc = &pdc_rx_reg, .mask = &ssc_rx_mask, } }, -#if NUM_SSC_DEVICES == 3 {{ .name = "SSC1 PCM out", .pdc = &pdc_tx_reg, @@ -128,7 +123,6 @@ static struct atmel_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = { .pdc = &pdc_rx_reg, .mask = &ssc_rx_mask, } }, -#endif }; @@ -139,7 +133,6 @@ static struct atmel_ssc_info ssc_info[NUM_SSC_DEVICES] = { .dir_mask = SSC_DIR_MASK_UNUSED, .initialized = 0, }, -#if NUM_SSC_DEVICES == 3 { .name = "ssc1", .lock = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock), @@ -152,7 +145,6 @@ static struct atmel_ssc_info ssc_info[NUM_SSC_DEVICES] = { .dir_mask = SSC_DIR_MASK_UNUSED, .initialized = 0, }, -#endif }; @@ -690,27 +682,9 @@ static int atmel_ssc_resume(struct snd_soc_dai *cpu_dai) static int atmel_ssc_probe(struct snd_soc_dai *dai) { struct atmel_ssc_info *ssc_p = &ssc_info[dai->id]; - int ret = 0; snd_soc_dai_set_drvdata(dai, ssc_p); - /* - * Request SSC device - */ - ssc_p->ssc = ssc_request(dai->id); - if (IS_ERR(ssc_p->ssc)) { - printk(KERN_ERR "ASoC: Failed to request SSC %d\n", dai->id); - ret = PTR_ERR(ssc_p->ssc); - } - - return ret; -} - -static int atmel_ssc_remove(struct snd_soc_dai *dai) -{ - struct atmel_ssc_info *ssc_p = snd_soc_dai_get_drvdata(dai); - - ssc_free(ssc_p->ssc); return 0; } @@ -728,30 +702,8 @@ static const struct snd_soc_dai_ops atmel_ssc_dai_ops = { .set_clkdiv = atmel_ssc_set_dai_clkdiv, }; -static struct snd_soc_dai_driver atmel_ssc_dai[NUM_SSC_DEVICES] = { - { - .name = "atmel-ssc-dai.0", - .probe = atmel_ssc_probe, - .remove = atmel_ssc_remove, - .suspend = atmel_ssc_suspend, - .resume = atmel_ssc_resume, - .playback = { - .channels_min = 1, - .channels_max = 2, - .rates = ATMEL_SSC_RATES, - .formats = ATMEL_SSC_FORMATS,}, - .capture = { - .channels_min = 1, - .channels_max = 2, - .rates = ATMEL_SSC_RATES, - .formats = ATMEL_SSC_FORMATS,}, - .ops = &atmel_ssc_dai_ops, - }, -#if NUM_SSC_DEVICES == 3 - { - .name = "atmel-ssc-dai.1", +static struct snd_soc_dai_driver atmel_ssc_dai = { .probe = atmel_ssc_probe, - .remove = atmel_ssc_remove, .suspend = atmel_ssc_suspend, .resume = atmel_ssc_resume, .playback = { @@ -765,50 +717,50 @@ static struct snd_soc_dai_driver atmel_ssc_dai[NUM_SSC_DEVICES] = { .rates = ATMEL_SSC_RATES, .formats = ATMEL_SSC_FORMATS,}, .ops = &atmel_ssc_dai_ops, - }, - { - .name = "atmel-ssc-dai.2", - .probe = atmel_ssc_probe, - .remove = atmel_ssc_remove, - .suspend = atmel_ssc_suspend, - .resume = atmel_ssc_resume, - .playback = { - .channels_min = 1, - .channels_max = 2, - .rates = ATMEL_SSC_RATES, - .formats = ATMEL_SSC_FORMATS,}, - .capture = { - .channels_min = 1, - .channels_max = 2, - .rates = ATMEL_SSC_RATES, - .formats = ATMEL_SSC_FORMATS,}, - .ops = &atmel_ssc_dai_ops, - }, -#endif }; -static __devinit int asoc_ssc_probe(struct platform_device *pdev) +static int asoc_ssc_init(struct device *dev) { - BUG_ON(pdev->id < 0); - BUG_ON(pdev->id >= ARRAY_SIZE(atmel_ssc_dai)); - return snd_soc_register_dai(&pdev->dev, &atmel_ssc_dai[pdev->id]); -} + struct platform_device *pdev = to_platform_device(dev); + struct ssc_device *ssc = platform_get_drvdata(pdev); + int ret; + + ret = snd_soc_register_dai(dev, &atmel_ssc_dai); + if (ret) { + dev_err(dev, "Could not register DAI: %d\n", ret); + goto err; + } + + if (ssc->pdata->use_dma) + ret = atmel_pcm_dma_platform_register(dev); + else + ret = atmel_pcm_pdc_platform_register(dev); + + if (ret) { + dev_err(dev, "Could not register PCM: %d\n", ret); + goto err_unregister_dai; + }; -static int __devexit asoc_ssc_remove(struct platform_device *pdev) -{ - snd_soc_unregister_dai(&pdev->dev); return 0; + +err_unregister_dai: + snd_soc_unregister_dai(dev); +err: + return ret; } -static struct platform_driver asoc_ssc_driver = { - .driver = { - .name = "atmel-ssc-dai", - .owner = THIS_MODULE, - }, +static void asoc_ssc_exit(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct ssc_device *ssc = platform_get_drvdata(pdev); - .probe = asoc_ssc_probe, - .remove = __devexit_p(asoc_ssc_remove), -}; + if (ssc->pdata->use_dma) + atmel_pcm_dma_platform_unregister(dev); + else + atmel_pcm_pdc_platform_unregister(dev); + + snd_soc_unregister_dai(dev); +} /** * atmel_ssc_set_audio - Allocate the specified SSC for audio use. @@ -816,50 +768,32 @@ static struct platform_driver asoc_ssc_driver = { int atmel_ssc_set_audio(int ssc_id) { struct ssc_device *ssc; - static struct platform_device *dma_pdev; - struct platform_device *ssc_pdev; int ret; - if (ssc_id < 0 || ssc_id >= ARRAY_SIZE(atmel_ssc_dai)) - return -EINVAL; - - /* Allocate a dummy device for DMA if we don't have one already */ - if (!dma_pdev) { - dma_pdev = platform_device_alloc("atmel-pcm-audio", -1); - if (!dma_pdev) - return -ENOMEM; - - ret = platform_device_add(dma_pdev); - if (ret < 0) { - platform_device_put(dma_pdev); - dma_pdev = NULL; - return ret; - } - } - - ssc_pdev = platform_device_alloc("atmel-ssc-dai", ssc_id); - if (!ssc_pdev) - return -ENOMEM; - /* If we can grab the SSC briefly to parent the DAI device off it */ ssc = ssc_request(ssc_id); - if (IS_ERR(ssc)) - pr_warn("Unable to parent ASoC SSC DAI on SSC: %ld\n", + if (IS_ERR(ssc)) { + pr_err("Unable to parent ASoC SSC DAI on SSC: %ld\n", PTR_ERR(ssc)); - else { - ssc_pdev->dev.parent = &(ssc->pdev->dev); - ssc_free(ssc); + return PTR_ERR(ssc); + } else { + ssc_info[ssc_id].ssc = ssc; } - ret = platform_device_add(ssc_pdev); - if (ret < 0) - platform_device_put(ssc_pdev); + ret = asoc_ssc_init(&ssc->pdev->dev); return ret; } EXPORT_SYMBOL_GPL(atmel_ssc_set_audio); -module_platform_driver(asoc_ssc_driver); +void atmel_ssc_put_audio(int ssc_id) +{ + struct ssc_device *ssc = ssc_info[ssc_id].ssc; + + ssc_free(ssc); + asoc_ssc_exit(&ssc->pdev->dev); +} +EXPORT_SYMBOL_GPL(atmel_ssc_put_audio); /* Module information */ 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 5d4f0f9b4d9..b1f08d51149 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 { struct atmel_ssc_state ssc_state; }; -int atmel_ssc_set_audio(int ssc); +int atmel_ssc_set_audio(int ssc_id); +void atmel_ssc_put_audio(int ssc_id); #endif /* _AT91_SSC_DAI_H */ diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c index c88351488f4..da976291da9 100644 --- a/sound/soc/atmel/sam9g20_wm8731.c +++ b/sound/soc/atmel/sam9g20_wm8731.c @@ -38,6 +38,8 @@ #include <linux/platform_device.h> #include <linux/i2c.h> +#include <linux/pinctrl/consumer.h> + #include <linux/atmel-ssc.h> #include <sound/core.h> @@ -179,10 +181,10 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd) static struct snd_soc_dai_link at91sam9g20ek_dai = { .name = "WM8731", .stream_name = "WM8731 PCM", - .cpu_dai_name = "atmel-ssc-dai.0", + .cpu_dai_name = "at91rm9200_ssc.0", .codec_dai_name = "wm8731-hifi", .init = at91sam9g20ek_wm8731_init, - .platform_name = "atmel-pcm-audio", + .platform_name = "at91rm9200_ssc.0", .codec_name = "wm8731.0-001b", .ops = &at91sam9g20ek_ops, }; @@ -195,20 +197,31 @@ static struct snd_soc_card snd_soc_at91sam9g20ek = { .set_bias_level = at91sam9g20ek_set_bias_level, }; -static struct platform_device *at91sam9g20ek_snd_device; - -static int __init at91sam9g20ek_init(void) +static int at91sam9g20ek_audio_probe(struct platform_device *pdev) { + struct device_node *np = pdev->dev.of_node; + struct device_node *codec_np, *cpu_np; struct clk *pllb; + struct snd_soc_card *card = &snd_soc_at91sam9g20ek; + struct pinctrl *pinctrl; int ret; - if (!(machine_is_at91sam9g20ek() || machine_is_at91sam9g20ek_2mmc())) - return -ENODEV; + pinctrl = devm_pinctrl_get_select_default(&pdev->dev); + if (IS_ERR(pinctrl)) { + dev_err(&pdev->dev, "Failed to request pinctrl for mck\n"); + return PTR_ERR(pinctrl); + } + + if (!np) { + if (!(machine_is_at91sam9g20ek() || + machine_is_at91sam9g20ek_2mmc())) + return -ENODEV; + } ret = atmel_ssc_set_audio(0); - if (ret != 0) { - pr_err("Failed to set SSC 0 for audio: %d\n", ret); - return ret; + if (ret) { + dev_err(&pdev->dev, "ssc channel is not valid\n"); + return -EINVAL; } /* @@ -236,45 +249,92 @@ static int __init at91sam9g20ek_init(void) clk_set_rate(mclk, MCLK_RATE); - at91sam9g20ek_snd_device = platform_device_alloc("soc-audio", -1); - if (!at91sam9g20ek_snd_device) { - printk(KERN_ERR "ASoC: Platform device allocation failed\n"); - ret = -ENOMEM; - goto err_mclk; + card->dev = &pdev->dev; + + /* Parse device node info */ + if (np) { + ret = snd_soc_of_parse_card_name(card, "atmel,model"); + if (ret) + goto err; + + ret = snd_soc_of_parse_audio_routing(card, + "atmel,audio-routing"); + if (ret) + goto err; + + /* Parse codec info */ + at91sam9g20ek_dai.codec_name = NULL; + codec_np = of_parse_phandle(np, "atmel,audio-codec", 0); + if (!codec_np) { + dev_err(&pdev->dev, "codec info missing\n"); + return -EINVAL; + } + at91sam9g20ek_dai.codec_of_node = codec_np; + + /* Parse dai and platform info */ + at91sam9g20ek_dai.cpu_dai_name = NULL; + at91sam9g20ek_dai.platform_name = NULL; + cpu_np = of_parse_phandle(np, "atmel,ssc-controller", 0); + if (!cpu_np) { + dev_err(&pdev->dev, "dai and pcm info missing\n"); + return -EINVAL; + } + at91sam9g20ek_dai.cpu_of_node = cpu_np; + at91sam9g20ek_dai.platform_of_node = cpu_np; + + of_node_put(codec_np); + of_node_put(cpu_np); } - platform_set_drvdata(at91sam9g20ek_snd_device, - &snd_soc_at91sam9g20ek); - - ret = platform_device_add(at91sam9g20ek_snd_device); + ret = snd_soc_register_card(card); if (ret) { - printk(KERN_ERR "ASoC: Platform device allocation failed\n"); - goto err_device_add; + printk(KERN_ERR "ASoC: snd_soc_register_card() failed\n"); } return ret; -err_device_add: - platform_device_put(at91sam9g20ek_snd_device); err_mclk: clk_put(mclk); mclk = NULL; err: + atmel_ssc_put_audio(0); return ret; } -static void __exit at91sam9g20ek_exit(void) +static int at91sam9g20ek_audio_remove(struct platform_device *pdev) { - platform_device_unregister(at91sam9g20ek_snd_device); - at91sam9g20ek_snd_device = NULL; + struct snd_soc_card *card = platform_get_drvdata(pdev); + + atmel_ssc_put_audio(0); + snd_soc_unregister_card(card); clk_put(mclk); mclk = NULL; + + return 0; } -module_init(at91sam9g20ek_init); -module_exit(at91sam9g20ek_exit); +#ifdef CONFIG_OF +static const struct of_device_id at91sam9g20ek_wm8731_dt_ids[] = { + { .compatible = "atmel,at91sam9g20ek-wm8731-audio", }, + { } +}; +MODULE_DEVICE_TABLE(of, at91sam9g20ek_wm8731_dt_ids); +#endif + +static struct platform_driver at91sam9g20ek_audio_driver = { + .driver = { + .name = "at91sam9g20ek-audio", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(at91sam9g20ek_wm8731_dt_ids), + }, + .probe = at91sam9g20ek_audio_probe, + .remove = at91sam9g20ek_audio_remove, +}; + +module_platform_driver(at91sam9g20ek_audio_driver); /* Module information */ MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>"); MODULE_DESCRIPTION("ALSA SoC AT91SAM9G20EK_WM8731"); +MODULE_ALIAS("platform:at91sam9g20ek-audio"); MODULE_LICENSE("GPL"); diff --git a/sound/soc/au1x/ac97c.c b/sound/soc/au1x/ac97c.c index c5ac2449563..ea7d9d15702 100644 --- a/sound/soc/au1x/ac97c.c +++ b/sound/soc/au1x/ac97c.c @@ -223,7 +223,7 @@ static struct snd_soc_dai_driver au1xac97c_dai_driver = { .ops = &alchemy_ac97c_ops, }; -static int __devinit au1xac97c_drvprobe(struct platform_device *pdev) +static int au1xac97c_drvprobe(struct platform_device *pdev) { int ret; struct resource *iores, *dmares; @@ -276,7 +276,7 @@ static int __devinit au1xac97c_drvprobe(struct platform_device *pdev) return 0; } -static int __devexit au1xac97c_drvremove(struct platform_device *pdev) +static int au1xac97c_drvremove(struct platform_device *pdev) { struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev); @@ -330,7 +330,7 @@ static struct platform_driver au1xac97c_driver = { .pm = AU1XPSCAC97_PMOPS, }, .probe = au1xac97c_drvprobe, - .remove = __devexit_p(au1xac97c_drvremove), + .remove = au1xac97c_drvremove, }; static int __init au1xac97c_load(void) diff --git a/sound/soc/au1x/db1000.c b/sound/soc/au1x/db1000.c index 511d83c11a9..376d976bcc2 100644 --- a/sound/soc/au1x/db1000.c +++ b/sound/soc/au1x/db1000.c @@ -34,14 +34,14 @@ static struct snd_soc_card db1000_ac97 = { .num_links = 1, }; -static int __devinit db1000_audio_probe(struct platform_device *pdev) +static int db1000_audio_probe(struct platform_device *pdev) { struct snd_soc_card *card = &db1000_ac97; card->dev = &pdev->dev; return snd_soc_register_card(card); } -static int __devexit db1000_audio_remove(struct platform_device *pdev) +static int db1000_audio_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); snd_soc_unregister_card(card); @@ -55,7 +55,7 @@ static struct platform_driver db1000_audio_driver = { .pm = &snd_soc_pm_ops, }, .probe = db1000_audio_probe, - .remove = __devexit_p(db1000_audio_remove), + .remove = db1000_audio_remove, }; module_platform_driver(db1000_audio_driver); diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c index 30ea513d81d..a497a0cfeba 100644 --- a/sound/soc/au1x/db1200.c +++ b/sound/soc/au1x/db1200.c @@ -167,7 +167,7 @@ static struct snd_soc_card db1550_i2s_machine = { /*------------------------- COMMON PART ---------------------------*/ -static struct snd_soc_card *db1200_cards[] __devinitdata = { +static struct snd_soc_card *db1200_cards[] = { &db1200_ac97_machine, &db1200_i2s_machine, &db1300_ac97_machine, @@ -176,7 +176,7 @@ static struct snd_soc_card *db1200_cards[] __devinitdata = { &db1550_i2s_machine, }; -static int __devinit db1200_audio_probe(struct platform_device *pdev) +static int db1200_audio_probe(struct platform_device *pdev) { const struct platform_device_id *pid = platform_get_device_id(pdev); struct snd_soc_card *card; @@ -186,7 +186,7 @@ static int __devinit db1200_audio_probe(struct platform_device *pdev) return snd_soc_register_card(card); } -static int __devexit db1200_audio_remove(struct platform_device *pdev) +static int db1200_audio_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); snd_soc_unregister_card(card); @@ -201,7 +201,7 @@ static struct platform_driver db1200_audio_driver = { }, .id_table = db1200_pids, .probe = db1200_audio_probe, - .remove = __devexit_p(db1200_audio_remove), + .remove = db1200_audio_remove, }; module_platform_driver(db1200_audio_driver); diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c index 8372cd35f0d..3b4eafaf30d 100644 --- a/sound/soc/au1x/dbdma2.c +++ b/sound/soc/au1x/dbdma2.c @@ -347,7 +347,7 @@ static struct snd_soc_platform_driver au1xpsc_soc_platform = { .pcm_free = au1xpsc_pcm_free_dma_buffers, }; -static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev) +static int au1xpsc_pcm_drvprobe(struct platform_device *pdev) { struct au1xpsc_audio_dmadata *dmadata; @@ -362,7 +362,7 @@ static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev) return snd_soc_register_platform(&pdev->dev, &au1xpsc_soc_platform); } -static int __devexit au1xpsc_pcm_drvremove(struct platform_device *pdev) +static int au1xpsc_pcm_drvremove(struct platform_device *pdev) { snd_soc_unregister_platform(&pdev->dev); @@ -375,7 +375,7 @@ static struct platform_driver au1xpsc_pcm_driver = { .owner = THIS_MODULE, }, .probe = au1xpsc_pcm_drvprobe, - .remove = __devexit_p(au1xpsc_pcm_drvremove), + .remove = au1xpsc_pcm_drvremove, }; module_platform_driver(au1xpsc_pcm_driver); diff --git a/sound/soc/au1x/dma.c b/sound/soc/au1x/dma.c index 0a91b186a86..befd1074f9b 100644 --- a/sound/soc/au1x/dma.c +++ b/sound/soc/au1x/dma.c @@ -322,7 +322,7 @@ static struct snd_soc_platform_driver alchemy_pcm_soc_platform = { .pcm_free = alchemy_pcm_free_dma_buffers, }; -static int __devinit alchemy_pcm_drvprobe(struct platform_device *pdev) +static int alchemy_pcm_drvprobe(struct platform_device *pdev) { struct alchemy_pcm_ctx *ctx; @@ -335,7 +335,7 @@ static int __devinit alchemy_pcm_drvprobe(struct platform_device *pdev) return snd_soc_register_platform(&pdev->dev, &alchemy_pcm_soc_platform); } -static int __devexit alchemy_pcm_drvremove(struct platform_device *pdev) +static int alchemy_pcm_drvremove(struct platform_device *pdev) { snd_soc_unregister_platform(&pdev->dev); @@ -348,7 +348,7 @@ static struct platform_driver alchemy_pcmdma_driver = { .owner = THIS_MODULE, }, .probe = alchemy_pcm_drvprobe, - .remove = __devexit_p(alchemy_pcm_drvremove), + .remove = alchemy_pcm_drvremove, }; module_platform_driver(alchemy_pcmdma_driver); diff --git a/sound/soc/au1x/i2sc.c b/sound/soc/au1x/i2sc.c index d4b9e364a47..072448afc21 100644 --- a/sound/soc/au1x/i2sc.c +++ b/sound/soc/au1x/i2sc.c @@ -225,7 +225,7 @@ static struct snd_soc_dai_driver au1xi2s_dai_driver = { .ops = &au1xi2s_dai_ops, }; -static int __devinit au1xi2s_drvprobe(struct platform_device *pdev) +static int au1xi2s_drvprobe(struct platform_device *pdev) { struct resource *iores, *dmares; struct au1xpsc_audio_data *ctx; @@ -263,7 +263,7 @@ static int __devinit au1xi2s_drvprobe(struct platform_device *pdev) return snd_soc_register_dai(&pdev->dev, &au1xi2s_dai_driver); } -static int __devexit au1xi2s_drvremove(struct platform_device *pdev) +static int au1xi2s_drvremove(struct platform_device *pdev) { struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev); @@ -309,7 +309,7 @@ static struct platform_driver au1xi2s_driver = { .pm = AU1XI2SC_PMOPS, }, .probe = au1xi2s_drvprobe, - .remove = __devexit_p(au1xi2s_drvremove), + .remove = au1xi2s_drvremove, }; module_platform_driver(au1xi2s_driver); diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c index 476b79a1c11..6ba07e36596 100644 --- a/sound/soc/au1x/psc-ac97.c +++ b/sound/soc/au1x/psc-ac97.c @@ -361,7 +361,7 @@ static const struct snd_soc_dai_driver au1xpsc_ac97_dai_template = { .ops = &au1xpsc_ac97_dai_ops, }; -static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev) +static int au1xpsc_ac97_drvprobe(struct platform_device *pdev) { int ret; struct resource *iores, *dmares; @@ -427,7 +427,7 @@ static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev) return 0; } -static int __devexit au1xpsc_ac97_drvremove(struct platform_device *pdev) +static int au1xpsc_ac97_drvremove(struct platform_device *pdev) { struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); @@ -495,7 +495,7 @@ static struct platform_driver au1xpsc_ac97_driver = { .pm = AU1XPSCAC97_PMOPS, }, .probe = au1xpsc_ac97_drvprobe, - .remove = __devexit_p(au1xpsc_ac97_drvremove), + .remove = au1xpsc_ac97_drvremove, }; static int __init au1xpsc_ac97_load(void) diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c index 0607ba3d925..360b4e50d7c 100644 --- a/sound/soc/au1x/psc-i2s.c +++ b/sound/soc/au1x/psc-i2s.c @@ -288,7 +288,7 @@ static const struct snd_soc_dai_driver au1xpsc_i2s_dai_template = { .ops = &au1xpsc_i2s_dai_ops, }; -static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev) +static int au1xpsc_i2s_drvprobe(struct platform_device *pdev) { struct resource *iores, *dmares; unsigned long sel; @@ -353,7 +353,7 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev) return snd_soc_register_dai(&pdev->dev, &wd->dai_drv); } -static int __devexit au1xpsc_i2s_drvremove(struct platform_device *pdev) +static int au1xpsc_i2s_drvremove(struct platform_device *pdev) { struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); @@ -418,7 +418,7 @@ static struct platform_driver au1xpsc_i2s_driver = { .pm = AU1XPSCI2S_PMOPS, }, .probe = au1xpsc_i2s_drvprobe, - .remove = __devexit_p(au1xpsc_i2s_drvremove), + .remove = au1xpsc_i2s_drvremove, }; module_platform_driver(au1xpsc_i2s_driver); diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c index d7dc9bde097..7e2f36004a5 100644 --- a/sound/soc/blackfin/bf5xx-ac97-pcm.c +++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c @@ -453,12 +453,12 @@ static struct snd_soc_platform_driver bf5xx_ac97_soc_platform = { .pcm_free = bf5xx_pcm_free_dma_buffers, }; -static int __devinit bf5xx_soc_platform_probe(struct platform_device *pdev) +static int bf5xx_soc_platform_probe(struct platform_device *pdev) { return snd_soc_register_platform(&pdev->dev, &bf5xx_ac97_soc_platform); } -static int __devexit bf5xx_soc_platform_remove(struct platform_device *pdev) +static int bf5xx_soc_platform_remove(struct platform_device *pdev) { snd_soc_unregister_platform(&pdev->dev); return 0; @@ -471,7 +471,7 @@ static struct platform_driver bf5xx_pcm_driver = { }, .probe = bf5xx_soc_platform_probe, - .remove = __devexit_p(bf5xx_soc_platform_remove), + .remove = bf5xx_soc_platform_remove, }; module_platform_driver(bf5xx_pcm_driver); diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c index f4e9dc4e262..8e41bcb020e 100644 --- a/sound/soc/blackfin/bf5xx-ac97.c +++ b/sound/soc/blackfin/bf5xx-ac97.c @@ -282,7 +282,7 @@ static struct snd_soc_dai_driver bfin_ac97_dai = { .formats = SNDRV_PCM_FMTBIT_S16_LE, }, }; -static int __devinit asoc_bfin_ac97_probe(struct platform_device *pdev) +static int asoc_bfin_ac97_probe(struct platform_device *pdev) { struct sport_device *sport_handle; int ret; @@ -352,7 +352,7 @@ gpio_err: return ret; } -static int __devexit asoc_bfin_ac97_remove(struct platform_device *pdev) +static int asoc_bfin_ac97_remove(struct platform_device *pdev) { struct sport_device *sport_handle = platform_get_drvdata(pdev); @@ -372,7 +372,7 @@ static struct platform_driver asoc_bfin_ac97_driver = { }, .probe = asoc_bfin_ac97_probe, - .remove = __devexit_p(asoc_bfin_ac97_remove), + .remove = asoc_bfin_ac97_remove, }; module_platform_driver(asoc_bfin_ac97_driver); diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c index 16b9c9efd19..d23f4b0ea54 100644 --- a/sound/soc/blackfin/bf5xx-ad1836.c +++ b/sound/soc/blackfin/bf5xx-ad1836.c @@ -75,7 +75,7 @@ static struct snd_soc_card bf5xx_ad1836 = { .num_links = 1, }; -static __devinit int bf5xx_ad1836_driver_probe(struct platform_device *pdev) +static int bf5xx_ad1836_driver_probe(struct platform_device *pdev) { struct snd_soc_card *card = &bf5xx_ad1836; const char **link_name; @@ -98,7 +98,7 @@ static __devinit int bf5xx_ad1836_driver_probe(struct platform_device *pdev) return ret; } -static int __devexit bf5xx_ad1836_driver_remove(struct platform_device *pdev) +static int bf5xx_ad1836_driver_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -113,7 +113,7 @@ static struct platform_driver bf5xx_ad1836_driver = { .pm = &snd_soc_pm_ops, }, .probe = bf5xx_ad1836_driver_probe, - .remove = __devexit_p(bf5xx_ad1836_driver_remove), + .remove = bf5xx_ad1836_driver_remove, }; module_platform_driver(bf5xx_ad1836_driver); diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c index 63205d723ea..262c1de364d 100644 --- a/sound/soc/blackfin/bf5xx-i2s-pcm.c +++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c @@ -292,12 +292,12 @@ static struct snd_soc_platform_driver bf5xx_i2s_soc_platform = { .pcm_free = bf5xx_pcm_free_dma_buffers, }; -static int __devinit bfin_i2s_soc_platform_probe(struct platform_device *pdev) +static int bfin_i2s_soc_platform_probe(struct platform_device *pdev) { return snd_soc_register_platform(&pdev->dev, &bf5xx_i2s_soc_platform); } -static int __devexit bfin_i2s_soc_platform_remove(struct platform_device *pdev) +static int bfin_i2s_soc_platform_remove(struct platform_device *pdev) { snd_soc_unregister_platform(&pdev->dev); return 0; @@ -310,7 +310,7 @@ static struct platform_driver bfin_i2s_pcm_driver = { }, .probe = bfin_i2s_soc_platform_probe, - .remove = __devexit_p(bfin_i2s_soc_platform_remove), + .remove = bfin_i2s_soc_platform_remove, }; module_platform_driver(bfin_i2s_pcm_driver); diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c index 4dccf0374fe..168d88bccb4 100644 --- a/sound/soc/blackfin/bf5xx-i2s.c +++ b/sound/soc/blackfin/bf5xx-i2s.c @@ -245,7 +245,7 @@ static struct snd_soc_dai_driver bf5xx_i2s_dai = { .ops = &bf5xx_i2s_dai_ops, }; -static int __devinit bf5xx_i2s_probe(struct platform_device *pdev) +static int bf5xx_i2s_probe(struct platform_device *pdev) { struct sport_device *sport_handle; int ret; @@ -267,7 +267,7 @@ static int __devinit bf5xx_i2s_probe(struct platform_device *pdev) return 0; } -static int __devexit bf5xx_i2s_remove(struct platform_device *pdev) +static int bf5xx_i2s_remove(struct platform_device *pdev) { struct sport_device *sport_handle = platform_get_drvdata(pdev); @@ -281,7 +281,7 @@ static int __devexit bf5xx_i2s_remove(struct platform_device *pdev) static struct platform_driver bfin_i2s_driver = { .probe = bf5xx_i2s_probe, - .remove = __devexit_p(bf5xx_i2s_remove), + .remove = bf5xx_i2s_remove, .driver = { .name = "bfin-i2s", .owner = THIS_MODULE, diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.c b/sound/soc/blackfin/bf5xx-tdm-pcm.c index 254490cf187..0e6b888bb4c 100644 --- a/sound/soc/blackfin/bf5xx-tdm-pcm.c +++ b/sound/soc/blackfin/bf5xx-tdm-pcm.c @@ -317,12 +317,12 @@ static struct snd_soc_platform_driver bf5xx_tdm_soc_platform = { .pcm_free = bf5xx_pcm_free_dma_buffers, }; -static int __devinit bf5xx_soc_platform_probe(struct platform_device *pdev) +static int bf5xx_soc_platform_probe(struct platform_device *pdev) { return snd_soc_register_platform(&pdev->dev, &bf5xx_tdm_soc_platform); } -static int __devexit bf5xx_soc_platform_remove(struct platform_device *pdev) +static int bf5xx_soc_platform_remove(struct platform_device *pdev) { snd_soc_unregister_platform(&pdev->dev); return 0; @@ -335,7 +335,7 @@ static struct platform_driver bfin_tdm_driver = { }, .probe = bf5xx_soc_platform_probe, - .remove = __devexit_p(bf5xx_soc_platform_remove), + .remove = bf5xx_soc_platform_remove, }; module_platform_driver(bfin_tdm_driver); diff --git a/sound/soc/blackfin/bf5xx-tdm.c b/sound/soc/blackfin/bf5xx-tdm.c index 594f88217c7..c1e516ec53a 100644 --- a/sound/soc/blackfin/bf5xx-tdm.c +++ b/sound/soc/blackfin/bf5xx-tdm.c @@ -249,7 +249,7 @@ static struct snd_soc_dai_driver bf5xx_tdm_dai = { .ops = &bf5xx_tdm_dai_ops, }; -static int __devinit bfin_tdm_probe(struct platform_device *pdev) +static int bfin_tdm_probe(struct platform_device *pdev) { struct sport_device *sport_handle; int ret; @@ -295,7 +295,7 @@ sport_config_err: return ret; } -static int __devexit bfin_tdm_remove(struct platform_device *pdev) +static int bfin_tdm_remove(struct platform_device *pdev) { struct sport_device *sport_handle = platform_get_drvdata(pdev); @@ -307,7 +307,7 @@ static int __devexit bfin_tdm_remove(struct platform_device *pdev) static struct platform_driver bfin_tdm_driver = { .probe = bfin_tdm_probe, - .remove = __devexit_p(bfin_tdm_remove), + .remove = bfin_tdm_remove, .driver = { .name = "bfin-tdm", .owner = THIS_MODULE, diff --git a/sound/soc/blackfin/bf6xx-i2s.c b/sound/soc/blackfin/bf6xx-i2s.c index c3c2466d3a4..8f337972f43 100644 --- a/sound/soc/blackfin/bf6xx-i2s.c +++ b/sound/soc/blackfin/bf6xx-i2s.c @@ -186,7 +186,7 @@ static struct snd_soc_dai_driver bfin_i2s_dai = { .ops = &bfin_i2s_dai_ops, }; -static int __devinit bfin_i2s_probe(struct platform_device *pdev) +static int bfin_i2s_probe(struct platform_device *pdev) { struct sport_device *sport; struct device *dev = &pdev->dev; @@ -208,7 +208,7 @@ static int __devinit bfin_i2s_probe(struct platform_device *pdev) return 0; } -static int __devexit bfin_i2s_remove(struct platform_device *pdev) +static int bfin_i2s_remove(struct platform_device *pdev) { struct sport_device *sport = platform_get_drvdata(pdev); @@ -220,7 +220,7 @@ static int __devexit bfin_i2s_remove(struct platform_device *pdev) static struct platform_driver bfin_i2s_driver = { .probe = bfin_i2s_probe, - .remove = __devexit_p(bfin_i2s_remove), + .remove = bfin_i2s_remove, .driver = { .name = "bfin-i2s", .owner = THIS_MODULE, diff --git a/sound/soc/blackfin/bfin-eval-adau1373.c b/sound/soc/blackfin/bfin-eval-adau1373.c index f3adbdbdd5e..4ef9683bcad 100644 --- a/sound/soc/blackfin/bfin-eval-adau1373.c +++ b/sound/soc/blackfin/bfin-eval-adau1373.c @@ -157,7 +157,7 @@ static int bfin_eval_adau1373_probe(struct platform_device *pdev) return snd_soc_register_card(&bfin_eval_adau1373); } -static int __devexit bfin_eval_adau1373_remove(struct platform_device *pdev) +static int bfin_eval_adau1373_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -173,7 +173,7 @@ static struct platform_driver bfin_eval_adau1373_driver = { .pm = &snd_soc_pm_ops, }, .probe = bfin_eval_adau1373_probe, - .remove = __devexit_p(bfin_eval_adau1373_remove), + .remove = bfin_eval_adau1373_remove, }; module_platform_driver(bfin_eval_adau1373_driver); diff --git a/sound/soc/blackfin/bfin-eval-adau1701.c b/sound/soc/blackfin/bfin-eval-adau1701.c index b0531fc9d81..3b55081a96c 100644 --- a/sound/soc/blackfin/bfin-eval-adau1701.c +++ b/sound/soc/blackfin/bfin-eval-adau1701.c @@ -97,7 +97,7 @@ static int bfin_eval_adau1701_probe(struct platform_device *pdev) return snd_soc_register_card(&bfin_eval_adau1701); } -static int __devexit bfin_eval_adau1701_remove(struct platform_device *pdev) +static int bfin_eval_adau1701_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -113,7 +113,7 @@ static struct platform_driver bfin_eval_adau1701_driver = { .pm = &snd_soc_pm_ops, }, .probe = bfin_eval_adau1701_probe, - .remove = __devexit_p(bfin_eval_adau1701_remove), + .remove = bfin_eval_adau1701_remove, }; module_platform_driver(bfin_eval_adau1701_driver); diff --git a/sound/soc/blackfin/bfin-eval-adav80x.c b/sound/soc/blackfin/bfin-eval-adav80x.c index 84b09987b7f..3b1b61a4481 100644 --- a/sound/soc/blackfin/bfin-eval-adav80x.c +++ b/sound/soc/blackfin/bfin-eval-adav80x.c @@ -122,7 +122,7 @@ static int bfin_eval_adav80x_probe(struct platform_device *pdev) return snd_soc_register_card(&bfin_eval_adav80x); } -static int __devexit bfin_eval_adav80x_remove(struct platform_device *pdev) +static int bfin_eval_adav80x_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -145,7 +145,7 @@ static struct platform_driver bfin_eval_adav80x_driver = { .pm = &snd_soc_pm_ops, }, .probe = bfin_eval_adav80x_probe, - .remove = __devexit_p(bfin_eval_adav80x_remove), + .remove = bfin_eval_adav80x_remove, .id_table = bfin_eval_adav80x_ids, }; diff --git a/sound/soc/cirrus/edb93xx.c b/sound/soc/cirrus/edb93xx.c index e01cb02abd3..5db68cf7b28 100644 --- a/sound/soc/cirrus/edb93xx.c +++ b/sound/soc/cirrus/edb93xx.c @@ -80,7 +80,7 @@ static struct snd_soc_card snd_soc_edb93xx = { .num_links = 1, }; -static int __devinit edb93xx_probe(struct platform_device *pdev) +static int edb93xx_probe(struct platform_device *pdev) { struct snd_soc_card *card = &snd_soc_edb93xx; int ret; @@ -101,7 +101,7 @@ static int __devinit edb93xx_probe(struct platform_device *pdev) return ret; } -static int __devexit edb93xx_remove(struct platform_device *pdev) +static int edb93xx_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -117,7 +117,7 @@ static struct platform_driver edb93xx_driver = { .owner = THIS_MODULE, }, .probe = edb93xx_probe, - .remove = __devexit_p(edb93xx_remove), + .remove = edb93xx_remove, }; module_platform_driver(edb93xx_driver); diff --git a/sound/soc/cirrus/ep93xx-ac97.c b/sound/soc/cirrus/ep93xx-ac97.c index c3521653cfd..f3f50e6fd6e 100644 --- a/sound/soc/cirrus/ep93xx-ac97.c +++ b/sound/soc/cirrus/ep93xx-ac97.c @@ -352,7 +352,7 @@ static struct snd_soc_dai_driver ep93xx_ac97_dai = { .ops = &ep93xx_ac97_dai_ops, }; -static int __devinit ep93xx_ac97_probe(struct platform_device *pdev) +static int ep93xx_ac97_probe(struct platform_device *pdev) { struct ep93xx_ac97_info *info; struct resource *res; @@ -402,7 +402,7 @@ fail: return ret; } -static int __devexit ep93xx_ac97_remove(struct platform_device *pdev) +static int ep93xx_ac97_remove(struct platform_device *pdev) { struct ep93xx_ac97_info *info = platform_get_drvdata(pdev); @@ -420,7 +420,7 @@ static int __devexit ep93xx_ac97_remove(struct platform_device *pdev) static struct platform_driver ep93xx_ac97_driver = { .probe = ep93xx_ac97_probe, - .remove = __devexit_p(ep93xx_ac97_remove), + .remove = ep93xx_ac97_remove, .driver = { .name = "ep93xx-ac97", .owner = THIS_MODULE, diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c index ac4a7515e7b..3365d4e843b 100644 --- a/sound/soc/cirrus/ep93xx-i2s.c +++ b/sound/soc/cirrus/ep93xx-i2s.c @@ -422,7 +422,7 @@ fail: return err; } -static int __devexit ep93xx_i2s_remove(struct platform_device *pdev) +static int ep93xx_i2s_remove(struct platform_device *pdev) { struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev); @@ -436,7 +436,7 @@ static int __devexit ep93xx_i2s_remove(struct platform_device *pdev) static struct platform_driver ep93xx_i2s_driver = { .probe = ep93xx_i2s_probe, - .remove = __devexit_p(ep93xx_i2s_remove), + .remove = ep93xx_i2s_remove, .driver = { .name = "ep93xx-i2s", .owner = THIS_MODULE, diff --git a/sound/soc/cirrus/ep93xx-pcm.c b/sound/soc/cirrus/ep93xx-pcm.c index 665d9c94cc1..72eb7a49e16 100644 --- a/sound/soc/cirrus/ep93xx-pcm.c +++ b/sound/soc/cirrus/ep93xx-pcm.c @@ -213,12 +213,12 @@ static struct snd_soc_platform_driver ep93xx_soc_platform = { .pcm_free = &ep93xx_pcm_free_dma_buffers, }; -static int __devinit ep93xx_soc_platform_probe(struct platform_device *pdev) +static int ep93xx_soc_platform_probe(struct platform_device *pdev) { return snd_soc_register_platform(&pdev->dev, &ep93xx_soc_platform); } -static int __devexit ep93xx_soc_platform_remove(struct platform_device *pdev) +static int ep93xx_soc_platform_remove(struct platform_device *pdev) { snd_soc_unregister_platform(&pdev->dev); return 0; @@ -231,7 +231,7 @@ static struct platform_driver ep93xx_pcm_driver = { }, .probe = ep93xx_soc_platform_probe, - .remove = __devexit_p(ep93xx_soc_platform_remove), + .remove = ep93xx_soc_platform_remove, }; module_platform_driver(ep93xx_pcm_driver); diff --git a/sound/soc/cirrus/simone.c b/sound/soc/cirrus/simone.c index dd997094eb3..a397bb0d817 100644 --- a/sound/soc/cirrus/simone.c +++ b/sound/soc/cirrus/simone.c @@ -41,7 +41,7 @@ static struct snd_soc_card snd_soc_simone = { static struct platform_device *simone_snd_ac97_device; -static int __devinit simone_probe(struct platform_device *pdev) +static int simone_probe(struct platform_device *pdev) { struct snd_soc_card *card = &snd_soc_simone; int ret; @@ -63,7 +63,7 @@ static int __devinit simone_probe(struct platform_device *pdev) return ret; } -static int __devexit simone_remove(struct platform_device *pdev) +static int simone_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -79,7 +79,7 @@ static struct platform_driver simone_driver = { .owner = THIS_MODULE, }, .probe = simone_probe, - .remove = __devexit_p(simone_remove), + .remove = simone_remove, }; module_platform_driver(simone_driver); diff --git a/sound/soc/cirrus/snappercl15.c b/sound/soc/cirrus/snappercl15.c index a193cea3cf3..9d77fe28dfc 100644 --- a/sound/soc/cirrus/snappercl15.c +++ b/sound/soc/cirrus/snappercl15.c @@ -98,7 +98,7 @@ static struct snd_soc_card snd_soc_snappercl15 = { .num_links = 1, }; -static int __devinit snappercl15_probe(struct platform_device *pdev) +static int snappercl15_probe(struct platform_device *pdev) { struct snd_soc_card *card = &snd_soc_snappercl15; int ret; @@ -119,7 +119,7 @@ static int __devinit snappercl15_probe(struct platform_device *pdev) return ret; } -static int __devexit snappercl15_remove(struct platform_device *pdev) +static int snappercl15_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -135,7 +135,7 @@ static struct platform_driver snappercl15_driver = { .owner = THIS_MODULE, }, .probe = snappercl15_probe, - .remove = __devexit_p(snappercl15_remove), + .remove = snappercl15_remove, }; module_platform_driver(snappercl15_driver); diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index 9fd3b6827bb..60159c07448 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c @@ -1423,7 +1423,7 @@ static struct snd_soc_codec_driver soc_codec_dev_pm860x = { .num_dapm_routes = ARRAY_SIZE(pm860x_dapm_routes), }; -static int __devinit pm860x_codec_probe(struct platform_device *pdev) +static int pm860x_codec_probe(struct platform_device *pdev) { struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); struct pm860x_priv *pm860x; @@ -1463,7 +1463,7 @@ out: return -EINVAL; } -static int __devexit pm860x_codec_remove(struct platform_device *pdev) +static int pm860x_codec_remove(struct platform_device *pdev) { snd_soc_unregister_codec(&pdev->dev); platform_set_drvdata(pdev, NULL); @@ -1476,7 +1476,7 @@ static struct platform_driver pm860x_codec_driver = { .owner = THIS_MODULE, }, .probe = pm860x_codec_probe, - .remove = __devexit_p(pm860x_codec_remove), + .remove = pm860x_codec_remove, }; module_platform_driver(pm860x_codec_driver); diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index b92759a3936..3a847828932 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -44,6 +44,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_LM4857 if I2C select SND_SOC_LM49453 if I2C select SND_SOC_MAX98088 if I2C + select SND_SOC_MAX98090 if I2C select SND_SOC_MAX98095 if I2C select SND_SOC_MAX9850 if I2C select SND_SOC_MAX9768 if I2C @@ -54,6 +55,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_PCM3008 select SND_SOC_RT5631 if I2C select SND_SOC_SGTL5000 if I2C + select SND_SOC_SI476X if MFD_SI476X_CORE select SND_SOC_SN95031 if INTEL_SCU_IPC select SND_SOC_SPDIF select SND_SOC_SSM2602 if SND_SOC_I2C_AND_SPI @@ -146,6 +148,13 @@ config SND_SOC_WM_HUBS default y if SND_SOC_WM8993=y || SND_SOC_WM8994=y default m if SND_SOC_WM8993=m || SND_SOC_WM8994=m +config SND_SOC_WM_ADSP + tristate + default y if SND_SOC_WM5102=y + default y if SND_SOC_WM2200=y + default m if SND_SOC_WM5102=m + default m if SND_SOC_WM2200=m + config SND_SOC_AB8500_CODEC tristate @@ -229,6 +238,7 @@ config SND_SOC_CX20442 tristate config SND_SOC_JZ4740_CODEC + select REGMAP_MMIO tristate config SND_SOC_L3 @@ -258,6 +268,9 @@ config SND_SOC_LM49453 config SND_SOC_MAX98088 tristate +config SND_SOC_MAX98090 + tristate + config SND_SOC_MAX98095 tristate @@ -277,6 +290,9 @@ config SND_SOC_RT5631 config SND_SOC_SGTL5000 tristate +config SND_SOC_SI476X + tristate + config SND_SOC_SIGMADSP tristate select CRC32 diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 9bd4d95aab4..f6e8e36cceb 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -34,6 +34,7 @@ snd-soc-lm4857-objs := lm4857.o snd-soc-lm49453-objs := lm49453.o snd-soc-max9768-objs := max9768.o snd-soc-max98088-objs := max98088.o +snd-soc-max98090-objs := max98090.o snd-soc-max98095-objs := max98095.o snd-soc-max9850-objs := max9850.o snd-soc-mc13783-objs := mc13783.o @@ -45,6 +46,7 @@ snd-soc-sgtl5000-objs := sgtl5000.o snd-soc-alc5623-objs := alc5623.o snd-soc-alc5632-objs := alc5632.o snd-soc-sigmadsp-objs := sigmadsp.o +snd-soc-si476x-objs := si476x.o snd-soc-sn95031-objs := sn95031.o snd-soc-spdif-tx-objs := spdif_transciever.o snd-soc-spdif-rx-objs := spdif_receiver.o @@ -62,6 +64,7 @@ snd-soc-twl6040-objs := twl6040.o snd-soc-uda134x-objs := uda134x.o snd-soc-uda1380-objs := uda1380.o snd-soc-wl1273-objs := wl1273.o +snd-soc-wm-adsp-objs := wm_adsp.o snd-soc-wm0010-objs := wm0010.o snd-soc-wm1250-ev1-objs := wm1250-ev1.o snd-soc-wm2000-objs := wm2000.o @@ -155,6 +158,7 @@ obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o obj-$(CONFIG_SND_SOC_LM49453) += snd-soc-lm49453.o obj-$(CONFIG_SND_SOC_MAX9768) += snd-soc-max9768.o obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o +obj-$(CONFIG_SND_SOC_MAX98090) += snd-soc-max98090.o obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o @@ -164,6 +168,7 @@ obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o +obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o @@ -229,6 +234,7 @@ obj-$(CONFIG_SND_SOC_WM9090) += snd-soc-wm9090.o obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o +obj-$(CONFIG_SND_SOC_WM_ADSP) += snd-soc-wm-adsp.o obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o # Amp diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index af547490b4f..6c12ac206ee 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, return 0; } -struct snd_soc_dai_driver ab8500_codec_dai[] = { +static struct snd_soc_dai_driver ab8500_codec_dai[] = { { .name = "ab8500-codec-dai.0", .id = 0, @@ -2554,7 +2554,7 @@ static struct snd_soc_codec_driver ab8500_codec_driver = { .num_dapm_routes = ARRAY_SIZE(ab8500_dapm_routes), }; -static int __devinit ab8500_codec_driver_probe(struct platform_device *pdev) +static int ab8500_codec_driver_probe(struct platform_device *pdev) { int status; struct ab8500_codec_drvdata *drvdata; @@ -2580,7 +2580,7 @@ static int __devinit ab8500_codec_driver_probe(struct platform_device *pdev) return status; } -static int __devexit ab8500_codec_driver_remove(struct platform_device *pdev) +static int ab8500_codec_driver_remove(struct platform_device *pdev) { dev_info(&pdev->dev, "%s Enter.\n", __func__); @@ -2595,7 +2595,7 @@ static struct platform_driver ab8500_codec_platform_driver = { .owner = THIS_MODULE, }, .probe = ab8500_codec_driver_probe, - .remove = __devexit_p(ab8500_codec_driver_remove), + .remove = ab8500_codec_driver_remove, .suspend = NULL, .resume = NULL, }; diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index ea06b834a7d..ef2ae32ffc6 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c @@ -118,13 +118,13 @@ static struct snd_soc_codec_driver soc_codec_dev_ac97 = { .resume = ac97_soc_resume, }; -static __devinit int ac97_probe(struct platform_device *pdev) +static int ac97_probe(struct platform_device *pdev) { return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_ac97, &ac97_dai, 1); } -static int __devexit ac97_remove(struct platform_device *pdev) +static int ac97_remove(struct platform_device *pdev) { snd_soc_unregister_codec(&pdev->dev); return 0; @@ -137,7 +137,7 @@ static struct platform_driver ac97_codec_driver = { }, .probe = ac97_probe, - .remove = __devexit_p(ac97_remove), + .remove = ac97_remove, }; module_platform_driver(ac97_codec_driver); diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c index dce6ebeef45..9a92b7962f4 100644 --- a/sound/soc/codecs/ad1836.c +++ b/sound/soc/codecs/ad1836.c @@ -360,7 +360,7 @@ static const struct regmap_config ad1836_regmap_config = { .cache_type = REGCACHE_RBTREE, }; -static int __devinit ad1836_spi_probe(struct spi_device *spi) +static int ad1836_spi_probe(struct spi_device *spi) { struct ad1836_priv *ad1836; int ret; @@ -383,7 +383,7 @@ static int __devinit ad1836_spi_probe(struct spi_device *spi) return ret; } -static int __devexit ad1836_spi_remove(struct spi_device *spi) +static int ad1836_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev); return 0; @@ -405,7 +405,7 @@ static struct spi_driver ad1836_spi_driver = { .owner = THIS_MODULE, }, .probe = ad1836_spi_probe, - .remove = __devexit_p(ad1836_spi_remove), + .remove = ad1836_spi_remove, .id_table = ad1836_ids, }; diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index 2f752660f67..aea7e52cf71 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c @@ -378,7 +378,7 @@ static const struct regmap_config ad193x_spi_regmap_config = { .volatile_reg = adau193x_reg_volatile, }; -static int __devinit ad193x_spi_probe(struct spi_device *spi) +static int ad193x_spi_probe(struct spi_device *spi) { struct ad193x_priv *ad193x; @@ -397,7 +397,7 @@ static int __devinit ad193x_spi_probe(struct spi_device *spi) &ad193x_dai, 1); } -static int __devexit ad193x_spi_remove(struct spi_device *spi) +static int ad193x_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev); return 0; @@ -409,7 +409,7 @@ static struct spi_driver ad193x_spi_driver = { .owner = THIS_MODULE, }, .probe = ad193x_spi_probe, - .remove = __devexit_p(ad193x_spi_remove), + .remove = ad193x_spi_remove, }; #endif @@ -430,8 +430,8 @@ static const struct i2c_device_id ad193x_id[] = { }; MODULE_DEVICE_TABLE(i2c, ad193x_id); -static int __devinit ad193x_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ad193x_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) { struct ad193x_priv *ad193x; @@ -450,7 +450,7 @@ static int __devinit ad193x_i2c_probe(struct i2c_client *client, &ad193x_dai, 1); } -static int __devexit ad193x_i2c_remove(struct i2c_client *client) +static int ad193x_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -461,7 +461,7 @@ static struct i2c_driver ad193x_i2c_driver = { .name = "ad193x", }, .probe = ad193x_i2c_probe, - .remove = __devexit_p(ad193x_i2c_remove), + .remove = ad193x_i2c_remove, .id_table = ad193x_id, }; #endif diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 8c39dddd7d0..f385342947d 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c @@ -255,13 +255,13 @@ static struct snd_soc_codec_driver soc_codec_dev_ad1980 = { .read = ac97_read, }; -static __devinit int ad1980_probe(struct platform_device *pdev) +static int ad1980_probe(struct platform_device *pdev) { return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_ad1980, &ad1980_dai, 1); } -static int __devexit ad1980_remove(struct platform_device *pdev) +static int ad1980_remove(struct platform_device *pdev) { snd_soc_unregister_codec(&pdev->dev); return 0; @@ -274,7 +274,7 @@ static struct platform_driver ad1980_codec_driver = { }, .probe = ad1980_probe, - .remove = __devexit_p(ad1980_remove), + .remove = ad1980_remove, }; module_platform_driver(ad1980_codec_driver); diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c index ee7a68dcefd..b1f2baf42b4 100644 --- a/sound/soc/codecs/ad73311.c +++ b/sound/soc/codecs/ad73311.c @@ -47,7 +47,7 @@ static int ad73311_probe(struct platform_device *pdev) &soc_codec_dev_ad73311, &ad73311_dai, 1); } -static int __devexit ad73311_remove(struct platform_device *pdev) +static int ad73311_remove(struct platform_device *pdev) { snd_soc_unregister_codec(&pdev->dev); return 0; @@ -60,7 +60,7 @@ static struct platform_driver ad73311_codec_driver = { }, .probe = ad73311_probe, - .remove = __devexit_p(ad73311_remove), + .remove = ad73311_remove, }; module_platform_driver(ad73311_codec_driver); diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c index 704544bfc90..068b3ae56a1 100644 --- a/sound/soc/codecs/adau1373.c +++ b/sound/soc/codecs/adau1373.c @@ -1353,8 +1353,8 @@ static struct snd_soc_codec_driver adau1373_codec_driver = { .num_dapm_routes = ARRAY_SIZE(adau1373_dapm_routes), }; -static int __devinit adau1373_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int adau1373_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) { struct adau1373 *adau1373; int ret; @@ -1370,7 +1370,7 @@ static int __devinit adau1373_i2c_probe(struct i2c_client *client, return ret; } -static int __devexit adau1373_i2c_remove(struct i2c_client *client) +static int adau1373_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -1388,7 +1388,7 @@ static struct i2c_driver adau1373_i2c_driver = { .owner = THIS_MODULE, }, .probe = adau1373_i2c_probe, - .remove = __devexit_p(adau1373_i2c_remove), + .remove = adau1373_i2c_remove, .id_table = adau1373_i2c_id, }; diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c index 51f2f3cd813..dafdbe87ede 100644 --- a/sound/soc/codecs/adau1701.c +++ b/sound/soc/codecs/adau1701.c @@ -489,8 +489,8 @@ static struct snd_soc_codec_driver adau1701_codec_drv = { .set_sysclk = adau1701_set_sysclk, }; -static __devinit int adau1701_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int adau1701_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) { struct adau1701 *adau1701; int ret; @@ -505,7 +505,7 @@ static __devinit int adau1701_i2c_probe(struct i2c_client *client, return ret; } -static __devexit int adau1701_i2c_remove(struct i2c_client *client) +static int adau1701_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -523,7 +523,7 @@ static struct i2c_driver adau1701_i2c_driver = { .owner = THIS_MODULE, }, .probe = adau1701_i2c_probe, - .remove = __devexit_p(adau1701_i2c_remove), + .remove = adau1701_i2c_remove, .id_table = adau1701_i2c_id, }; diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c index ebd7b37b902..3c839cc4e00 100644 --- a/sound/soc/codecs/adav80x.c +++ b/sound/soc/codecs/adav80x.c @@ -839,8 +839,8 @@ static struct snd_soc_codec_driver adav80x_codec_driver = { .num_dapm_routes = ARRAY_SIZE(adav80x_dapm_routes), }; -static int __devinit adav80x_bus_probe(struct device *dev, - enum snd_soc_control_type control_type) +static int adav80x_bus_probe(struct device *dev, + enum snd_soc_control_type control_type) { struct adav80x *adav80x; int ret; @@ -860,7 +860,7 @@ static int __devinit adav80x_bus_probe(struct device *dev, return ret; } -static int __devexit adav80x_bus_remove(struct device *dev) +static int adav80x_bus_remove(struct device *dev) { snd_soc_unregister_codec(dev); kfree(dev_get_drvdata(dev)); @@ -868,12 +868,12 @@ static int __devexit adav80x_bus_remove(struct device *dev) } #if defined(CONFIG_SPI_MASTER) -static int __devinit adav80x_spi_probe(struct spi_device *spi) +static int adav80x_spi_probe(struct spi_device *spi) { return adav80x_bus_probe(&spi->dev, SND_SOC_SPI); } -static int __devexit adav80x_spi_remove(struct spi_device *spi) +static int adav80x_spi_remove(struct spi_device *spi) { return adav80x_bus_remove(&spi->dev); } @@ -884,7 +884,7 @@ static struct spi_driver adav80x_spi_driver = { .owner = THIS_MODULE, }, .probe = adav80x_spi_probe, - .remove = __devexit_p(adav80x_spi_remove), + .remove = adav80x_spi_remove, }; #endif @@ -895,13 +895,13 @@ static const struct i2c_device_id adav80x_id[] = { }; MODULE_DEVICE_TABLE(i2c, adav80x_id); -static int __devinit adav80x_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int adav80x_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) { return adav80x_bus_probe(&client->dev, SND_SOC_I2C); } -static int __devexit adav80x_i2c_remove(struct i2c_client *client) +static int adav80x_i2c_remove(struct i2c_client *client) { return adav80x_bus_remove(&client->dev); } @@ -912,7 +912,7 @@ static struct i2c_driver adav80x_i2c_driver = { .owner = THIS_MODULE, }, .probe = adav80x_i2c_probe, - .remove = __devexit_p(adav80x_i2c_remove), + .remove = adav80x_i2c_remove, .id_table = adav80x_id, }; #endif diff --git a/sound/soc/codecs/ads117x.c b/sound/soc/codecs/ads117x.c index 8103b938b8c..506d474c4d2 100644 --- a/sound/soc/codecs/ads117x.c +++ b/sound/soc/codecs/ads117x.c @@ -36,13 +36,13 @@ static struct snd_soc_dai_driver ads117x_dai = { static struct snd_soc_codec_driver soc_codec_dev_ads117x; -static __devinit int ads117x_probe(struct platform_device *pdev) +static int ads117x_probe(struct platform_device *pdev) { return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_ads117x, &ads117x_dai, 1); } -static int __devexit ads117x_remove(struct platform_device *pdev) +static int ads117x_remove(struct platform_device *pdev) { snd_soc_unregister_codec(&pdev->dev); return 0; @@ -55,7 +55,7 @@ static struct platform_driver ads117x_codec_driver = { }, .probe = ads117x_probe, - .remove = __devexit_p(ads117x_remove), + .remove = ads117x_remove, }; module_platform_driver(ads117x_codec_driver); diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c index 31d4483245d..6f6c335a5ba 100644 --- a/sound/soc/codecs/ak4104.c +++ b/sound/soc/codecs/ak4104.c @@ -15,6 +15,8 @@ #include <sound/soc.h> #include <sound/initval.h> #include <linux/spi/spi.h> +#include <linux/of_device.h> +#include <linux/of_gpio.h> #include <sound/asoundef.h> /* AK4104 registers addresses */ @@ -98,14 +100,32 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream, val = 0; switch (params_rate(params)) { + case 22050: + val |= IEC958_AES3_CON_FS_22050; + break; + case 24000: + val |= IEC958_AES3_CON_FS_24000; + break; + case 32000: + val |= IEC958_AES3_CON_FS_32000; + break; case 44100: val |= IEC958_AES3_CON_FS_44100; break; case 48000: val |= IEC958_AES3_CON_FS_48000; break; - case 32000: - val |= IEC958_AES3_CON_FS_32000; + case 88200: + val |= IEC958_AES3_CON_FS_88200; + break; + case 96000: + val |= IEC958_AES3_CON_FS_96000; + break; + case 176400: + val |= IEC958_AES3_CON_FS_176400; + break; + case 192000: + val |= IEC958_AES3_CON_FS_192000; break; default: dev_err(codec->dev, "unsupported sampling rate\n"); @@ -186,6 +206,7 @@ static const struct regmap_config ak4104_regmap = { static int ak4104_spi_probe(struct spi_device *spi) { + struct device_node *np = spi->dev.of_node; struct ak4104_private *ak4104; unsigned int val; int ret; @@ -201,52 +222,62 @@ static int ak4104_spi_probe(struct spi_device *spi) if (ak4104 == NULL) return -ENOMEM; - ak4104->regmap = regmap_init_spi(spi, &ak4104_regmap); + ak4104->regmap = devm_regmap_init_spi(spi, &ak4104_regmap); if (IS_ERR(ak4104->regmap)) { ret = PTR_ERR(ak4104->regmap); return ret; } + if (np) { + enum of_gpio_flags flags; + int gpio = of_get_named_gpio_flags(np, "reset-gpio", 0, &flags); + + if (gpio_is_valid(gpio)) { + ret = devm_gpio_request_one(&spi->dev, gpio, + flags & OF_GPIO_ACTIVE_LOW ? + GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH, + "ak4104 reset"); + if (ret < 0) + return ret; + } + } + /* read the 'reserved' register - according to the datasheet, it * should contain 0x5b. Not a good way to verify the presence of * the device, but there is no hardware ID register. */ ret = regmap_read(ak4104->regmap, AK4104_REG_RESERVED, &val); if (ret != 0) - goto err; - if (val != AK4104_RESERVED_VAL) { - ret = -ENODEV; - goto err; - } + return ret; + if (val != AK4104_RESERVED_VAL) + return -ENODEV; spi_set_drvdata(spi, ak4104); ret = snd_soc_register_codec(&spi->dev, &soc_codec_device_ak4104, &ak4104_dai, 1); - if (ret != 0) - goto err; - - return 0; - -err: - regmap_exit(ak4104->regmap); return ret; } -static int __devexit ak4104_spi_remove(struct spi_device *spi) +static int ak4104_spi_remove(struct spi_device *spi) { - struct ak4104_private *ak4101 = spi_get_drvdata(spi); - regmap_exit(ak4101->regmap); snd_soc_unregister_codec(&spi->dev); return 0; } +static const struct of_device_id ak4104_of_match[] = { + { .compatible = "asahi-kasei,ak4104", }, + { } +}; +MODULE_DEVICE_TABLE(of, ak4104_of_match); + static struct spi_driver ak4104_spi_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, + .of_match_table = ak4104_of_match, }, .probe = ak4104_spi_probe, - .remove = __devexit_p(ak4104_spi_remove), + .remove = ak4104_spi_remove, }; module_spi_driver(ak4104_spi_driver); diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index 618fdc30f73..684fe910669 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c @@ -436,8 +436,8 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4535 = { .num_dapm_routes = ARRAY_SIZE(ak4535_audio_map), }; -static __devinit int ak4535_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ak4535_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct ak4535_priv *ak4535; int ret; @@ -447,7 +447,7 @@ static __devinit int ak4535_i2c_probe(struct i2c_client *i2c, if (ak4535 == NULL) return -ENOMEM; - ak4535->regmap = regmap_init_i2c(i2c, &ak4535_regmap); + ak4535->regmap = devm_regmap_init_i2c(i2c, &ak4535_regmap); if (IS_ERR(ak4535->regmap)) { ret = PTR_ERR(ak4535->regmap); 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, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_ak4535, &ak4535_dai, 1); - if (ret != 0) - regmap_exit(ak4535->regmap); return ret; } -static __devexit int ak4535_i2c_remove(struct i2c_client *client) +static int ak4535_i2c_remove(struct i2c_client *client) { - struct ak4535_priv *ak4535 = i2c_get_clientdata(client); - snd_soc_unregister_codec(&client->dev); - regmap_exit(ak4535->regmap); return 0; } @@ -485,7 +480,7 @@ static struct i2c_driver ak4535_i2c_driver = { .owner = THIS_MODULE, }, .probe = ak4535_i2c_probe, - .remove = __devexit_p(ak4535_i2c_remove), + .remove = ak4535_i2c_remove, .id_table = ak4535_i2c_id, }; diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c index 543a12f471b..5f9af1fb76e 100644 --- a/sound/soc/codecs/ak4641.c +++ b/sound/soc/codecs/ak4641.c @@ -557,8 +557,8 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4641 = { }; -static int __devinit ak4641_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ak4641_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct ak4641_platform_data *pdata = i2c->dev.platform_data; struct ak4641_priv *ak4641; @@ -610,7 +610,7 @@ err_out: return ret; } -static int __devexit ak4641_i2c_remove(struct i2c_client *i2c) +static int ak4641_i2c_remove(struct i2c_client *i2c) { struct ak4641_platform_data *pdata = i2c->dev.platform_data; @@ -640,7 +640,7 @@ static struct i2c_driver ak4641_i2c_driver = { .owner = THIS_MODULE, }, .probe = ak4641_i2c_probe, - .remove = __devexit_p(ak4641_i2c_remove), + .remove = ak4641_i2c_remove, .id_table = ak4641_i2c_id, }; diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index b3e24f28942..1f0cdab0329 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[] = { {"LINEOUT Mixer", "DACL", "DAC"}, }; -/* codec private data */ -struct ak4642_priv { - unsigned int sysclk; - enum snd_soc_control_type control_type; -}; - /* * ak4642 register cache */ @@ -468,10 +462,9 @@ static int ak4642_resume(struct snd_soc_codec *codec) static int ak4642_probe(struct snd_soc_codec *codec) { - struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec); int ret; - ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4642->control_type); + ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); if (ret < 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); return ret; @@ -520,27 +513,15 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4648 = { }; #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static __devinit int ak4642_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ak4642_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { - struct ak4642_priv *ak4642; - int ret; - - ak4642 = devm_kzalloc(&i2c->dev, sizeof(struct ak4642_priv), - GFP_KERNEL); - if (!ak4642) - return -ENOMEM; - - i2c_set_clientdata(i2c, ak4642); - ak4642->control_type = SND_SOC_I2C; - - ret = snd_soc_register_codec(&i2c->dev, + return snd_soc_register_codec(&i2c->dev, (struct snd_soc_codec_driver *)id->driver_data, &ak4642_dai, 1); - return ret; } -static __devexit int ak4642_i2c_remove(struct i2c_client *client) +static int ak4642_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -560,7 +541,7 @@ static struct i2c_driver ak4642_i2c_driver = { .owner = THIS_MODULE, }, .probe = ak4642_i2c_probe, - .remove = __devexit_p(ak4642_i2c_remove), + .remove = ak4642_i2c_remove, .id_table = ak4642_i2c_id, }; #endif diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c index 2b457976a7b..25bdf6ad4a5 100644 --- a/sound/soc/codecs/ak4671.c +++ b/sound/soc/codecs/ak4671.c @@ -655,8 +655,8 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4671 = { .num_dapm_routes = ARRAY_SIZE(ak4671_intercon), }; -static int __devinit ak4671_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ak4671_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) { struct ak4671_priv *ak4671; int ret; @@ -674,7 +674,7 @@ static int __devinit ak4671_i2c_probe(struct i2c_client *client, return ret; } -static __devexit int ak4671_i2c_remove(struct i2c_client *client) +static int ak4671_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -692,7 +692,7 @@ static struct i2c_driver ak4671_i2c_driver = { .owner = THIS_MODULE, }, .probe = ak4671_i2c_probe, - .remove = __devexit_p(ak4671_i2c_remove), + .remove = ak4671_i2c_remove, .id_table = ak4671_i2c_id, }; diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c index 1960478ce6b..256c364193a 100644 --- a/sound/soc/codecs/alc5623.c +++ b/sound/soc/codecs/alc5623.c @@ -991,8 +991,8 @@ static struct snd_soc_codec_driver soc_codec_device_alc5623 = { * low = 0x1a * high = 0x1b */ -static __devinit int alc5623_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int alc5623_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) { struct alc5623_platform_data *pdata; struct alc5623_priv *alc5623; @@ -1058,7 +1058,7 @@ static __devinit int alc5623_i2c_probe(struct i2c_client *client, return ret; } -static __devexit int alc5623_i2c_remove(struct i2c_client *client) +static int alc5623_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -1079,7 +1079,7 @@ static struct i2c_driver alc5623_i2c_driver = { .owner = THIS_MODULE, }, .probe = alc5623_i2c_probe, - .remove = __devexit_p(alc5623_i2c_remove), + .remove = alc5623_i2c_remove, .id_table = alc5623_i2c_table, }; diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c index 7dd02420b36..f2e62e45f91 100644 --- a/sound/soc/codecs/alc5632.c +++ b/sound/soc/codecs/alc5632.c @@ -1116,8 +1116,8 @@ static struct regmap_config alc5632_regmap = { * low = 0x1a * high = 0x1b */ -static __devinit int alc5632_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int alc5632_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) { struct alc5632_priv *alc5632; int ret, ret1, ret2; @@ -1179,7 +1179,7 @@ static __devinit int alc5632_i2c_probe(struct i2c_client *client, return ret; } -static __devexit int alc5632_i2c_remove(struct i2c_client *client) +static int alc5632_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -1198,7 +1198,7 @@ static struct i2c_driver alc5632_i2c_driver = { .owner = THIS_MODULE, }, .probe = alc5632_i2c_probe, - .remove = __devexit_p(alc5632_i2c_remove), + .remove = alc5632_i2c_remove, .id_table = alc5632_i2c_table, }; diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 054967d8bac..adf397b9d0e 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -226,6 +226,31 @@ EXPORT_SYMBOL_GPL(arizona_mixer_values); const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0); EXPORT_SYMBOL_GPL(arizona_mixer_tlv); +static const char *arizona_vol_ramp_text[] = { + "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB", + "15ms/6dB", "30ms/6dB", +}; + +const struct soc_enum arizona_in_vd_ramp = + SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP, + ARIZONA_IN_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text); +EXPORT_SYMBOL_GPL(arizona_in_vd_ramp); + +const struct soc_enum arizona_in_vi_ramp = + SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP, + ARIZONA_IN_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text); +EXPORT_SYMBOL_GPL(arizona_in_vi_ramp); + +const struct soc_enum arizona_out_vd_ramp = + SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP, + ARIZONA_OUT_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text); +EXPORT_SYMBOL_GPL(arizona_out_vd_ramp); + +const struct soc_enum arizona_out_vi_ramp = + SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP, + ARIZONA_OUT_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text); +EXPORT_SYMBOL_GPL(arizona_out_vi_ramp); + static const char *arizona_lhpf_mode_text[] = { "Low-pass", "High-pass" }; @@ -380,6 +405,18 @@ int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, case 49152000: val |= 3 << ARIZONA_SYSCLK_FREQ_SHIFT; break; + case 67737600: + case 73728000: + val |= 4 << ARIZONA_SYSCLK_FREQ_SHIFT; + break; + case 90316800: + case 98304000: + val |= 5 << ARIZONA_SYSCLK_FREQ_SHIFT; + break; + case 135475200: + case 147456000: + val |= 6 << ARIZONA_SYSCLK_FREQ_SHIFT; + break; default: return -EINVAL; } @@ -737,6 +774,9 @@ static int arizona_dai_set_sysclk(struct snd_soc_dai *dai, return -EBUSY; } + dev_dbg(codec->dev, "Setting AIF%d to %s\n", dai->id + 1, + arizona_dai_clk_str(clk_id)); + memset(&routes, 0, sizeof(routes)); routes[0].sink = dai->driver->capture.stream_name; routes[1].sink = dai->driver->playback.stream_name; @@ -749,6 +789,8 @@ static int arizona_dai_set_sysclk(struct snd_soc_dai *dai, routes[1].source = arizona_dai_clk_str(clk_id); snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes)); + dai_priv->clk = clk_id; + return snd_soc_dapm_sync(&codec->dapm); } @@ -925,6 +967,9 @@ int arizona_set_fll(struct arizona_fll *fll, int source, bool ena; int ret; + if (fll->fref == Fref && fll->fout == Fout) + return 0; + ret = regmap_read(arizona->regmap, fll->base + 1, ®); if (ret != 0) { arizona_fll_err(fll, "Failed to read current state: %d\n", @@ -970,6 +1015,9 @@ int arizona_set_fll(struct arizona_fll *fll, int source, if (ena) pm_runtime_put_autosuspend(arizona->dev); + fll->fref = Fref; + fll->fout = Fout; + return 0; } @@ -998,10 +1046,13 @@ int arizona_set_fll(struct arizona_fll *fll, int source, ARIZONA_FLL1_SYNC_ENA); ret = wait_for_completion_timeout(&fll->ok, - msecs_to_jiffies(25)); + msecs_to_jiffies(250)); if (ret == 0) arizona_fll_warn(fll, "Timed out waiting for lock\n"); + fll->fref = Fref; + fll->fout = Fout; + return 0; } EXPORT_SYMBOL_GPL(arizona_set_fll); diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 36ec6494612..41dae1ed3b7 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h @@ -17,6 +17,8 @@ #include <sound/soc.h> +#include "wm_adsp.h" + #define ARIZONA_CLK_SYSCLK 1 #define ARIZONA_CLK_ASYNCCLK 2 #define ARIZONA_CLK_OPCLK 3 @@ -46,15 +48,18 @@ #define ARIZONA_MIXER_VOL_SHIFT 1 #define ARIZONA_MIXER_VOL_WIDTH 7 -#define ARIZONA_MAX_DAI 3 +#define ARIZONA_MAX_DAI 4 +#define ARIZONA_MAX_ADSP 4 struct arizona; +struct wm_adsp; struct arizona_dai_priv { int clk; }; struct arizona_priv { + struct wm_adsp adsp[ARIZONA_MAX_ADSP]; struct arizona *arizona; int sysclk; int asyncclk; @@ -89,19 +94,30 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; const struct snd_kcontrol_new name##_mux = \ SOC_DAPM_VALUE_ENUM("Route", name##_enum) +#define ARIZONA_MUX_ENUMS(name, base_reg) \ + static ARIZONA_MUX_ENUM_DECL(name##_enum, base_reg); \ + static ARIZONA_MUX_CTL_DECL(name) + #define ARIZONA_MIXER_ENUMS(name, base_reg) \ - static ARIZONA_MUX_ENUM_DECL(name##_in1_enum, base_reg); \ - static ARIZONA_MUX_ENUM_DECL(name##_in2_enum, base_reg + 2); \ - static ARIZONA_MUX_ENUM_DECL(name##_in3_enum, base_reg + 4); \ - static ARIZONA_MUX_ENUM_DECL(name##_in4_enum, base_reg + 6); \ - static ARIZONA_MUX_CTL_DECL(name##_in1); \ - static ARIZONA_MUX_CTL_DECL(name##_in2); \ - static ARIZONA_MUX_CTL_DECL(name##_in3); \ - static ARIZONA_MUX_CTL_DECL(name##_in4) + ARIZONA_MUX_ENUMS(name##_in1, base_reg); \ + ARIZONA_MUX_ENUMS(name##_in2, base_reg + 2); \ + ARIZONA_MUX_ENUMS(name##_in3, base_reg + 4); \ + ARIZONA_MUX_ENUMS(name##_in4, base_reg + 6) + +#define ARIZONA_DSP_AUX_ENUMS(name, base_reg) \ + ARIZONA_MUX_ENUMS(name##_aux1, base_reg); \ + ARIZONA_MUX_ENUMS(name##_aux2, base_reg + 8); \ + ARIZONA_MUX_ENUMS(name##_aux3, base_reg + 16); \ + ARIZONA_MUX_ENUMS(name##_aux4, base_reg + 24); \ + ARIZONA_MUX_ENUMS(name##_aux5, base_reg + 32); \ + ARIZONA_MUX_ENUMS(name##_aux6, base_reg + 40) #define ARIZONA_MUX(name, ctrl) \ SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) +#define ARIZONA_MUX_WIDGETS(name, name_str) \ + ARIZONA_MUX(name_str " Input", &name##_mux) + #define ARIZONA_MIXER_WIDGETS(name, name_str) \ ARIZONA_MUX(name_str " Input 1", &name##_in1_mux), \ ARIZONA_MUX(name_str " Input 2", &name##_in2_mux), \ @@ -109,6 +125,19 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; ARIZONA_MUX(name_str " Input 4", &name##_in4_mux), \ SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0) +#define ARIZONA_DSP_WIDGETS(name, name_str) \ + ARIZONA_MIXER_WIDGETS(name##L, name_str "L"), \ + ARIZONA_MIXER_WIDGETS(name##R, name_str "R"), \ + ARIZONA_MUX(name_str " Aux 1", &name##_aux1_mux), \ + ARIZONA_MUX(name_str " Aux 2", &name##_aux2_mux), \ + ARIZONA_MUX(name_str " Aux 3", &name##_aux3_mux), \ + ARIZONA_MUX(name_str " Aux 4", &name##_aux4_mux), \ + ARIZONA_MUX(name_str " Aux 5", &name##_aux5_mux), \ + ARIZONA_MUX(name_str " Aux 6", &name##_aux6_mux) + +#define ARIZONA_MUX_ROUTES(name) \ + ARIZONA_MIXER_INPUT_ROUTES(name " Input") + #define ARIZONA_MIXER_ROUTES(widget, name) \ { widget, NULL, name " Mixer" }, \ { name " Mixer", NULL, name " Input 1" }, \ @@ -120,6 +149,28 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; ARIZONA_MIXER_INPUT_ROUTES(name " Input 3"), \ ARIZONA_MIXER_INPUT_ROUTES(name " Input 4") +#define ARIZONA_DSP_ROUTES(name) \ + { name, NULL, name " Aux 1" }, \ + { name, NULL, name " Aux 2" }, \ + { name, NULL, name " Aux 3" }, \ + { name, NULL, name " Aux 4" }, \ + { name, NULL, name " Aux 5" }, \ + { name, NULL, name " Aux 6" }, \ + ARIZONA_MIXER_INPUT_ROUTES(name " Aux 1"), \ + ARIZONA_MIXER_INPUT_ROUTES(name " Aux 2"), \ + ARIZONA_MIXER_INPUT_ROUTES(name " Aux 3"), \ + ARIZONA_MIXER_INPUT_ROUTES(name " Aux 4"), \ + ARIZONA_MIXER_INPUT_ROUTES(name " Aux 5"), \ + ARIZONA_MIXER_INPUT_ROUTES(name " Aux 6"), \ + ARIZONA_MIXER_ROUTES(name, name "L"), \ + ARIZONA_MIXER_ROUTES(name, name "R") + +extern const struct soc_enum arizona_in_vi_ramp; +extern const struct soc_enum arizona_in_vd_ramp; + +extern const struct soc_enum arizona_out_vi_ramp; +extern const struct soc_enum arizona_out_vd_ramp; + extern const struct soc_enum arizona_lhpf1_mode; extern const struct soc_enum arizona_lhpf2_mode; extern const struct soc_enum arizona_lhpf3_mode; @@ -146,6 +197,8 @@ struct arizona_fll { unsigned int vco_mult; struct completion lock; struct completion ok; + unsigned int fref; + unsigned int fout; char lock_name[ARIZONA_FLL_NAME_LEN]; char clock_ok_name[ARIZONA_FLL_NAME_LEN]; diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c index 064cd6a9351..23316c887b1 100644 --- a/sound/soc/codecs/cq93vc.c +++ b/sound/soc/codecs/cq93vc.c @@ -201,7 +201,7 @@ static struct platform_driver cq93vc_codec_driver = { }, .probe = cq93vc_platform_probe, - .remove = __devexit_p(cq93vc_platform_remove), + .remove = cq93vc_platform_remove, }; module_platform_driver(cq93vc_codec_driver); diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index e3f0a7f3131..4f1127935fd 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) struct cs4271_platform_data *cs4271plat = codec->dev->platform_data; int ret; int gpio_nreset = -EINVAL; + int amutec_eq_bmutec = 0; #ifdef CONFIG_OF - if (of_match_device(cs4271_dt_ids, codec->dev)) + if (of_match_device(cs4271_dt_ids, codec->dev)) { gpio_nreset = of_get_named_gpio(codec->dev->of_node, "reset-gpio", 0); + + if (!of_get_property(codec->dev->of_node, + "cirrus,amutec-eq-bmutec", NULL)) + amutec_eq_bmutec = 1; + } #endif - if (cs4271plat && gpio_is_valid(cs4271plat->gpio_nreset)) - gpio_nreset = cs4271plat->gpio_nreset; + if (cs4271plat) { + if (gpio_is_valid(cs4271plat->gpio_nreset)) + gpio_nreset = cs4271plat->gpio_nreset; + + amutec_eq_bmutec = cs4271plat->amutec_eq_bmutec; + } if (gpio_nreset >= 0) if (devm_gpio_request(codec->dev, gpio_nreset, "CS4271 Reset")) @@ -528,6 +538,11 @@ static int cs4271_probe(struct snd_soc_codec *codec) /* Power-up sequence requires 85 uS */ udelay(85); + if (amutec_eq_bmutec) + snd_soc_update_bits(codec, CS4271_MODE2, + CS4271_MODE2_MUTECAEQUB, + CS4271_MODE2_MUTECAEQUB); + return snd_soc_add_codec_controls(codec, cs4271_snd_controls, ARRAY_SIZE(cs4271_snd_controls)); } @@ -555,7 +570,7 @@ static struct snd_soc_codec_driver soc_codec_dev_cs4271 = { }; #if defined(CONFIG_SPI_MASTER) -static int __devinit cs4271_spi_probe(struct spi_device *spi) +static int cs4271_spi_probe(struct spi_device *spi) { struct cs4271_private *cs4271; @@ -570,7 +585,7 @@ static int __devinit cs4271_spi_probe(struct spi_device *spi) &cs4271_dai, 1); } -static int __devexit cs4271_spi_remove(struct spi_device *spi) +static int cs4271_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev); return 0; @@ -583,7 +598,7 @@ static struct spi_driver cs4271_spi_driver = { .of_match_table = of_match_ptr(cs4271_dt_ids), }, .probe = cs4271_spi_probe, - .remove = __devexit_p(cs4271_spi_remove), + .remove = cs4271_spi_remove, }; #endif /* defined(CONFIG_SPI_MASTER) */ @@ -594,8 +609,8 @@ static const struct i2c_device_id cs4271_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, cs4271_i2c_id); -static int __devinit cs4271_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int cs4271_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) { struct cs4271_private *cs4271; @@ -610,7 +625,7 @@ static int __devinit cs4271_i2c_probe(struct i2c_client *client, &cs4271_dai, 1); } -static int __devexit cs4271_i2c_remove(struct i2c_client *client) +static int cs4271_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -624,7 +639,7 @@ static struct i2c_driver cs4271_i2c_driver = { }, .id_table = cs4271_i2c_id, .probe = cs4271_i2c_probe, - .remove = __devexit_p(cs4271_i2c_remove), + .remove = cs4271_i2c_remove, }; #endif /* defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) */ diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 97a81051e88..99bb1c69499 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c @@ -1271,7 +1271,7 @@ static struct i2c_driver cs42l52_i2c_driver = { }, .id_table = cs42l52_id, .probe = cs42l52_i2c_probe, - .remove = __devexit_p(cs42l52_i2c_remove), + .remove = cs42l52_i2c_remove, }; module_i2c_driver(cs42l52_i2c_driver); diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 2c08c4cb465..a0791ecf6d9 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c @@ -1345,8 +1345,8 @@ static struct regmap_config cs42l73_regmap = { .cache_type = REGCACHE_RBTREE, }; -static __devinit int cs42l73_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) +static int cs42l73_i2c_probe(struct i2c_client *i2c_client, + const struct i2c_device_id *id) { struct cs42l73_private *cs42l73; int ret; @@ -1406,7 +1406,7 @@ static __devinit int cs42l73_i2c_probe(struct i2c_client *i2c_client, return 0; } -static __devexit int cs42l73_i2c_remove(struct i2c_client *client) +static int cs42l73_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -1426,7 +1426,7 @@ static struct i2c_driver cs42l73_i2c_driver = { }, .id_table = cs42l73_id, .probe = cs42l73_i2c_probe, - .remove = __devexit_p(cs42l73_i2c_remove), + .remove = cs42l73_i2c_remove, }; diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index af5db708051..9c123145650 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c @@ -1218,8 +1218,8 @@ static const struct regmap_config da7210_regmap_config_i2c = { .cache_type = REGCACHE_RBTREE, }; -static int __devinit da7210_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int da7210_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct da7210_priv *da7210; int ret; @@ -1231,7 +1231,7 @@ static int __devinit da7210_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, da7210); - da7210->regmap = regmap_init_i2c(i2c, &da7210_regmap_config_i2c); + da7210->regmap = devm_regmap_init_i2c(i2c, &da7210_regmap_config_i2c); if (IS_ERR(da7210->regmap)) { ret = PTR_ERR(da7210->regmap); dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); @@ -1245,24 +1245,15 @@ static int __devinit da7210_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da7210, &da7210_dai, 1); - if (ret < 0) { + if (ret < 0) dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); - goto err_regmap; - } - return ret; - -err_regmap: - regmap_exit(da7210->regmap); return ret; } -static int __devexit da7210_i2c_remove(struct i2c_client *client) +static int da7210_i2c_remove(struct i2c_client *client) { - struct da7210_priv *da7210 = i2c_get_clientdata(client); - snd_soc_unregister_codec(&client->dev); - regmap_exit(da7210->regmap); return 0; } @@ -1279,7 +1270,7 @@ static struct i2c_driver da7210_i2c_driver = { .owner = THIS_MODULE, }, .probe = da7210_i2c_probe, - .remove = __devexit_p(da7210_i2c_remove), + .remove = da7210_i2c_remove, .id_table = da7210_i2c_id, }; #endif @@ -1323,7 +1314,7 @@ static const struct regmap_config da7210_regmap_config_spi = { .cache_type = REGCACHE_RBTREE, }; -static int __devinit da7210_spi_probe(struct spi_device *spi) +static int da7210_spi_probe(struct spi_device *spi) { struct da7210_priv *da7210; int ret; @@ -1346,24 +1337,15 @@ static int __devinit da7210_spi_probe(struct spi_device *spi) if (ret != 0) dev_warn(&spi->dev, "Failed to apply regmap patch: %d\n", ret); - ret = snd_soc_register_codec(&spi->dev, + ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_da7210, &da7210_dai, 1); - if (ret < 0) - goto err_regmap; - - return ret; - -err_regmap: - regmap_exit(da7210->regmap); return ret; } -static int __devexit da7210_spi_remove(struct spi_device *spi) +static int da7210_spi_remove(struct spi_device *spi) { - struct da7210_priv *da7210 = spi_get_drvdata(spi); snd_soc_unregister_codec(&spi->dev); - regmap_exit(da7210->regmap); return 0; } @@ -1373,7 +1355,7 @@ static struct spi_driver da7210_spi_driver = { .owner = THIS_MODULE, }, .probe = da7210_spi_probe, - .remove = __devexit_p(da7210_spi_remove) + .remove = da7210_spi_remove }; #endif diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c index 01be2a320e2..dc0284dc9e6 100644 --- a/sound/soc/codecs/da732x.c +++ b/sound/soc/codecs/da732x.c @@ -1557,8 +1557,8 @@ static struct snd_soc_codec_driver soc_codec_dev_da732x = { .reg_cache_size = ARRAY_SIZE(da732x_reg_cache), }; -static __devinit int da732x_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int da732x_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct da732x_priv *da732x; unsigned int reg; @@ -1596,7 +1596,7 @@ err: return ret; } -static __devexit int da732x_i2c_remove(struct i2c_client *client) +static int da732x_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); @@ -1615,7 +1615,7 @@ static struct i2c_driver da732x_i2c_driver = { .owner = THIS_MODULE, }, .probe = da732x_i2c_probe, - .remove = __devexit_p(da732x_i2c_remove), + .remove = da732x_i2c_remove, .id_table = da732x_i2c_id, }; diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c index f379b085c39..fc9802d1281 100644 --- a/sound/soc/codecs/da9055.c +++ b/sound/soc/codecs/da9055.c @@ -173,6 +173,7 @@ #define DA9055_AIF_FORMAT_I2S_MODE (0 << 0) #define DA9055_AIF_FORMAT_LEFT_J (1 << 0) #define DA9055_AIF_FORMAT_RIGHT_J (2 << 0) +#define DA9055_AIF_FORMAT_DSP (3 << 0) #define DA9055_AIF_WORD_S16_LE (0 << 2) #define DA9055_AIF_WORD_S20_3LE (1 << 2) #define DA9055_AIF_WORD_S24_LE (2 << 2) @@ -752,6 +753,17 @@ static const struct snd_kcontrol_new da9055_dapm_mixoutr_controls[] = { 6, 1, 0), }; +/* Headphone Output Enable */ +static const struct snd_kcontrol_new da9055_dapm_hp_l_control = +SOC_DAPM_SINGLE("Switch", DA9055_HP_L_CTRL, 3, 1, 0); + +static const struct snd_kcontrol_new da9055_dapm_hp_r_control = +SOC_DAPM_SINGLE("Switch", DA9055_HP_R_CTRL, 3, 1, 0); + +/* Lineout Output Enable */ +static const struct snd_kcontrol_new da9055_dapm_lineout_control = +SOC_DAPM_SINGLE("Switch", DA9055_LINE_CTRL, 3, 1, 0); + /* DAPM widgets */ static const struct snd_soc_dapm_widget da9055_dapm_widgets[] = { /* Input Side */ @@ -816,6 +828,14 @@ static const struct snd_soc_dapm_widget da9055_dapm_widgets[] = { &da9055_dapm_mixoutr_controls[0], ARRAY_SIZE(da9055_dapm_mixoutr_controls)), + /* Output Enable Switches */ + SND_SOC_DAPM_SWITCH("Headphone Left Enable", SND_SOC_NOPM, 0, 0, + &da9055_dapm_hp_l_control), + SND_SOC_DAPM_SWITCH("Headphone Right Enable", SND_SOC_NOPM, 0, 0, + &da9055_dapm_hp_r_control), + SND_SOC_DAPM_SWITCH("Lineout Enable", SND_SOC_NOPM, 0, 0, + &da9055_dapm_lineout_control), + /* Output PGAs */ SND_SOC_DAPM_PGA("MIXOUT Left", DA9055_MIXOUT_L_CTRL, 7, 0, NULL, 0), 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[] = { {"Out Mixer Right", "DAC Right Switch", "DAC Right"}, {"MIXOUT Left", NULL, "Out Mixer Left"}, - {"Headphone Left", NULL, "MIXOUT Left"}, + {"Headphone Left Enable", "Switch", "MIXOUT Left"}, + {"Headphone Left", NULL, "Headphone Left Enable"}, {"Headphone Left", NULL, "Charge Pump"}, {"HPL", NULL, "Headphone Left"}, {"MIXOUT Right", NULL, "Out Mixer Right"}, - {"Headphone Right", NULL, "MIXOUT Right"}, + {"Headphone Right Enable", "Switch", "MIXOUT Right"}, + {"Headphone Right", NULL, "Headphone Right Enable"}, {"Headphone Right", NULL, "Charge Pump"}, {"HPR", NULL, "Headphone Right"}, {"MIXOUT Right", NULL, "Out Mixer Right"}, - {"Lineout", NULL, "MIXOUT Right"}, + {"Lineout Enable", "Switch", "MIXOUT Right"}, + {"Lineout", NULL, "Lineout Enable"}, {"LINE", NULL, "Lineout"}, }; @@ -1175,6 +1198,9 @@ static int da9055_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) case SND_SOC_DAIFMT_RIGHT_J: aif_ctrl = DA9055_AIF_FORMAT_RIGHT_J; break; + case SND_SOC_DAIFMT_DSP_A: + aif_ctrl = DA9055_AIF_FORMAT_DSP; + break; default: return -EINVAL; } @@ -1390,8 +1416,7 @@ static int da9055_probe(struct snd_soc_codec *codec) DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN); /* - * There are two separate control bits for input and output mixers as - * well as headphone and line outs. + * There are two separate control bits for input and output mixers. * One to enable corresponding amplifier and other to enable its * output. As amplifier bits are related to power control, they are * being managed by DAPM while other (non power related) bits are @@ -1407,14 +1432,6 @@ static int da9055_probe(struct snd_soc_codec *codec) snd_soc_update_bits(codec, DA9055_MIXOUT_R_CTRL, DA9055_MIXOUT_R_MIX_EN, DA9055_MIXOUT_R_MIX_EN); - snd_soc_update_bits(codec, DA9055_HP_L_CTRL, - DA9055_HP_L_AMP_OE, DA9055_HP_L_AMP_OE); - snd_soc_update_bits(codec, DA9055_HP_R_CTRL, - DA9055_HP_R_AMP_OE, DA9055_HP_R_AMP_OE); - - snd_soc_update_bits(codec, DA9055_LINE_CTRL, - DA9055_LINE_AMP_OE, DA9055_LINE_AMP_OE); - /* Set this as per your system configuration */ snd_soc_write(codec, DA9055_PLL_CTRL, DA9055_PLL_INDIV_10_20_MHZ); @@ -1467,8 +1484,8 @@ static const struct regmap_config da9055_regmap_config = { .cache_type = REGCACHE_RBTREE, }; -static int __devinit da9055_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int da9055_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct da9055_priv *da9055; struct da9055_platform_data *pdata = dev_get_platdata(&i2c->dev); @@ -1500,7 +1517,7 @@ static int __devinit da9055_i2c_probe(struct i2c_client *i2c, return ret; } -static int __devexit da9055_remove(struct i2c_client *client) +static int da9055_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -1519,7 +1536,7 @@ static struct i2c_driver da9055_i2c_driver = { .owner = THIS_MODULE, }, .probe = da9055_i2c_probe, - .remove = __devexit_p(da9055_remove), + .remove = da9055_remove, .id_table = da9055_i2c_id, }; diff --git a/sound/soc/codecs/dfbmcs320.c b/sound/soc/codecs/dfbmcs320.c index bfe46aa9036..4f4f7f41a7d 100644 --- a/sound/soc/codecs/dfbmcs320.c +++ b/sound/soc/codecs/dfbmcs320.c @@ -33,13 +33,13 @@ static struct snd_soc_dai_driver dfbmcs320_dai = { static struct snd_soc_codec_driver soc_codec_dev_dfbmcs320; -static int __devinit dfbmcs320_probe(struct platform_device *pdev) +static int dfbmcs320_probe(struct platform_device *pdev) { return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_dfbmcs320, &dfbmcs320_dai, 1); } -static int __devexit dfbmcs320_remove(struct platform_device *pdev) +static int dfbmcs320_remove(struct platform_device *pdev) { snd_soc_unregister_codec(&pdev->dev); @@ -52,7 +52,7 @@ static struct platform_driver dfmcs320_driver = { .owner = THIS_MODULE, }, .probe = dfbmcs320_probe, - .remove = __devexit_p(dfbmcs320_remove), + .remove = dfbmcs320_remove, }; module_platform_driver(dfmcs320_driver); diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c index 3e929f079a1..66967ba6f75 100644 --- a/sound/soc/codecs/dmic.c +++ b/sound/soc/codecs/dmic.c @@ -66,13 +66,13 @@ static struct snd_soc_codec_driver soc_dmic = { .probe = dmic_probe, }; -static int __devinit dmic_dev_probe(struct platform_device *pdev) +static int dmic_dev_probe(struct platform_device *pdev) { return snd_soc_register_codec(&pdev->dev, &soc_dmic, &dmic_dai, 1); } -static int __devexit dmic_dev_remove(struct platform_device *pdev) +static int dmic_dev_remove(struct platform_device *pdev) { snd_soc_unregister_codec(&pdev->dev); return 0; @@ -86,7 +86,7 @@ static struct platform_driver dmic_driver = { .owner = THIS_MODULE, }, .probe = dmic_dev_probe, - .remove = __devexit_p(dmic_dev_remove), + .remove = dmic_dev_remove, }; module_platform_driver(dmic_driver); diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c index 1bf55602c9e..53b455b8c07 100644 --- a/sound/soc/codecs/isabelle.c +++ b/sound/soc/codecs/isabelle.c @@ -1119,8 +1119,8 @@ static const struct regmap_config isabelle_regmap_config = { .cache_type = REGCACHE_RBTREE, }; -static int __devinit isabelle_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int isabelle_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct regmap *isabelle_regmap; int ret = 0; @@ -1145,7 +1145,7 @@ static int __devinit isabelle_i2c_probe(struct i2c_client *i2c, return ret; } -static int __devexit isabelle_i2c_remove(struct i2c_client *client) +static int isabelle_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -1163,7 +1163,7 @@ static struct i2c_driver isabelle_i2c_driver = { .owner = THIS_MODULE, }, .probe = isabelle_i2c_probe, - .remove = __devexit_p(isabelle_i2c_remove), + .remove = isabelle_i2c_remove, .id_table = isabelle_i2c_id, }; diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c index 85d9cabe6d5..d991529e1af 100644 --- a/sound/soc/codecs/jz4740.c +++ b/sound/soc/codecs/jz4740.c @@ -16,6 +16,7 @@ #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/io.h> +#include <linux/regmap.h> #include <linux/delay.h> @@ -24,9 +25,10 @@ #include <sound/pcm_params.h> #include <sound/initval.h> #include <sound/soc.h> +#include <sound/tlv.h> #define JZ4740_REG_CODEC_1 0x0 -#define JZ4740_REG_CODEC_2 0x1 +#define JZ4740_REG_CODEC_2 0x4 #define JZ4740_CODEC_1_LINE_ENABLE BIT(29) #define JZ4740_CODEC_1_MIC_ENABLE BIT(28) @@ -67,43 +69,36 @@ #define JZ4740_CODEC_2_MIC_BOOST_GAIN_OFFSET 4 #define JZ4740_CODEC_2_HEADPHONE_VOLUME_OFFSET 0 -static const uint32_t jz4740_codec_regs[] = { - 0x021b2302, 0x00170803, +static const struct reg_default jz4740_codec_reg_defaults[] = { + { JZ4740_REG_CODEC_1, 0x021b2302 }, + { JZ4740_REG_CODEC_2, 0x00170803 }, }; struct jz4740_codec { - void __iomem *base; - struct resource *mem; + struct regmap *regmap; }; -static unsigned int jz4740_codec_read(struct snd_soc_codec *codec, - unsigned int reg) -{ - struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec); - return readl(jz4740_codec->base + (reg << 2)); -} - -static int jz4740_codec_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int val) -{ - struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec); - u32 *cache = codec->reg_cache; - - cache[reg] = val; - writel(val, jz4740_codec->base + (reg << 2)); +static const unsigned int jz4740_mic_tlv[] = { + TLV_DB_RANGE_HEAD(2), + 0, 2, TLV_DB_SCALE_ITEM(0, 600, 0), + 3, 3, TLV_DB_SCALE_ITEM(2000, 0, 0), +}; - return 0; -} +static const DECLARE_TLV_DB_SCALE(jz4740_out_tlv, 0, 200, 0); +static const DECLARE_TLV_DB_SCALE(jz4740_in_tlv, -3450, 150, 0); static const struct snd_kcontrol_new jz4740_codec_controls[] = { - SOC_SINGLE("Master Playback Volume", JZ4740_REG_CODEC_2, - JZ4740_CODEC_2_HEADPHONE_VOLUME_OFFSET, 3, 0), - SOC_SINGLE("Master Capture Volume", JZ4740_REG_CODEC_2, - JZ4740_CODEC_2_INPUT_VOLUME_OFFSET, 31, 0), + SOC_SINGLE_TLV("Master Playback Volume", JZ4740_REG_CODEC_2, + JZ4740_CODEC_2_HEADPHONE_VOLUME_OFFSET, 3, 0, + jz4740_out_tlv), + SOC_SINGLE_TLV("Master Capture Volume", JZ4740_REG_CODEC_2, + JZ4740_CODEC_2_INPUT_VOLUME_OFFSET, 31, 0, + jz4740_in_tlv), SOC_SINGLE("Master Playback Switch", JZ4740_REG_CODEC_1, JZ4740_CODEC_1_HEADPHONE_DISABLE_OFFSET, 1, 1), - SOC_SINGLE("Mic Capture Volume", JZ4740_REG_CODEC_2, - JZ4740_CODEC_2_MIC_BOOST_GAIN_OFFSET, 3, 0), + SOC_SINGLE_TLV("Mic Capture Volume", JZ4740_REG_CODEC_2, + JZ4740_CODEC_2_MIC_BOOST_GAIN_OFFSET, 3, 0, + jz4740_mic_tlv), }; 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[] = { static int jz4740_codec_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { + struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(dai->codec); uint32_t val; - struct snd_soc_codec *codec = dai->codec; switch (params_rate(params)) { case 8000: @@ -200,7 +195,7 @@ static int jz4740_codec_hw_params(struct snd_pcm_substream *substream, val <<= JZ4740_CODEC_2_SAMPLE_RATE_OFFSET; - snd_soc_update_bits(codec, JZ4740_REG_CODEC_2, + regmap_update_bits(jz4740_codec->regmap, JZ4740_REG_CODEC_2, JZ4740_CODEC_2_SAMPLE_RATE_MASK, val); return 0; @@ -230,25 +225,23 @@ static struct snd_soc_dai_driver jz4740_codec_dai = { .symmetric_rates = 1, }; -static void jz4740_codec_wakeup(struct snd_soc_codec *codec) +static void jz4740_codec_wakeup(struct regmap *regmap) { - int i; - uint32_t *cache = codec->reg_cache; - - snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, + regmap_update_bits(regmap, JZ4740_REG_CODEC_1, JZ4740_CODEC_1_RESET, JZ4740_CODEC_1_RESET); udelay(2); - snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, + regmap_update_bits(regmap, JZ4740_REG_CODEC_1, JZ4740_CODEC_1_SUSPEND | JZ4740_CODEC_1_RESET, 0); - for (i = 0; i < ARRAY_SIZE(jz4740_codec_regs); ++i) - jz4740_codec_write(codec, i, cache[i]); + regcache_sync(regmap); } static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { + struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec); + struct regmap *regmap = jz4740_codec->regmap; unsigned int mask; unsigned int value; @@ -261,12 +254,12 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec, JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M; value = 0; - snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, mask, value); + regmap_update_bits(regmap, JZ4740_REG_CODEC_1, mask, value); break; case SND_SOC_BIAS_STANDBY: /* The only way to clear the suspend flag is to reset the codec */ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) - jz4740_codec_wakeup(codec); + jz4740_codec_wakeup(regmap); mask = JZ4740_CODEC_1_VREF_DISABLE | JZ4740_CODEC_1_VREF_AMP_DISABLE | @@ -275,13 +268,14 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec, JZ4740_CODEC_1_VREF_AMP_DISABLE | JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M; - snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, mask, value); + regmap_update_bits(regmap, JZ4740_REG_CODEC_1, mask, value); break; case SND_SOC_BIAS_OFF: mask = JZ4740_CODEC_1_SUSPEND; value = JZ4740_CODEC_1_SUSPEND; - snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, mask, value); + regmap_update_bits(regmap, JZ4740_REG_CODEC_1, mask, value); + regcache_mark_dirty(regmap); break; default: break; @@ -294,7 +288,9 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec, static int jz4740_codec_dev_probe(struct snd_soc_codec *codec) { - snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, + struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec); + + regmap_update_bits(jz4740_codec->regmap, JZ4740_REG_CODEC_1, JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE); 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 = { .remove = jz4740_codec_dev_remove, .suspend = jz4740_codec_suspend, .resume = jz4740_codec_resume, - .read = jz4740_codec_read, - .write = jz4740_codec_write, .set_bias_level = jz4740_codec_set_bias_level, - .reg_cache_default = jz4740_codec_regs, - .reg_word_size = sizeof(u32), - .reg_cache_size = 2, .controls = jz4740_codec_controls, .num_controls = ARRAY_SIZE(jz4740_codec_controls), @@ -346,11 +337,23 @@ static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = { .num_dapm_routes = ARRAY_SIZE(jz4740_codec_dapm_routes), }; -static int __devinit jz4740_codec_probe(struct platform_device *pdev) +static const struct regmap_config jz4740_codec_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = JZ4740_REG_CODEC_2, + + .reg_defaults = jz4740_codec_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(jz4740_codec_reg_defaults), + .cache_type = REGCACHE_RBTREE, +}; + +static int jz4740_codec_probe(struct platform_device *pdev) { int ret; struct jz4740_codec *jz4740_codec; struct resource *mem; + void __iomem *base; jz4740_codec = devm_kzalloc(&pdev->dev, sizeof(*jz4740_codec), GFP_KERNEL); @@ -358,56 +361,29 @@ static int __devinit jz4740_codec_probe(struct platform_device *pdev) return -ENOMEM; mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem) { - dev_err(&pdev->dev, "Failed to get mmio memory resource\n"); - ret = -ENOENT; - goto err_out; - } - - mem = request_mem_region(mem->start, resource_size(mem), pdev->name); - if (!mem) { - dev_err(&pdev->dev, "Failed to request mmio memory region\n"); - ret = -EBUSY; - goto err_out; - } + base = devm_request_and_ioremap(&pdev->dev, mem); + if (!base) + return -EBUSY; - jz4740_codec->base = ioremap(mem->start, resource_size(mem)); - if (!jz4740_codec->base) { - dev_err(&pdev->dev, "Failed to ioremap mmio memory\n"); - ret = -EBUSY; - goto err_release_mem_region; - } - jz4740_codec->mem = mem; + jz4740_codec->regmap = devm_regmap_init_mmio(&pdev->dev, base, + &jz4740_codec_regmap_config); + if (IS_ERR(jz4740_codec->regmap)) + return PTR_ERR(jz4740_codec->regmap); platform_set_drvdata(pdev, jz4740_codec); ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_jz4740_codec, &jz4740_codec_dai, 1); - if (ret) { + if (ret) dev_err(&pdev->dev, "Failed to register codec\n"); - goto err_iounmap; - } - return 0; - -err_iounmap: - iounmap(jz4740_codec->base); -err_release_mem_region: - release_mem_region(mem->start, resource_size(mem)); -err_out: return ret; } -static int __devexit jz4740_codec_remove(struct platform_device *pdev) +static int jz4740_codec_remove(struct platform_device *pdev) { - struct jz4740_codec *jz4740_codec = platform_get_drvdata(pdev); - struct resource *mem = jz4740_codec->mem; - snd_soc_unregister_codec(&pdev->dev); - iounmap(jz4740_codec->base); - release_mem_region(mem->start, resource_size(mem)); - platform_set_drvdata(pdev, NULL); return 0; @@ -415,7 +391,7 @@ static int __devexit jz4740_codec_remove(struct platform_device *pdev) static struct platform_driver jz4740_codec_driver = { .probe = jz4740_codec_probe, - .remove = __devexit_p(jz4740_codec_remove), + .remove = jz4740_codec_remove, .driver = { .name = "jz4740-codec", .owner = THIS_MODULE, diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c index 81a328c7883..9f9f59573f7 100644 --- a/sound/soc/codecs/lm4857.c +++ b/sound/soc/codecs/lm4857.c @@ -209,8 +209,8 @@ static struct snd_soc_codec_driver soc_codec_dev_lm4857 = { .set_bias_level = lm4857_set_bias_level, }; -static int __devinit lm4857_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int lm4857_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct lm4857 *lm4857; int ret; @@ -228,7 +228,7 @@ static int __devinit lm4857_i2c_probe(struct i2c_client *i2c, return ret; } -static int __devexit lm4857_i2c_remove(struct i2c_client *i2c) +static int lm4857_i2c_remove(struct i2c_client *i2c) { snd_soc_unregister_codec(&i2c->dev); return 0; @@ -246,7 +246,7 @@ static struct i2c_driver lm4857_i2c_driver = { .owner = THIS_MODULE, }, .probe = lm4857_i2c_probe, - .remove = __devexit_p(lm4857_i2c_remove), + .remove = lm4857_i2c_remove, .id_table = lm4857_i2c_id, }; diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c index 99b0a9dcff3..d75257d40a4 100644 --- a/sound/soc/codecs/lm49453.c +++ b/sound/soc/codecs/lm49453.c @@ -1483,8 +1483,8 @@ static const struct regmap_config lm49453_regmap_config = { .cache_type = REGCACHE_RBTREE, }; -static __devinit int lm49453_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int lm49453_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct lm49453_priv *lm49453; int ret = 0; @@ -1497,7 +1497,7 @@ static __devinit int lm49453_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, lm49453); - lm49453->regmap = regmap_init_i2c(i2c, &lm49453_regmap_config); + lm49453->regmap = devm_regmap_init_i2c(i2c, &lm49453_regmap_config); if (IS_ERR(lm49453->regmap)) { ret = PTR_ERR(lm49453->regmap); 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, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_lm49453, lm49453_dai, ARRAY_SIZE(lm49453_dai)); - if (ret < 0) { + if (ret < 0) dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); - regmap_exit(lm49453->regmap); - return ret; - } return ret; } -static int __devexit lm49453_i2c_remove(struct i2c_client *client) +static int lm49453_i2c_remove(struct i2c_client *client) { - struct lm49453_priv *lm49453 = i2c_get_clientdata(client); - snd_soc_unregister_codec(&client->dev); - regmap_exit(lm49453->regmap); return 0; } @@ -1538,7 +1532,7 @@ static struct i2c_driver lm49453_i2c_driver = { .owner = THIS_MODULE, }, .probe = lm49453_i2c_probe, - .remove = __devexit_p(lm49453_i2c_remove), + .remove = lm49453_i2c_remove, .id_table = lm49453_i2c_id, }; diff --git a/sound/soc/codecs/max9768.c b/sound/soc/codecs/max9768.c index 17b3ec2d05c..a6ac2313047 100644 --- a/sound/soc/codecs/max9768.c +++ b/sound/soc/codecs/max9768.c @@ -159,8 +159,8 @@ static const struct regmap_config max9768_i2c_regmap_config = { .cache_type = REGCACHE_RBTREE, }; -static int __devinit max9768_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int max9768_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) { struct max9768 *max9768; struct max9768_pdata *pdata = client->dev.platform_data; @@ -187,7 +187,7 @@ static int __devinit max9768_i2c_probe(struct i2c_client *client, i2c_set_clientdata(client, max9768); - max9768->regmap = regmap_init_i2c(client, &max9768_i2c_regmap_config); + max9768->regmap = devm_regmap_init_i2c(client, &max9768_i2c_regmap_config); if (IS_ERR(max9768->regmap)) { err = PTR_ERR(max9768->regmap); goto err_gpio_free; @@ -195,12 +195,10 @@ static int __devinit max9768_i2c_probe(struct i2c_client *client, err = snd_soc_register_codec(&client->dev, &max9768_codec_driver, NULL, 0); if (err) - goto err_regmap_free; + goto err_gpio_free; return 0; - err_regmap_free: - regmap_exit(max9768->regmap); err_gpio_free: if (gpio_is_valid(max9768->shdn_gpio)) gpio_free(max9768->shdn_gpio); @@ -210,12 +208,11 @@ static int __devinit max9768_i2c_probe(struct i2c_client *client, return err; } -static int __devexit max9768_i2c_remove(struct i2c_client *client) +static int max9768_i2c_remove(struct i2c_client *client) { struct max9768 *max9768 = i2c_get_clientdata(client); snd_soc_unregister_codec(&client->dev); - regmap_exit(max9768->regmap); if (gpio_is_valid(max9768->shdn_gpio)) gpio_free(max9768->shdn_gpio); @@ -237,7 +234,7 @@ static struct i2c_driver max9768_i2c_driver = { .owner = THIS_MODULE, }, .probe = max9768_i2c_probe, - .remove = __devexit_p(max9768_i2c_remove), + .remove = max9768_i2c_remove, .id_table = max9768_i2c_id, }; module_i2c_driver(max9768_i2c_driver); diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index 3264a516930..a4c16fd70f7 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c @@ -2084,7 +2084,7 @@ static int max98088_i2c_probe(struct i2c_client *i2c, return ret; } -static int __devexit max98088_i2c_remove(struct i2c_client *client) +static int max98088_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -2098,13 +2098,13 @@ static const struct i2c_device_id max98088_i2c_id[] = { MODULE_DEVICE_TABLE(i2c, max98088_i2c_id); static struct i2c_driver max98088_i2c_driver = { - .driver = { - .name = "max98088", - .owner = THIS_MODULE, - }, - .probe = max98088_i2c_probe, - .remove = __devexit_p(max98088_i2c_remove), - .id_table = max98088_i2c_id, + .driver = { + .name = "max98088", + .owner = THIS_MODULE, + }, + .probe = max98088_i2c_probe, + .remove = max98088_i2c_remove, + .id_table = max98088_i2c_id, }; 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 00000000000..c9772ca3da4 --- /dev/null +++ b/sound/soc/codecs/max98090.c @@ -0,0 +1,577 @@ +/* + * max98090.c -- MAX98090 ALSA SoC Audio driver + * based on Rev0p8 datasheet + * + * Copyright (C) 2012 Renesas Solutions Corp. + * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> + * + * Based on + * + * max98095.c + * Copyright 2011 Maxim Integrated Products + * + * https://github.com/hardkernel/linux/commit/\ + * 3417d7166b17113b3b33b0a337c74d1c7cc313df#sound/soc/codecs/max98090.c + * Copyright 2011 Maxim Integrated Products + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/i2c.h> +#include <linux/module.h> +#include <linux/regmap.h> +#include <sound/soc.h> +#include <sound/tlv.h> + +/* + * + * MAX98090 Registers Definition + * + */ + +/* RESET / STATUS / INTERRUPT REGISTERS */ +#define MAX98090_0x00_SW_RESET 0x00 +#define MAX98090_0x01_INT_STS 0x01 +#define MAX98090_0x02_JACK_STS 0x02 +#define MAX98090_0x03_INT_MASK 0x03 + +/* QUICK SETUP REGISTERS */ +#define MAX98090_0x04_SYS_CLK 0x04 +#define MAX98090_0x05_SAMPLE_RATE 0x05 +#define MAX98090_0x06_DAI_IF 0x06 +#define MAX98090_0x07_DAC_PATH 0x07 +#define MAX98090_0x08_MIC_TO_ADC 0x08 +#define MAX98090_0x09_LINE_TO_ADC 0x09 +#define MAX98090_0x0A_ANALOG_MIC_LOOP 0x0A +#define MAX98090_0x0B_ANALOG_LINE_LOOP 0x0B + +/* ANALOG INPUT CONFIGURATION REGISTERS */ +#define MAX98090_0x0D_INPUT_CONFIG 0x0D +#define MAX98090_0x0E_LINE_IN_LVL 0x0E +#define MAX98090_0x0F_LINI_IN_CFG 0x0F +#define MAX98090_0x10_MIC1_IN_LVL 0x10 +#define MAX98090_0x11_MIC2_IN_LVL 0x11 + +/* MICROPHONE CONFIGURATION REGISTERS */ +#define MAX98090_0x12_MIC_BIAS_VOL 0x12 +#define MAX98090_0x13_DIGITAL_MIC_CFG 0x13 +#define MAX98090_0x14_DIGITAL_MIC_MODE 0x14 + +/* ADC PATH AND CONFIGURATION REGISTERS */ +#define MAX98090_0x15_L_ADC_MIX 0x15 +#define MAX98090_0x16_R_ADC_MIX 0x16 +#define MAX98090_0x17_L_ADC_LVL 0x17 +#define MAX98090_0x18_R_ADC_LVL 0x18 +#define MAX98090_0x19_ADC_BIQUAD_LVL 0x19 +#define MAX98090_0x1A_ADC_SIDETONE 0x1A + +/* CLOCK CONFIGURATION REGISTERS */ +#define MAX98090_0x1B_SYS_CLK 0x1B +#define MAX98090_0x1C_CLK_MODE 0x1C +#define MAX98090_0x1D_ANY_CLK1 0x1D +#define MAX98090_0x1E_ANY_CLK2 0x1E +#define MAX98090_0x1F_ANY_CLK3 0x1F +#define MAX98090_0x20_ANY_CLK4 0x20 +#define MAX98090_0x21_MASTER_MODE 0x21 + +/* INTERFACE CONTROL REGISTERS */ +#define MAX98090_0x22_DAI_IF_FMT 0x22 +#define MAX98090_0x23_DAI_TDM_FMT1 0x23 +#define MAX98090_0x24_DAI_TDM_FMT2 0x24 +#define MAX98090_0x25_DAI_IO_CFG 0x25 +#define MAX98090_0x26_FILTER_CFG 0x26 +#define MAX98090_0x27_DAI_PLAYBACK_LVL 0x27 +#define MAX98090_0x28_EQ_PLAYBACK_LVL 0x28 + +/* HEADPHONE CONTROL REGISTERS */ +#define MAX98090_0x29_L_HP_MIX 0x29 +#define MAX98090_0x2A_R_HP_MIX 0x2A +#define MAX98090_0x2B_HP_CTR 0x2B +#define MAX98090_0x2C_L_HP_VOL 0x2C +#define MAX98090_0x2D_R_HP_VOL 0x2D + +/* SPEAKER CONFIGURATION REGISTERS */ +#define MAX98090_0x2E_L_SPK_MIX 0x2E +#define MAX98090_0x2F_R_SPK_MIX 0x2F +#define MAX98090_0x30_SPK_CTR 0x30 +#define MAX98090_0x31_L_SPK_VOL 0x31 +#define MAX98090_0x32_R_SPK_VOL 0x32 + +/* ALC CONFIGURATION REGISTERS */ +#define MAX98090_0x33_ALC_TIMING 0x33 +#define MAX98090_0x34_ALC_COMPRESSOR 0x34 +#define MAX98090_0x35_ALC_EXPANDER 0x35 +#define MAX98090_0x36_ALC_GAIN 0x36 + +/* RECEIVER AND LINE_OUTPUT REGISTERS */ +#define MAX98090_0x37_RCV_LOUT_L_MIX 0x37 +#define MAX98090_0x38_RCV_LOUT_L_CNTL 0x38 +#define MAX98090_0x39_RCV_LOUT_L_VOL 0x39 +#define MAX98090_0x3A_LOUT_R_MIX 0x3A +#define MAX98090_0x3B_LOUT_R_CNTL 0x3B +#define MAX98090_0x3C_LOUT_R_VOL 0x3C + +/* JACK DETECT AND ENABLE REGISTERS */ +#define MAX98090_0x3D_JACK_DETECT 0x3D +#define MAX98090_0x3E_IN_ENABLE 0x3E +#define MAX98090_0x3F_OUT_ENABLE 0x3F +#define MAX98090_0x40_LVL_CTR 0x40 +#define MAX98090_0x41_DSP_FILTER_ENABLE 0x41 + +/* BIAS AND POWER MODE CONFIGURATION REGISTERS */ +#define MAX98090_0x42_BIAS_CTR 0x42 +#define MAX98090_0x43_DAC_CTR 0x43 +#define MAX98090_0x44_ADC_CTR 0x44 +#define MAX98090_0x45_DEV_SHUTDOWN 0x45 + +/* REVISION ID REGISTER */ +#define MAX98090_0xFF_REV_ID 0xFF + +#define MAX98090_REG_MAX_CACHED 0x45 +#define MAX98090_REG_END 0xFF + +/* + * + * MAX98090 Registers Bit Fields + * + */ + +/* MAX98090_0x06_DAI_IF */ +#define MAX98090_DAI_IF_MASK 0x3F +#define MAX98090_RJ_M (1 << 5) +#define MAX98090_RJ_S (1 << 4) +#define MAX98090_LJ_M (1 << 3) +#define MAX98090_LJ_S (1 << 2) +#define MAX98090_I2S_M (1 << 1) +#define MAX98090_I2S_S (1 << 0) + +/* MAX98090_0x45_DEV_SHUTDOWN */ +#define MAX98090_SHDNRUN (1 << 7) + +/* codec private data */ +struct max98090_priv { + struct regmap *regmap; +}; + +static const struct reg_default max98090_reg_defaults[] = { + /* RESET / STATUS / INTERRUPT REGISTERS */ + {MAX98090_0x00_SW_RESET, 0x00}, + {MAX98090_0x01_INT_STS, 0x00}, + {MAX98090_0x02_JACK_STS, 0x00}, + {MAX98090_0x03_INT_MASK, 0x04}, + + /* QUICK SETUP REGISTERS */ + {MAX98090_0x04_SYS_CLK, 0x00}, + {MAX98090_0x05_SAMPLE_RATE, 0x00}, + {MAX98090_0x06_DAI_IF, 0x00}, + {MAX98090_0x07_DAC_PATH, 0x00}, + {MAX98090_0x08_MIC_TO_ADC, 0x00}, + {MAX98090_0x09_LINE_TO_ADC, 0x00}, + {MAX98090_0x0A_ANALOG_MIC_LOOP, 0x00}, + {MAX98090_0x0B_ANALOG_LINE_LOOP, 0x00}, + + /* ANALOG INPUT CONFIGURATION REGISTERS */ + {MAX98090_0x0D_INPUT_CONFIG, 0x00}, + {MAX98090_0x0E_LINE_IN_LVL, 0x1B}, + {MAX98090_0x0F_LINI_IN_CFG, 0x00}, + {MAX98090_0x10_MIC1_IN_LVL, 0x11}, + {MAX98090_0x11_MIC2_IN_LVL, 0x11}, + + /* MICROPHONE CONFIGURATION REGISTERS */ + {MAX98090_0x12_MIC_BIAS_VOL, 0x00}, + {MAX98090_0x13_DIGITAL_MIC_CFG, 0x00}, + {MAX98090_0x14_DIGITAL_MIC_MODE, 0x00}, + + /* ADC PATH AND CONFIGURATION REGISTERS */ + {MAX98090_0x15_L_ADC_MIX, 0x00}, + {MAX98090_0x16_R_ADC_MIX, 0x00}, + {MAX98090_0x17_L_ADC_LVL, 0x03}, + {MAX98090_0x18_R_ADC_LVL, 0x03}, + {MAX98090_0x19_ADC_BIQUAD_LVL, 0x00}, + {MAX98090_0x1A_ADC_SIDETONE, 0x00}, + + /* CLOCK CONFIGURATION REGISTERS */ + {MAX98090_0x1B_SYS_CLK, 0x00}, + {MAX98090_0x1C_CLK_MODE, 0x00}, + {MAX98090_0x1D_ANY_CLK1, 0x00}, + {MAX98090_0x1E_ANY_CLK2, 0x00}, + {MAX98090_0x1F_ANY_CLK3, 0x00}, + {MAX98090_0x20_ANY_CLK4, 0x00}, + {MAX98090_0x21_MASTER_MODE, 0x00}, + + /* INTERFACE CONTROL REGISTERS */ + {MAX98090_0x22_DAI_IF_FMT, 0x00}, + {MAX98090_0x23_DAI_TDM_FMT1, 0x00}, + {MAX98090_0x24_DAI_TDM_FMT2, 0x00}, + {MAX98090_0x25_DAI_IO_CFG, 0x00}, + {MAX98090_0x26_FILTER_CFG, 0x80}, + {MAX98090_0x27_DAI_PLAYBACK_LVL, 0x00}, + {MAX98090_0x28_EQ_PLAYBACK_LVL, 0x00}, + + /* HEADPHONE CONTROL REGISTERS */ + {MAX98090_0x29_L_HP_MIX, 0x00}, + {MAX98090_0x2A_R_HP_MIX, 0x00}, + {MAX98090_0x2B_HP_CTR, 0x00}, + {MAX98090_0x2C_L_HP_VOL, 0x1A}, + {MAX98090_0x2D_R_HP_VOL, 0x1A}, + + /* SPEAKER CONFIGURATION REGISTERS */ + {MAX98090_0x2E_L_SPK_MIX, 0x00}, + {MAX98090_0x2F_R_SPK_MIX, 0x00}, + {MAX98090_0x30_SPK_CTR, 0x00}, + {MAX98090_0x31_L_SPK_VOL, 0x2C}, + {MAX98090_0x32_R_SPK_VOL, 0x2C}, + + /* ALC CONFIGURATION REGISTERS */ + {MAX98090_0x33_ALC_TIMING, 0x00}, + {MAX98090_0x34_ALC_COMPRESSOR, 0x00}, + {MAX98090_0x35_ALC_EXPANDER, 0x00}, + {MAX98090_0x36_ALC_GAIN, 0x00}, + + /* RECEIVER AND LINE_OUTPUT REGISTERS */ + {MAX98090_0x37_RCV_LOUT_L_MIX, 0x00}, + {MAX98090_0x38_RCV_LOUT_L_CNTL, 0x00}, + {MAX98090_0x39_RCV_LOUT_L_VOL, 0x15}, + {MAX98090_0x3A_LOUT_R_MIX, 0x00}, + {MAX98090_0x3B_LOUT_R_CNTL, 0x00}, + {MAX98090_0x3C_LOUT_R_VOL, 0x15}, + + /* JACK DETECT AND ENABLE REGISTERS */ + {MAX98090_0x3D_JACK_DETECT, 0x00}, + {MAX98090_0x3E_IN_ENABLE, 0x00}, + {MAX98090_0x3F_OUT_ENABLE, 0x00}, + {MAX98090_0x40_LVL_CTR, 0x00}, + {MAX98090_0x41_DSP_FILTER_ENABLE, 0x00}, + + /* BIAS AND POWER MODE CONFIGURATION REGISTERS */ + {MAX98090_0x42_BIAS_CTR, 0x00}, + {MAX98090_0x43_DAC_CTR, 0x00}, + {MAX98090_0x44_ADC_CTR, 0x06}, + {MAX98090_0x45_DEV_SHUTDOWN, 0x00}, +}; + +static const unsigned int max98090_hp_tlv[] = { + TLV_DB_RANGE_HEAD(5), + 0x0, 0x6, TLV_DB_SCALE_ITEM(-6700, 400, 0), + 0x7, 0xE, TLV_DB_SCALE_ITEM(-4000, 300, 0), + 0xF, 0x15, TLV_DB_SCALE_ITEM(-1700, 200, 0), + 0x16, 0x1B, TLV_DB_SCALE_ITEM(-400, 100, 0), + 0x1C, 0x1F, TLV_DB_SCALE_ITEM(150, 50, 0), +}; + +static struct snd_kcontrol_new max98090_snd_controls[] = { + SOC_DOUBLE_R_TLV("Headphone Volume", MAX98090_0x2C_L_HP_VOL, + MAX98090_0x2D_R_HP_VOL, 0, 31, 0, max98090_hp_tlv), +}; + +/* Left HeadPhone Mixer Switch */ +static struct snd_kcontrol_new max98090_left_hp_mixer_controls[] = { + SOC_DAPM_SINGLE("DACR Switch", MAX98090_0x29_L_HP_MIX, 1, 1, 0), + SOC_DAPM_SINGLE("DACL Switch", MAX98090_0x29_L_HP_MIX, 0, 1, 0), +}; + +/* Right HeadPhone Mixer Switch */ +static struct snd_kcontrol_new max98090_right_hp_mixer_controls[] = { + SOC_DAPM_SINGLE("DACR Switch", MAX98090_0x2A_R_HP_MIX, 1, 1, 0), + SOC_DAPM_SINGLE("DACL Switch", MAX98090_0x2A_R_HP_MIX, 0, 1, 0), +}; + +static struct snd_soc_dapm_widget max98090_dapm_widgets[] = { + /* Output */ + SND_SOC_DAPM_OUTPUT("HPL"), + SND_SOC_DAPM_OUTPUT("HPR"), + + /* PGA */ + SND_SOC_DAPM_PGA("HPL Out", MAX98090_0x3F_OUT_ENABLE, 7, 0, NULL, 0), + SND_SOC_DAPM_PGA("HPR Out", MAX98090_0x3F_OUT_ENABLE, 6, 0, NULL, 0), + + /* Mixer */ + SND_SOC_DAPM_MIXER("HPL Mixer", SND_SOC_NOPM, 0, 0, + max98090_left_hp_mixer_controls, + ARRAY_SIZE(max98090_left_hp_mixer_controls)), + + SND_SOC_DAPM_MIXER("HPR Mixer", SND_SOC_NOPM, 0, 0, + max98090_right_hp_mixer_controls, + ARRAY_SIZE(max98090_right_hp_mixer_controls)), + + /* DAC */ + SND_SOC_DAPM_DAC("DACL", "Hifi Playback", MAX98090_0x3F_OUT_ENABLE, 0, 0), + SND_SOC_DAPM_DAC("DACR", "Hifi Playback", MAX98090_0x3F_OUT_ENABLE, 1, 0), +}; + +static struct snd_soc_dapm_route max98090_audio_map[] = { + /* Output */ + {"HPL", NULL, "HPL Out"}, + {"HPR", NULL, "HPR Out"}, + + /* PGA */ + {"HPL Out", NULL, "HPL Mixer"}, + {"HPR Out", NULL, "HPR Mixer"}, + + /* Mixer*/ + {"HPL Mixer", "DACR Switch", "DACR"}, + {"HPL Mixer", "DACL Switch", "DACL"}, + + {"HPR Mixer", "DACR Switch", "DACR"}, + {"HPR Mixer", "DACL Switch", "DACL"}, +}; + +static bool max98090_volatile(struct device *dev, unsigned int reg) +{ + if ((reg == MAX98090_0x01_INT_STS) || + (reg == MAX98090_0x02_JACK_STS) || + (reg > MAX98090_REG_MAX_CACHED)) + return true; + + return false; +} + +static int max98090_dai_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + unsigned int val; + + switch (params_rate(params)) { + case 96000: + val = 1 << 5; + break; + case 32000: + val = 1 << 4; + break; + case 48000: + val = 1 << 3; + break; + case 44100: + val = 1 << 2; + break; + case 16000: + val = 1 << 1; + break; + case 8000: + val = 1 << 0; + break; + default: + dev_err(codec->dev, "unsupported rate\n"); + return -EINVAL; + } + snd_soc_update_bits(codec, MAX98090_0x05_SAMPLE_RATE, 0x03F, val); + + return 0; +} + +static int max98090_dai_set_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = dai->codec; + unsigned int val; + + snd_soc_update_bits(codec, MAX98090_0x45_DEV_SHUTDOWN, + MAX98090_SHDNRUN, 0); + + switch (freq) { + case 26000000: + val = 1 << 7; + break; + case 19200000: + val = 1 << 6; + break; + case 13000000: + val = 1 << 5; + break; + case 12288000: + val = 1 << 4; + break; + case 12000000: + val = 1 << 3; + break; + case 11289600: + val = 1 << 2; + break; + default: + dev_err(codec->dev, "Invalid master clock frequency\n"); + return -EINVAL; + } + snd_soc_update_bits(codec, MAX98090_0x04_SYS_CLK, 0xFD, val); + + snd_soc_update_bits(codec, MAX98090_0x45_DEV_SHUTDOWN, + MAX98090_SHDNRUN, MAX98090_SHDNRUN); + + dev_dbg(dai->dev, "sysclk is %uHz\n", freq); + + return 0; +} + +static int max98090_dai_set_fmt(struct snd_soc_dai *dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = dai->codec; + int is_master; + u8 val; + + /* master/slave mode */ + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + is_master = 1; + break; + case SND_SOC_DAIFMT_CBS_CFS: + is_master = 0; + break; + default: + dev_err(codec->dev, "unsupported clock\n"); + return -EINVAL; + } + + /* format */ + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_I2S: + val = (is_master) ? MAX98090_I2S_M : MAX98090_I2S_S; + break; + case SND_SOC_DAIFMT_RIGHT_J: + val = (is_master) ? MAX98090_RJ_M : MAX98090_RJ_S; + break; + case SND_SOC_DAIFMT_LEFT_J: + val = (is_master) ? MAX98090_LJ_M : MAX98090_LJ_S; + break; + default: + dev_err(codec->dev, "unsupported format\n"); + return -EINVAL; + } + snd_soc_update_bits(codec, MAX98090_0x06_DAI_IF, + MAX98090_DAI_IF_MASK, val); + + return 0; +} + +#define MAX98090_RATES SNDRV_PCM_RATE_8000_96000 +#define MAX98090_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) + +static struct snd_soc_dai_ops max98090_dai_ops = { + .set_sysclk = max98090_dai_set_sysclk, + .set_fmt = max98090_dai_set_fmt, + .hw_params = max98090_dai_hw_params, +}; + +static struct snd_soc_dai_driver max98090_dai = { + .name = "max98090-Hifi", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 2, + .rates = MAX98090_RATES, + .formats = MAX98090_FORMATS, + }, + .ops = &max98090_dai_ops, +}; + +static int max98090_probe(struct snd_soc_codec *codec) +{ + struct max98090_priv *priv = snd_soc_codec_get_drvdata(codec); + struct device *dev = codec->dev; + int ret; + + codec->control_data = priv->regmap; + ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); + if (ret < 0) { + dev_err(dev, "Failed to set cache I/O: %d\n", ret); + return ret; + } + + /* Device active */ + snd_soc_update_bits(codec, MAX98090_0x45_DEV_SHUTDOWN, + MAX98090_SHDNRUN, MAX98090_SHDNRUN); + + return 0; +} + +static int max98090_remove(struct snd_soc_codec *codec) +{ + return 0; +} + +static struct snd_soc_codec_driver soc_codec_dev_max98090 = { + .probe = max98090_probe, + .remove = max98090_remove, + .controls = max98090_snd_controls, + .num_controls = ARRAY_SIZE(max98090_snd_controls), + .dapm_widgets = max98090_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(max98090_dapm_widgets), + .dapm_routes = max98090_audio_map, + .num_dapm_routes = ARRAY_SIZE(max98090_audio_map), +}; + +static const struct regmap_config max98090_regmap = { + .reg_bits = 8, + .val_bits = 8, + .max_register = MAX98090_REG_END, + .volatile_reg = max98090_volatile, + .cache_type = REGCACHE_RBTREE, + .reg_defaults = max98090_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(max98090_reg_defaults), +}; + +static int max98090_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct max98090_priv *priv; + struct device *dev = &i2c->dev; + unsigned int val; + int ret; + + priv = devm_kzalloc(dev, sizeof(struct max98090_priv), + GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->regmap = devm_regmap_init_i2c(i2c, &max98090_regmap); + if (IS_ERR(priv->regmap)) { + ret = PTR_ERR(priv->regmap); + dev_err(dev, "Failed to init regmap: %d\n", ret); + return ret; + } + + i2c_set_clientdata(i2c, priv); + + ret = regmap_read(priv->regmap, MAX98090_0xFF_REV_ID, &val); + if (ret < 0) { + dev_err(dev, "Failed to read device revision: %d\n", ret); + return ret; + } + dev_info(dev, "revision 0x%02x\n", val); + + ret = snd_soc_register_codec(dev, + &soc_codec_dev_max98090, + &max98090_dai, 1); + + return ret; +} + +static int max98090_i2c_remove(struct i2c_client *client) +{ + snd_soc_unregister_codec(&client->dev); + return 0; +} + +static const struct i2c_device_id max98090_i2c_id[] = { + { "max98090", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, max98090_i2c_id); + +static struct i2c_driver max98090_i2c_driver = { + .driver = { + .name = "max98090", + .owner = THIS_MODULE, + }, + .probe = max98090_i2c_probe, + .remove = max98090_i2c_remove, + .id_table = max98090_i2c_id, +}; +module_i2c_driver(max98090_i2c_driver); + +MODULE_DESCRIPTION("ALSA SoC MAX98090 driver"); +MODULE_AUTHOR("Peter Hsiang, Kuninori Morimoto"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index 38d43c59d3f..41cdd164297 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c @@ -2511,7 +2511,7 @@ static int max98095_i2c_probe(struct i2c_client *i2c, return ret; } -static int __devexit max98095_i2c_remove(struct i2c_client *client) +static int max98095_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -2529,7 +2529,7 @@ static struct i2c_driver max98095_i2c_driver = { .owner = THIS_MODULE, }, .probe = max98095_i2c_probe, - .remove = __devexit_p(max98095_i2c_remove), + .remove = max98095_i2c_remove, .id_table = max98095_i2c_id, }; diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c index efe535c37b3..58c38a5b481 100644 --- a/sound/soc/codecs/max9850.c +++ b/sound/soc/codecs/max9850.c @@ -329,8 +329,8 @@ static struct snd_soc_codec_driver soc_codec_dev_max9850 = { .num_dapm_routes = ARRAY_SIZE(max9850_dapm_routes), }; -static int __devinit max9850_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int max9850_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct max9850_priv *max9850; int ret; @@ -347,7 +347,7 @@ static int __devinit max9850_i2c_probe(struct i2c_client *i2c, return ret; } -static __devexit int max9850_i2c_remove(struct i2c_client *client) +static int max9850_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -365,7 +365,7 @@ static struct i2c_driver max9850_i2c_driver = { .owner = THIS_MODULE, }, .probe = max9850_i2c_probe, - .remove = __devexit_p(max9850_i2c_remove), + .remove = max9850_i2c_remove, .id_table = max9850_i2c_id, }; diff --git a/sound/soc/codecs/max9877.c b/sound/soc/codecs/max9877.c index d15e5943c85..6b6c74cd83e 100644 --- a/sound/soc/codecs/max9877.c +++ b/sound/soc/codecs/max9877.c @@ -258,8 +258,8 @@ int max9877_add_controls(struct snd_soc_codec *codec) } EXPORT_SYMBOL_GPL(max9877_add_controls); -static int __devinit max9877_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int max9877_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) { i2c = client; @@ -268,7 +268,7 @@ static int __devinit max9877_i2c_probe(struct i2c_client *client, return 0; } -static __devexit int max9877_i2c_remove(struct i2c_client *client) +static int max9877_i2c_remove(struct i2c_client *client) { i2c = NULL; @@ -287,7 +287,7 @@ static struct i2c_driver max9877_i2c_driver = { .owner = THIS_MODULE, }, .probe = max9877_i2c_probe, - .remove = __devexit_p(max9877_i2c_remove), + .remove = max9877_i2c_remove, .id_table = max9877_i2c_id, }; diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c index bc955999c8a..5402dfbbb71 100644 --- a/sound/soc/codecs/mc13783.c +++ b/sound/soc/codecs/mc13783.c @@ -779,7 +779,7 @@ static struct platform_driver mc13783_codec_driver = { .owner = THIS_MODULE, }, .probe = mc13783_codec_probe, - .remove = __devexit_p(mc13783_codec_remove), + .remove = mc13783_codec_remove, }; module_platform_driver(mc13783_codec_driver); diff --git a/sound/soc/codecs/ml26124.c b/sound/soc/codecs/ml26124.c index 96aa5fa0516..26118828782 100644 --- a/sound/soc/codecs/ml26124.c +++ b/sound/soc/codecs/ml26124.c @@ -626,8 +626,8 @@ static const struct regmap_config ml26124_i2c_regmap = { .write_flag_mask = 0x01, }; -static __devinit int ml26124_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ml26124_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct ml26124_priv *priv; int ret; @@ -649,7 +649,7 @@ static __devinit int ml26124_i2c_probe(struct i2c_client *i2c, &soc_codec_dev_ml26124, &ml26124_dai, 1); } -static __devexit int ml26124_i2c_remove(struct i2c_client *client) +static int ml26124_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -667,7 +667,7 @@ static struct i2c_driver ml26124_i2c_driver = { .owner = THIS_MODULE, }, .probe = ml26124_i2c_probe, - .remove = __devexit_p(ml26124_i2c_remove), + .remove = ml26124_i2c_remove, .id_table = ml26124_i2c_id, }; diff --git a/sound/soc/codecs/omap-hdmi.c b/sound/soc/codecs/omap-hdmi.c index 1bf5c74f5f9..529d06444c5 100644 --- a/sound/soc/codecs/omap-hdmi.c +++ b/sound/soc/codecs/omap-hdmi.c @@ -39,13 +39,13 @@ static struct snd_soc_dai_driver omap_hdmi_codec_dai = { }, }; -static __devinit int omap_hdmi_codec_probe(struct platform_device *pdev) +static int omap_hdmi_codec_probe(struct platform_device *pdev) { return snd_soc_register_codec(&pdev->dev, &omap_hdmi_codec, &omap_hdmi_codec_dai, 1); } -static __devexit int omap_hdmi_codec_remove(struct platform_device *pdev) +static int omap_hdmi_codec_remove(struct platform_device *pdev) { snd_soc_unregister_codec(&pdev->dev); return 0; @@ -58,7 +58,7 @@ static struct platform_driver omap_hdmi_codec_driver = { }, .probe = omap_hdmi_codec_probe, - .remove = __devexit_p(omap_hdmi_codec_remove), + .remove = omap_hdmi_codec_remove, }; module_platform_driver(omap_hdmi_codec_driver); diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c index edcaa7ea548..f2a6282b41f 100644 --- a/sound/soc/codecs/pcm3008.c +++ b/sound/soc/codecs/pcm3008.c @@ -149,13 +149,13 @@ static struct snd_soc_codec_driver soc_codec_dev_pcm3008 = { .resume = pcm3008_soc_resume, }; -static int __devinit pcm3008_codec_probe(struct platform_device *pdev) +static int pcm3008_codec_probe(struct platform_device *pdev) { return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_pcm3008, &pcm3008_dai, 1); } -static int __devexit pcm3008_codec_remove(struct platform_device *pdev) +static int pcm3008_codec_remove(struct platform_device *pdev) { snd_soc_unregister_codec(&pdev->dev); return 0; @@ -165,7 +165,7 @@ MODULE_ALIAS("platform:pcm3008-codec"); static struct platform_driver pcm3008_codec_driver = { .probe = pcm3008_codec_probe, - .remove = __devexit_p(pcm3008_codec_remove), + .remove = pcm3008_codec_remove, .driver = { .name = "pcm3008-codec", .owner = THIS_MODULE, diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c index 960d0e93cce..912c9cbc272 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, timesofbclk); if (coeff < 0) { dev_err(codec->dev, "Fail to get coeff\n"); - return -EINVAL; + return coeff; } switch (params_format(params)) { @@ -1748,7 +1748,7 @@ static int rt5631_i2c_probe(struct i2c_client *i2c, return ret; } -static __devexit int rt5631_i2c_remove(struct i2c_client *client) +static int rt5631_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -1760,7 +1760,7 @@ static struct i2c_driver rt5631_i2c_driver = { .owner = THIS_MODULE, }, .probe = rt5631_i2c_probe, - .remove = __devexit_p(rt5631_i2c_remove), + .remove = rt5631_i2c_remove, .id_table = rt5631_i2c_id, }; diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index df2f99d1d42..cb1675cd8e1 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -1404,8 +1404,8 @@ static struct snd_soc_codec_driver sgtl5000_driver = { .num_dapm_routes = ARRAY_SIZE(sgtl5000_dapm_routes), }; -static __devinit int sgtl5000_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int sgtl5000_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) { struct sgtl5000_priv *sgtl5000; int ret; @@ -1422,7 +1422,7 @@ static __devinit int sgtl5000_i2c_probe(struct i2c_client *client, return ret; } -static __devexit int sgtl5000_i2c_remove(struct i2c_client *client) +static int sgtl5000_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); @@ -1449,7 +1449,7 @@ static struct i2c_driver sgtl5000_i2c_driver = { .of_match_table = sgtl5000_dt_ids, }, .probe = sgtl5000_i2c_probe, - .remove = __devexit_p(sgtl5000_i2c_remove), + .remove = sgtl5000_i2c_remove, .id_table = sgtl5000_id, }; diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c new file mode 100644 index 00000000000..f2d61a18783 --- /dev/null +++ b/sound/soc/codecs/si476x.c @@ -0,0 +1,255 @@ +#include <linux/module.h> +#include <linux/slab.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/soc.h> +#include <sound/initval.h> + +#include <linux/i2c.h> + +#include <linux/mfd/si476x-core.h> + +enum si476x_audio_registers { + SI476X_DIGITAL_IO_OUTPUT_FORMAT = 0x0203, + SI476X_DIGITAL_IO_OUTPUT_SAMPLE_RATE = 0x0202, +}; + +enum si476x_digital_io_output_format { + SI476X_DIGITAL_IO_SLOT_SIZE_SHIFT = 11, + SI476X_DIGITAL_IO_SAMPLE_SIZE_SHIFT = 8, +}; + +#define SI476X_DIGITAL_IO_OUTPUT_WIDTH_MASK ((0b111 << SI476X_DIGITAL_IO_SLOT_SIZE_SHIFT) | \ + (0b111 << SI476X_DIGITAL_IO_SAMPLE_SIZE_SHIFT)) +#define SI476X_DIGITAL_IO_OUTPUT_FORMAT_MASK (0b1111110) + +enum si476x_daudio_formats { + SI476X_DAUDIO_MODE_I2S = (0x0 << 1), + SI476X_DAUDIO_MODE_DSP_A = (0x6 << 1), + SI476X_DAUDIO_MODE_DSP_B = (0x7 << 1), + SI476X_DAUDIO_MODE_LEFT_J = (0x8 << 1), + SI476X_DAUDIO_MODE_RIGHT_J = (0x9 << 1), + + SI476X_DAUDIO_MODE_IB = (1 << 5), + SI476X_DAUDIO_MODE_IF = (1 << 6), +}; + +enum si476x_pcm_format { + SI476X_PCM_FORMAT_S8 = 2, + SI476X_PCM_FORMAT_S16_LE = 4, + SI476X_PCM_FORMAT_S20_3LE = 5, + SI476X_PCM_FORMAT_S24_LE = 6, +}; + +static unsigned int si476x_codec_read(struct snd_soc_codec *codec, + unsigned int reg) +{ + int err; + struct si476x_core *core = codec->control_data; + + si476x_core_lock(core); + err = si476x_core_cmd_get_property(core, reg); + si476x_core_unlock(core); + + return err; +} + +static int si476x_codec_write(struct snd_soc_codec *codec, + unsigned int reg, unsigned int val) +{ + int err; + struct si476x_core *core = codec->control_data; + + si476x_core_lock(core); + err = si476x_core_cmd_set_property(core, reg, val); + si476x_core_unlock(core); + + return err; +} + +static int si476x_codec_set_dai_fmt(struct snd_soc_dai *codec_dai, + unsigned int fmt) +{ + int err; + u16 format = 0; + + if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) + return -EINVAL; + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: + format |= SI476X_DAUDIO_MODE_DSP_A; + break; + case SND_SOC_DAIFMT_DSP_B: + format |= SI476X_DAUDIO_MODE_DSP_B; + break; + case SND_SOC_DAIFMT_I2S: + format |= SI476X_DAUDIO_MODE_I2S; + break; + case SND_SOC_DAIFMT_RIGHT_J: + format |= SI476X_DAUDIO_MODE_RIGHT_J; + break; + case SND_SOC_DAIFMT_LEFT_J: + format |= SI476X_DAUDIO_MODE_LEFT_J; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: + case SND_SOC_DAIFMT_DSP_B: + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_NF: + format |= SI476X_DAUDIO_MODE_IB; + break; + default: + return -EINVAL; + } + break; + case SND_SOC_DAIFMT_I2S: + case SND_SOC_DAIFMT_RIGHT_J: + case SND_SOC_DAIFMT_LEFT_J: + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_IF: + format |= SI476X_DAUDIO_MODE_IB | + SI476X_DAUDIO_MODE_IF; + break; + case SND_SOC_DAIFMT_IB_NF: + format |= SI476X_DAUDIO_MODE_IB; + break; + case SND_SOC_DAIFMT_NB_IF: + format |= SI476X_DAUDIO_MODE_IF; + break; + default: + return -EINVAL; + } + break; + default: + return -EINVAL; + } + + err = snd_soc_update_bits(codec_dai->codec, SI476X_DIGITAL_IO_OUTPUT_FORMAT, + SI476X_DIGITAL_IO_OUTPUT_FORMAT_MASK, + format); + if (err < 0) { + dev_err(codec_dai->codec->dev, "Failed to set output format\n"); + return err; + } + + return 0; +} + +static int si476x_codec_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + int rate, width, err; + + rate = params_rate(params); + if (rate < 32000 || rate > 48000) { + dev_err(dai->codec->dev, "Rate: %d is not supported\n", rate); + return -EINVAL; + } + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S8: + width = SI476X_PCM_FORMAT_S8; + case SNDRV_PCM_FORMAT_S16_LE: + width = SI476X_PCM_FORMAT_S16_LE; + break; + case SNDRV_PCM_FORMAT_S20_3LE: + width = SI476X_PCM_FORMAT_S20_3LE; + break; + case SNDRV_PCM_FORMAT_S24_LE: + width = SI476X_PCM_FORMAT_S24_LE; + break; + default: + return -EINVAL; + } + + err = snd_soc_write(dai->codec, SI476X_DIGITAL_IO_OUTPUT_SAMPLE_RATE, + rate); + if (err < 0) { + dev_err(dai->codec->dev, "Failed to set sample rate\n"); + return err; + } + + err = snd_soc_update_bits(dai->codec, SI476X_DIGITAL_IO_OUTPUT_FORMAT, + SI476X_DIGITAL_IO_OUTPUT_WIDTH_MASK, + (width << SI476X_DIGITAL_IO_SLOT_SIZE_SHIFT) | + (width << SI476X_DIGITAL_IO_SAMPLE_SIZE_SHIFT)); + if (err < 0) { + dev_err(dai->codec->dev, "Failed to set output width\n"); + return err; + } + + return 0; +} + +static int si476x_codec_probe(struct snd_soc_codec *codec) +{ + codec->control_data = i2c_mfd_cell_to_core(codec->dev); + return 0; +} + +static struct snd_soc_dai_ops si476x_dai_ops = { + .hw_params = si476x_codec_hw_params, + .set_fmt = si476x_codec_set_dai_fmt, +}; + +static struct snd_soc_dai_driver si476x_dai = { + .name = "si476x-codec", + .capture = { + .stream_name = "Capture", + .channels_min = 2, + .channels_max = 2, + + .rates = SNDRV_PCM_RATE_32000 | + SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S8 | + SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S20_3LE | + SNDRV_PCM_FMTBIT_S24_LE + }, + .ops = &si476x_dai_ops, +}; + +static struct snd_soc_codec_driver soc_codec_dev_si476x = { + .probe = si476x_codec_probe, + .read = si476x_codec_read, + .write = si476x_codec_write, +}; + +static int si476x_platform_probe(struct platform_device *pdev) +{ + return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_si476x, + &si476x_dai, 1); +} + +static int si476x_platform_remove(struct platform_device *pdev) +{ + snd_soc_unregister_codec(&pdev->dev); + return 0; +} + +MODULE_ALIAS("platform:si476x-codec"); + +static struct platform_driver si476x_platform_driver = { + .driver = { + .name = "si476x-codec", + .owner = THIS_MODULE, + }, + .probe = si476x_platform_probe, + .remove = si476x_platform_remove, +}; +module_platform_driver(si476x_platform_driver); + +MODULE_AUTHOR("Andrey Smirnov <andrey.smirnov@convergeddevices.net>"); +MODULE_DESCRIPTION("ASoC Si4761/64 codec driver"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c index 50dbdb9357e..d1ae869d318 100644 --- a/sound/soc/codecs/sn95031.c +++ b/sound/soc/codecs/sn95031.c @@ -896,14 +896,14 @@ struct snd_soc_codec_driver sn95031_codec = { .num_dapm_routes = ARRAY_SIZE(sn95031_audio_map), }; -static int __devinit sn95031_device_probe(struct platform_device *pdev) +static int sn95031_device_probe(struct platform_device *pdev) { pr_debug("codec device probe called for %s\n", dev_name(&pdev->dev)); return snd_soc_register_codec(&pdev->dev, &sn95031_codec, sn95031_dais, ARRAY_SIZE(sn95031_dais)); } -static int __devexit sn95031_device_remove(struct platform_device *pdev) +static int sn95031_device_remove(struct platform_device *pdev) { pr_debug("codec device remove called\n"); snd_soc_unregister_codec(&pdev->dev); @@ -916,7 +916,7 @@ static struct platform_driver sn95031_codec_driver = { .owner = THIS_MODULE, }, .probe = sn95031_device_probe, - .remove = __devexit_p(sn95031_device_remove), + .remove = sn95031_device_remove, }; module_platform_driver(sn95031_codec_driver); diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c index 079066fef42..f8d30e5f637 100644 --- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c @@ -691,7 +691,7 @@ static const struct regmap_config ssm2602_regmap_config = { }; #if defined(CONFIG_SPI_MASTER) -static int __devinit ssm2602_spi_probe(struct spi_device *spi) +static int ssm2602_spi_probe(struct spi_device *spi) { struct ssm2602_priv *ssm2602; int ret; @@ -713,7 +713,7 @@ static int __devinit ssm2602_spi_probe(struct spi_device *spi) return ret; } -static int __devexit ssm2602_spi_remove(struct spi_device *spi) +static int ssm2602_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev); return 0; @@ -725,7 +725,7 @@ static struct spi_driver ssm2602_spi_driver = { .owner = THIS_MODULE, }, .probe = ssm2602_spi_probe, - .remove = __devexit_p(ssm2602_spi_remove), + .remove = ssm2602_spi_remove, }; #endif @@ -736,7 +736,7 @@ static struct spi_driver ssm2602_spi_driver = { * low = 0x1a * high = 0x1b */ -static int __devinit ssm2602_i2c_probe(struct i2c_client *i2c, +static int ssm2602_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct ssm2602_priv *ssm2602; @@ -759,7 +759,7 @@ static int __devinit ssm2602_i2c_probe(struct i2c_client *i2c, return ret; } -static int __devexit ssm2602_i2c_remove(struct i2c_client *client) +static int ssm2602_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -780,7 +780,7 @@ static struct i2c_driver ssm2602_i2c_driver = { .owner = THIS_MODULE, }, .probe = ssm2602_i2c_probe, - .remove = __devexit_p(ssm2602_i2c_remove), + .remove = ssm2602_i2c_remove, .id_table = ssm2602_i2c_id, }; #endif diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c index 0935bfe6247..cfb55fe35e9 100644 --- a/sound/soc/codecs/sta32x.c +++ b/sound/soc/codecs/sta32x.c @@ -995,8 +995,8 @@ static const struct regmap_config sta32x_regmap = { .volatile_reg = sta32x_reg_is_volatile, }; -static __devinit int sta32x_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int sta32x_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct sta32x_priv *sta32x; int ret, i; @@ -1033,7 +1033,7 @@ static __devinit int sta32x_i2c_probe(struct i2c_client *i2c, return ret; } -static __devexit int sta32x_i2c_remove(struct i2c_client *client) +static int sta32x_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -1053,7 +1053,7 @@ static struct i2c_driver sta32x_i2c_driver = { .owner = THIS_MODULE, }, .probe = sta32x_i2c_probe, - .remove = __devexit_p(sta32x_i2c_remove), + .remove = sta32x_i2c_remove, .id_table = sta32x_i2c_id, }; diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c index 9e314486238..ab355c4f0b2 100644 --- a/sound/soc/codecs/sta529.c +++ b/sound/soc/codecs/sta529.c @@ -380,8 +380,8 @@ static const struct regmap_config sta529_regmap = { .num_reg_defaults = ARRAY_SIZE(sta529_reg_defaults), }; -static __devinit int sta529_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int sta529_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct sta529 *sta529; int ret; @@ -412,7 +412,7 @@ static __devinit int sta529_i2c_probe(struct i2c_client *i2c, return ret; } -static int __devexit sta529_i2c_remove(struct i2c_client *client) +static int sta529_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); @@ -431,7 +431,7 @@ static struct i2c_driver sta529_i2c_driver = { .owner = THIS_MODULE, }, .probe = sta529_i2c_probe, - .remove = __devexit_p(sta529_i2c_remove), + .remove = sta529_i2c_remove, .id_table = sta529_i2c_id, }; diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index 982e437799a..2eda85ba79a 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c @@ -385,13 +385,13 @@ static struct snd_soc_codec_driver soc_codec_dev_stac9766 = { .reg_cache_default = stac9766_reg, }; -static __devinit int stac9766_probe(struct platform_device *pdev) +static int stac9766_probe(struct platform_device *pdev) { return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_stac9766, stac9766_dai, ARRAY_SIZE(stac9766_dai)); } -static int __devexit stac9766_remove(struct platform_device *pdev) +static int stac9766_remove(struct platform_device *pdev) { snd_soc_unregister_codec(&pdev->dev); return 0; @@ -404,7 +404,7 @@ static struct platform_driver stac9766_codec_driver = { }, .probe = stac9766_probe, - .remove = __devexit_p(stac9766_remove), + .remove = stac9766_remove, }; module_platform_driver(stac9766_codec_driver); diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index f230292ba96..17df4e32fea 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c @@ -28,6 +28,7 @@ #include <linux/init.h> #include <linux/delay.h> #include <linux/pm.h> +#include <linux/gpio.h> #include <linux/i2c.h> #include <linux/cdev.h> #include <linux/slab.h> @@ -65,6 +66,7 @@ struct aic32x4_priv { u32 power_cfg; u32 micpga_routing; bool swapdacs; + int rstn_gpio; }; /* 0dB min, 1dB steps */ @@ -627,10 +629,20 @@ static int aic32x4_probe(struct snd_soc_codec *codec) { struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); u32 tmp_reg; + int ret; codec->hw_write = (hw_write_t) i2c_master_send; codec->control_data = aic32x4->control_data; + if (aic32x4->rstn_gpio >= 0) { + ret = devm_gpio_request_one(codec->dev, aic32x4->rstn_gpio, + GPIOF_OUT_INIT_LOW, "tlv320aic32x4 rstn"); + if (ret != 0) + return ret; + ndelay(10); + gpio_set_value(aic32x4->rstn_gpio, 1); + } + snd_soc_write(codec, AIC32X4_RESET, 0x01); /* Power platform configuration */ @@ -675,6 +687,16 @@ static int aic32x4_probe(struct snd_soc_codec *codec) ARRAY_SIZE(aic32x4_snd_controls)); aic32x4_add_widgets(codec); + /* + * Workaround: for an unknown reason, the ADC needs to be powered up + * and down for the first capture to work properly. It seems related to + * a HW BUG or some kind of behavior not documented in the datasheet. + */ + tmp_reg = snd_soc_read(codec, AIC32X4_ADCSETUP); + snd_soc_write(codec, AIC32X4_ADCSETUP, tmp_reg | + AIC32X4_LADC_EN | AIC32X4_RADC_EN); + snd_soc_write(codec, AIC32X4_ADCSETUP, tmp_reg); + return 0; } @@ -694,8 +716,8 @@ static struct snd_soc_codec_driver soc_codec_dev_aic32x4 = { .set_bias_level = aic32x4_set_bias_level, }; -static __devinit int aic32x4_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int aic32x4_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct aic32x4_pdata *pdata = i2c->dev.platform_data; struct aic32x4_priv *aic32x4; @@ -713,10 +735,12 @@ static __devinit int aic32x4_i2c_probe(struct i2c_client *i2c, aic32x4->power_cfg = pdata->power_cfg; aic32x4->swapdacs = pdata->swapdacs; aic32x4->micpga_routing = pdata->micpga_routing; + aic32x4->rstn_gpio = pdata->rstn_gpio; } else { aic32x4->power_cfg = 0; aic32x4->swapdacs = false; aic32x4->micpga_routing = 0; + aic32x4->rstn_gpio = -1; } ret = snd_soc_register_codec(&i2c->dev, @@ -724,7 +748,7 @@ static __devinit int aic32x4_i2c_probe(struct i2c_client *i2c, return ret; } -static __devexit int aic32x4_i2c_remove(struct i2c_client *client) +static int aic32x4_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -742,7 +766,7 @@ static struct i2c_driver aic32x4_i2c_driver = { .owner = THIS_MODULE, }, .probe = aic32x4_i2c_probe, - .remove = __devexit_p(aic32x4_i2c_remove), + .remove = aic32x4_i2c_remove, .id_table = aic32x4_i2c_id, }; diff --git a/sound/soc/codecs/tlv320aic32x4.h b/sound/soc/codecs/tlv320aic32x4.h index aae2b244039..35774223fd9 100644 --- a/sound/soc/codecs/tlv320aic32x4.h +++ b/sound/soc/codecs/tlv320aic32x4.h @@ -94,6 +94,9 @@ #define AIC32X4_WORD_LEN_24BITS 0x02 #define AIC32X4_WORD_LEN_32BITS 0x03 +#define AIC32X4_LADC_EN (1 << 7) +#define AIC32X4_RADC_EN (1 << 6) + #define AIC32X4_I2S_MODE 0x00 #define AIC32X4_DSP_MODE 0x01 #define AIC32X4_RIGHT_JUSTIFIED_MODE 0x02 diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index d2e16c5d7d1..782b0cded2e 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -1514,8 +1514,8 @@ static struct snd_soc_dai_driver dac33_dai = { .ops = &dac33_dai_ops, }; -static int __devinit dac33_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int dac33_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) { struct tlv320dac33_platform_data *pdata; struct tlv320dac33_priv *dac33; @@ -1586,7 +1586,7 @@ err_gpio: return ret; } -static int __devexit dac33_i2c_remove(struct i2c_client *client) +static int dac33_i2c_remove(struct i2c_client *client) { struct tlv320dac33_priv *dac33 = i2c_get_clientdata(client); @@ -1617,7 +1617,7 @@ static struct i2c_driver tlv320dac33_i2c_driver = { .owner = THIS_MODULE, }, .probe = dac33_i2c_probe, - .remove = __devexit_p(dac33_i2c_remove), + .remove = dac33_i2c_remove, .id_table = tlv320dac33_i2c_id, }; diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index 565ff39ad3a..8d75aa152c8 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c @@ -359,8 +359,8 @@ int tpa6130a2_add_controls(struct snd_soc_codec *codec) } EXPORT_SYMBOL_GPL(tpa6130a2_add_controls); -static int __devinit tpa6130a2_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int tpa6130a2_probe(struct i2c_client *client, + const struct i2c_device_id *id) { struct device *dev; struct tpa6130a2_data *data; @@ -455,7 +455,7 @@ err_gpio: return ret; } -static int __devexit tpa6130a2_remove(struct i2c_client *client) +static int tpa6130a2_remove(struct i2c_client *client) { struct tpa6130a2_data *data = i2c_get_clientdata(client); @@ -483,7 +483,7 @@ static struct i2c_driver tpa6130a2_i2c_driver = { .owner = THIS_MODULE, }, .probe = tpa6130a2_probe, - .remove = __devexit_p(tpa6130a2_remove), + .remove = tpa6130a2_remove, .id_table = tpa6130a2_id, }; diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index e7f608996c4..63b280b0603 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -2334,13 +2334,13 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = { .num_dapm_routes = ARRAY_SIZE(intercon), }; -static int __devinit twl4030_codec_probe(struct platform_device *pdev) +static int twl4030_codec_probe(struct platform_device *pdev) { return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl4030, twl4030_dai, ARRAY_SIZE(twl4030_dai)); } -static int __devexit twl4030_codec_remove(struct platform_device *pdev) +static int twl4030_codec_remove(struct platform_device *pdev) { snd_soc_unregister_codec(&pdev->dev); return 0; @@ -2350,7 +2350,7 @@ MODULE_ALIAS("platform:twl4030-codec"); static struct platform_driver twl4030_codec_driver = { .probe = twl4030_codec_probe, - .remove = __devexit_p(twl4030_codec_remove), + .remove = twl4030_codec_remove, .driver = { .name = "twl4030-codec", .owner = THIS_MODULE, diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 00b85cc1b9a..3fc3fc64dd8 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -1229,13 +1229,13 @@ static struct snd_soc_codec_driver soc_codec_dev_twl6040 = { .num_dapm_routes = ARRAY_SIZE(intercon), }; -static int __devinit twl6040_codec_probe(struct platform_device *pdev) +static int twl6040_codec_probe(struct platform_device *pdev) { return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl6040, twl6040_dai, ARRAY_SIZE(twl6040_dai)); } -static int __devexit twl6040_codec_remove(struct platform_device *pdev) +static int twl6040_codec_remove(struct platform_device *pdev) { snd_soc_unregister_codec(&pdev->dev); return 0; @@ -1247,7 +1247,7 @@ static struct platform_driver twl6040_codec_driver = { .owner = THIS_MODULE, }, .probe = twl6040_codec_probe, - .remove = __devexit_p(twl6040_codec_remove), + .remove = twl6040_codec_remove, }; module_platform_driver(twl6040_codec_driver); diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index 6c3d43b8ee8..6d0aa44c375 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c @@ -601,13 +601,13 @@ static struct snd_soc_codec_driver soc_codec_dev_uda134x = { .set_bias_level = uda134x_set_bias_level, }; -static int __devinit uda134x_codec_probe(struct platform_device *pdev) +static int uda134x_codec_probe(struct platform_device *pdev) { return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_uda134x, &uda134x_dai, 1); } -static int __devexit uda134x_codec_remove(struct platform_device *pdev) +static int uda134x_codec_remove(struct platform_device *pdev) { snd_soc_unregister_codec(&pdev->dev); return 0; @@ -619,7 +619,7 @@ static struct platform_driver uda134x_codec_driver = { .owner = THIS_MODULE, }, .probe = uda134x_codec_probe, - .remove = __devexit_p(uda134x_codec_remove), + .remove = uda134x_codec_remove, }; module_platform_driver(uda134x_codec_driver); diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index 2502214b84a..fd0a314bc20 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c @@ -795,8 +795,8 @@ static struct snd_soc_codec_driver soc_codec_dev_uda1380 = { }; #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static __devinit int uda1380_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int uda1380_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct uda1380_priv *uda1380; int ret; @@ -814,7 +814,7 @@ static __devinit int uda1380_i2c_probe(struct i2c_client *i2c, return ret; } -static int __devexit uda1380_i2c_remove(struct i2c_client *i2c) +static int uda1380_i2c_remove(struct i2c_client *i2c) { snd_soc_unregister_codec(&i2c->dev); return 0; @@ -832,7 +832,7 @@ static struct i2c_driver uda1380_i2c_driver = { .owner = THIS_MODULE, }, .probe = uda1380_i2c_probe, - .remove = __devexit_p(uda1380_i2c_remove), + .remove = uda1380_i2c_remove, .id_table = uda1380_i2c_id, }; #endif diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c index 7b24d6d192e..54cd3da09ab 100644 --- a/sound/soc/codecs/wl1273.c +++ b/sound/soc/codecs/wl1273.c @@ -485,13 +485,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wl1273 = { .remove = wl1273_remove, }; -static int __devinit wl1273_platform_probe(struct platform_device *pdev) +static int wl1273_platform_probe(struct platform_device *pdev) { return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wl1273, &wl1273_dai, 1); } -static int __devexit wl1273_platform_remove(struct platform_device *pdev) +static int wl1273_platform_remove(struct platform_device *pdev) { snd_soc_unregister_codec(&pdev->dev); return 0; @@ -505,7 +505,7 @@ static struct platform_driver wl1273_platform_driver = { .owner = THIS_MODULE, }, .probe = wl1273_platform_probe, - .remove = __devexit_p(wl1273_platform_remove), + .remove = wl1273_platform_remove, }; module_platform_driver(wl1273_platform_driver); diff --git a/sound/soc/codecs/wm0010.c b/sound/soc/codecs/wm0010.c index 99afc003a08..ad2fee4bb4c 100644 --- a/sound/soc/codecs/wm0010.c +++ b/sound/soc/codecs/wm0010.c @@ -31,6 +31,9 @@ #define DEVICE_ID_WM0010 10 +/* We only support v1 of the .dfw INFO record */ +#define INFO_VERSION 1 + enum dfw_cmd { DFW_CMD_FUSE = 0x01, DFW_CMD_CODE_HDR, @@ -46,6 +49,13 @@ struct dfw_binrec { uint8_t data[0]; } __packed; +struct dfw_inforec { + u8 info_version; + u8 tool_major_version; + u8 tool_minor_version; + u8 dsp_target; +}; + struct dfw_pllrec { u8 command; u32 length:24; @@ -97,7 +107,6 @@ struct wm0010_priv { enum wm0010_state state; bool boot_failed; - int boot_done; bool ready; bool pll_running; int max_spi_freq; @@ -234,7 +243,7 @@ static void wm0010_boot_xfer_complete(void *data) break; case 0x55555555: - if (wm0010->boot_done == 0) + if (wm0010->state < WM0010_STAGE2) break; dev_err(codec->dev, "%d: ROM bootloader running in stage 2\n", i); @@ -321,7 +330,6 @@ static void wm0010_boot_xfer_complete(void *data) break; } - wm0010->boot_done++; if (xfer->done) complete(xfer->done); } @@ -334,94 +342,198 @@ static void byte_swap_64(u64 *data_in, u64 *data_out, u32 len) data_out[i] = cpu_to_be64(le64_to_cpu(data_in[i])); } -static int wm0010_boot(struct snd_soc_codec *codec) +static int wm0010_firmware_load(char *name, struct snd_soc_codec *codec) { struct spi_device *spi = to_spi_device(codec->dev); struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec); - unsigned long flags; struct list_head xfer_list; struct wm0010_boot_xfer *xfer; int ret; struct completion done; const struct firmware *fw; const struct dfw_binrec *rec; - struct spi_message m; - struct spi_transfer t; - struct dfw_pllrec pll_rec; - u32 *img, *p; - u64 *img_swap; - u8 *out; + const struct dfw_inforec *inforec; + u64 *img; + u8 *out, dsp; u32 len, offset; - int i; - spin_lock_irqsave(&wm0010->irq_lock, flags); - if (wm0010->state != WM0010_POWER_OFF) - dev_warn(wm0010->dev, "DSP already powered up!\n"); - spin_unlock_irqrestore(&wm0010->irq_lock, flags); + INIT_LIST_HEAD(&xfer_list); - if (wm0010->sysclk > 26000000) { - dev_err(codec->dev, "Max DSP clock frequency is 26MHz\n"); - ret = -ECANCELED; - goto err; + ret = request_firmware(&fw, name, codec->dev); + if (ret != 0) { + dev_err(codec->dev, "Failed to request application: %d\n", + ret); + return ret; } - INIT_LIST_HEAD(&xfer_list); + rec = (const struct dfw_binrec *)fw->data; + inforec = (const struct dfw_inforec *)rec->data; + offset = 0; + dsp = inforec->dsp_target; + wm0010->boot_failed = false; + BUG_ON(!list_empty(&xfer_list)); + init_completion(&done); - mutex_lock(&wm0010->lock); - wm0010->pll_running = false; + /* First record should be INFO */ + if (rec->command != DFW_CMD_INFO) { + dev_err(codec->dev, "First record not INFO\r\n"); + ret = -EINVAL; + goto abort; + } - dev_dbg(codec->dev, "max_spi_freq: %d\n", wm0010->max_spi_freq); + if (inforec->info_version != INFO_VERSION) { + dev_err(codec->dev, + "Unsupported version (%02d) of INFO record\r\n", + inforec->info_version); + ret = -EINVAL; + goto abort; + } - ret = regulator_bulk_enable(ARRAY_SIZE(wm0010->core_supplies), - wm0010->core_supplies); - if (ret != 0) { - dev_err(&spi->dev, "Failed to enable core supplies: %d\n", - ret); - mutex_unlock(&wm0010->lock); - goto err; + dev_dbg(codec->dev, "Version v%02d INFO record found\r\n", + inforec->info_version); + + /* Check it's a DSP file */ + if (dsp != DEVICE_ID_WM0010) { + dev_err(codec->dev, "Not a WM0010 firmware file.\r\n"); + ret = -EINVAL; + goto abort; } - ret = regulator_enable(wm0010->dbvdd); - if (ret != 0) { - dev_err(&spi->dev, "Failed to enable DBVDD: %d\n", ret); - goto err_core; + /* Skip the info record as we don't need to send it */ + offset += ((rec->length) + 8); + rec = (void *)&rec->data[rec->length]; + + while (offset < fw->size) { + dev_dbg(codec->dev, + "Packet: command %d, data length = 0x%x\r\n", + rec->command, rec->length); + len = rec->length + 8; + + out = kzalloc(len, GFP_KERNEL); + if (!out) { + dev_err(codec->dev, + "Failed to allocate RX buffer\n"); + ret = -ENOMEM; + goto abort1; + } + + img = kzalloc(len, GFP_KERNEL); + if (!img) { + dev_err(codec->dev, + "Failed to allocate image buffer\n"); + ret = -ENOMEM; + goto abort1; + } + + byte_swap_64((u64 *)&rec->command, img, len); + + xfer = kzalloc(sizeof(*xfer), GFP_KERNEL); + if (!xfer) { + dev_err(codec->dev, "Failed to allocate xfer\n"); + ret = -ENOMEM; + goto abort1; + } + + xfer->codec = codec; + list_add_tail(&xfer->list, &xfer_list); + + spi_message_init(&xfer->m); + xfer->m.complete = wm0010_boot_xfer_complete; + xfer->m.context = xfer; + xfer->t.tx_buf = img; + xfer->t.rx_buf = out; + xfer->t.len = len; + xfer->t.bits_per_word = 8; + + if (!wm0010->pll_running) { + xfer->t.speed_hz = wm0010->sysclk / 6; + } else { + xfer->t.speed_hz = wm0010->max_spi_freq; + + if (wm0010->board_max_spi_speed && + (wm0010->board_max_spi_speed < wm0010->max_spi_freq)) + xfer->t.speed_hz = wm0010->board_max_spi_speed; + } + + /* Store max usable spi frequency for later use */ + wm0010->max_spi_freq = xfer->t.speed_hz; + + spi_message_add_tail(&xfer->t, &xfer->m); + + offset += ((rec->length) + 8); + rec = (void *)&rec->data[rec->length]; + + if (offset >= fw->size) { + dev_dbg(codec->dev, "All transfers scheduled\n"); + xfer->done = &done; + } + + ret = spi_async(spi, &xfer->m); + if (ret != 0) { + dev_err(codec->dev, "Write failed: %d\n", ret); + goto abort1; + } + + if (wm0010->boot_failed) { + dev_dbg(codec->dev, "Boot fail!\n"); + ret = -EINVAL; + goto abort1; + } } - /* Release reset */ - gpio_set_value_cansleep(wm0010->gpio_reset, !wm0010->gpio_reset_value); - spin_lock_irqsave(&wm0010->irq_lock, flags); - wm0010->state = WM0010_OUT_OF_RESET; - spin_unlock_irqrestore(&wm0010->irq_lock, flags); + wait_for_completion(&done); + + ret = 0; + +abort1: + while (!list_empty(&xfer_list)) { + xfer = list_first_entry(&xfer_list, struct wm0010_boot_xfer, + list); + kfree(xfer->t.rx_buf); + kfree(xfer->t.tx_buf); + list_del(&xfer->list); + kfree(xfer); + } + +abort: + release_firmware(fw); + return ret; +} + +static int wm0010_stage2_load(struct snd_soc_codec *codec) +{ + struct spi_device *spi = to_spi_device(codec->dev); + struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec); + const struct firmware *fw; + struct spi_message m; + struct spi_transfer t; + u32 *img; + u8 *out; + int i; + int ret = 0; - /* First the bootloader */ ret = request_firmware(&fw, "wm0010_stage2.bin", codec->dev); if (ret != 0) { dev_err(codec->dev, "Failed to request stage2 loader: %d\n", ret); - goto abort; + return ret; } - if (!wait_for_completion_timeout(&wm0010->boot_completion, - msecs_to_jiffies(10))) - dev_err(codec->dev, "Failed to get interrupt from DSP\n"); - - spin_lock_irqsave(&wm0010->irq_lock, flags); - wm0010->state = WM0010_BOOTROM; - spin_unlock_irqrestore(&wm0010->irq_lock, flags); - dev_dbg(codec->dev, "Downloading %zu byte stage 2 loader\n", fw->size); /* Copy to local buffer first as vmalloc causes problems for dma */ img = kzalloc(fw->size, GFP_KERNEL); if (!img) { dev_err(codec->dev, "Failed to allocate image buffer\n"); - goto abort; + ret = -ENOMEM; + goto abort2; } out = kzalloc(fw->size, GFP_KERNEL); if (!out) { dev_err(codec->dev, "Failed to allocate output buffer\n"); - goto abort; + ret = -ENOMEM; + goto abort1; } memcpy(img, &fw->data[0], fw->size); @@ -447,20 +559,97 @@ static int wm0010_boot(struct snd_soc_codec *codec) /* Look for errors from the boot ROM */ for (i = 0; i < fw->size; i++) { if (out[i] != 0x55) { - ret = -EBUSY; dev_err(codec->dev, "Boot ROM error: %x in %d\n", out[i], i); wm0010_mark_boot_failure(wm0010); + ret = -EBUSY; goto abort; } } - - release_firmware(fw); - kfree(img); +abort: kfree(out); +abort1: + kfree(img); +abort2: + release_firmware(fw); + + return ret; +} + +static int wm0010_boot(struct snd_soc_codec *codec) +{ + struct spi_device *spi = to_spi_device(codec->dev); + struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec); + unsigned long flags; + int ret; + const struct firmware *fw; + struct spi_message m; + struct spi_transfer t; + struct dfw_pllrec pll_rec; + u32 *p, len; + u64 *img_swap; + u8 *out; + int i; + + spin_lock_irqsave(&wm0010->irq_lock, flags); + if (wm0010->state != WM0010_POWER_OFF) + dev_warn(wm0010->dev, "DSP already powered up!\n"); + spin_unlock_irqrestore(&wm0010->irq_lock, flags); + + if (wm0010->sysclk > 26000000) { + dev_err(codec->dev, "Max DSP clock frequency is 26MHz\n"); + ret = -ECANCELED; + goto err; + } + + mutex_lock(&wm0010->lock); + wm0010->pll_running = false; + + dev_dbg(codec->dev, "max_spi_freq: %d\n", wm0010->max_spi_freq); + + ret = regulator_bulk_enable(ARRAY_SIZE(wm0010->core_supplies), + wm0010->core_supplies); + if (ret != 0) { + dev_err(&spi->dev, "Failed to enable core supplies: %d\n", + ret); + mutex_unlock(&wm0010->lock); + goto err; + } + + ret = regulator_enable(wm0010->dbvdd); + if (ret != 0) { + dev_err(&spi->dev, "Failed to enable DBVDD: %d\n", ret); + goto err_core; + } + + /* Release reset */ + gpio_set_value_cansleep(wm0010->gpio_reset, !wm0010->gpio_reset_value); + spin_lock_irqsave(&wm0010->irq_lock, flags); + wm0010->state = WM0010_OUT_OF_RESET; + spin_unlock_irqrestore(&wm0010->irq_lock, flags); + + /* First the bootloader */ + ret = request_firmware(&fw, "wm0010_stage2.bin", codec->dev); + if (ret != 0) { + dev_err(codec->dev, "Failed to request stage2 loader: %d\n", + ret); + goto abort; + } + + if (!wait_for_completion_timeout(&wm0010->boot_completion, + msecs_to_jiffies(20))) + dev_err(codec->dev, "Failed to get interrupt from DSP\n"); + + spin_lock_irqsave(&wm0010->irq_lock, flags); + wm0010->state = WM0010_BOOTROM; + spin_unlock_irqrestore(&wm0010->irq_lock, flags); + + ret = wm0010_stage2_load(codec); + if (ret) + goto abort; if (!wait_for_completion_timeout(&wm0010->boot_completion, - msecs_to_jiffies(10))) + msecs_to_jiffies(20))) dev_err(codec->dev, "Failed to get interrupt from DSP loader.\n"); spin_lock_irqsave(&wm0010->irq_lock, flags); @@ -535,110 +724,10 @@ static int wm0010_boot(struct snd_soc_codec *codec) } else dev_dbg(codec->dev, "Not enabling DSP PLL."); - ret = request_firmware(&fw, "wm0010.dfw", codec->dev); - if (ret != 0) { - dev_err(codec->dev, "Failed to request application: %d\n", - ret); - goto abort; - } - - rec = (const struct dfw_binrec *)fw->data; - offset = 0; - wm0010->boot_done = 0; - wm0010->boot_failed = false; - BUG_ON(!list_empty(&xfer_list)); - init_completion(&done); + ret = wm0010_firmware_load("wm0010.dfw", codec); - /* First record should be INFO */ - if (rec->command != DFW_CMD_INFO) { - dev_err(codec->dev, "First record not INFO\r\n"); - goto abort; - } - - /* Check it's a 0010 file */ - if (rec->data[0] != DEVICE_ID_WM0010) { - dev_err(codec->dev, "Not a WM0010 firmware file.\r\n"); + if (ret != 0) goto abort; - } - - /* Skip the info record as we don't need to send it */ - offset += ((rec->length) + 8); - rec = (void *)&rec->data[rec->length]; - - while (offset < fw->size) { - dev_dbg(codec->dev, - "Packet: command %d, data length = 0x%x\r\n", - rec->command, rec->length); - len = rec->length + 8; - - out = kzalloc(len, GFP_KERNEL); - if (!out) { - dev_err(codec->dev, - "Failed to allocate RX buffer\n"); - goto abort; - } - - img_swap = kzalloc(len, GFP_KERNEL); - if (!img_swap) { - dev_err(codec->dev, - "Failed to allocate image buffer\n"); - goto abort; - } - - /* We need to re-order for 0010 */ - byte_swap_64((u64 *)&rec->command, img_swap, len); - - xfer = kzalloc(sizeof(*xfer), GFP_KERNEL); - if (!xfer) { - dev_err(codec->dev, "Failed to allocate xfer\n"); - goto abort; - } - - xfer->codec = codec; - list_add_tail(&xfer->list, &xfer_list); - - spi_message_init(&xfer->m); - xfer->m.complete = wm0010_boot_xfer_complete; - xfer->m.context = xfer; - xfer->t.tx_buf = img_swap; - xfer->t.rx_buf = out; - xfer->t.len = len; - xfer->t.bits_per_word = 8; - - if (!wm0010->pll_running) { - xfer->t.speed_hz = wm0010->sysclk / 6; - } else { - xfer->t.speed_hz = wm0010->max_spi_freq; - - if (wm0010->board_max_spi_speed && - (wm0010->board_max_spi_speed < wm0010->max_spi_freq)) - xfer->t.speed_hz = wm0010->board_max_spi_speed; - } - - /* Store max usable spi frequency for later use */ - wm0010->max_spi_freq = xfer->t.speed_hz; - - spi_message_add_tail(&xfer->t, &xfer->m); - - offset += ((rec->length) + 8); - rec = (void *)&rec->data[rec->length]; - - if (offset >= fw->size) { - dev_dbg(codec->dev, "All transfers scheduled\n"); - xfer->done = &done; - } - - ret = spi_async(spi, &xfer->m); - if (ret != 0) { - dev_err(codec->dev, "Write failed: %d\n", ret); - goto abort; - } - - if (wm0010->boot_failed) - goto abort; - } - - wait_for_completion(&done); spin_lock_irqsave(&wm0010->irq_lock, flags); wm0010->state = WM0010_FIRMWARE; @@ -646,17 +735,6 @@ static int wm0010_boot(struct snd_soc_codec *codec) mutex_unlock(&wm0010->lock); - release_firmware(fw); - - while (!list_empty(&xfer_list)) { - xfer = list_first_entry(&xfer_list, struct wm0010_boot_xfer, - list); - kfree(xfer->t.rx_buf); - kfree(xfer->t.tx_buf); - list_del(&xfer->list); - kfree(xfer); - } - return 0; abort: @@ -784,7 +862,6 @@ static irqreturn_t wm0010_irq(int irq, void *data) struct wm0010_priv *wm0010 = data; switch (wm0010->state) { - case WM0010_POWER_OFF: case WM0010_OUT_OF_RESET: case WM0010_BOOTROM: case WM0010_STAGE2: @@ -808,7 +885,7 @@ static int wm0010_probe(struct snd_soc_codec *codec) return 0; } -static int __devinit wm0010_spi_probe(struct spi_device *spi) +static int wm0010_spi_probe(struct spi_device *spi) { unsigned long gpio_flags; int ret; @@ -908,7 +985,7 @@ static int __devinit wm0010_spi_probe(struct spi_device *spi) return 0; } -static int __devexit wm0010_spi_remove(struct spi_device *spi) +static int wm0010_spi_remove(struct spi_device *spi) { struct wm0010_priv *wm0010 = spi_get_drvdata(spi); @@ -930,7 +1007,7 @@ static struct spi_driver wm0010_spi_driver = { .owner = THIS_MODULE, }, .probe = wm0010_spi_probe, - .remove = __devexit_p(wm0010_spi_remove), + .remove = wm0010_spi_remove, }; module_spi_driver(wm0010_spi_driver); diff --git a/sound/soc/codecs/wm1250-ev1.c b/sound/soc/codecs/wm1250-ev1.c index 951d7b49476..6e6b93d4696 100644 --- a/sound/soc/codecs/wm1250-ev1.c +++ b/sound/soc/codecs/wm1250-ev1.c @@ -153,7 +153,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm1250_ev1 = { .idle_bias_off = true, }; -static int __devinit wm1250_ev1_pdata(struct i2c_client *i2c) +static int wm1250_ev1_pdata(struct i2c_client *i2c) { struct wm1250_ev1_pdata *pdata = dev_get_platdata(&i2c->dev); struct wm1250_priv *wm1250; @@ -199,8 +199,8 @@ static void wm1250_ev1_free(struct i2c_client *i2c) gpio_free_array(wm1250->gpios, ARRAY_SIZE(wm1250->gpios)); } -static int __devinit wm1250_ev1_probe(struct i2c_client *i2c, - const struct i2c_device_id *i2c_id) +static int wm1250_ev1_probe(struct i2c_client *i2c, + const struct i2c_device_id *i2c_id) { int id, board, rev, ret; @@ -237,7 +237,7 @@ static int __devinit wm1250_ev1_probe(struct i2c_client *i2c, return 0; } -static int __devexit wm1250_ev1_remove(struct i2c_client *i2c) +static int wm1250_ev1_remove(struct i2c_client *i2c) { snd_soc_unregister_codec(&i2c->dev); wm1250_ev1_free(i2c); @@ -257,7 +257,7 @@ static struct i2c_driver wm1250_ev1_i2c_driver = { .owner = THIS_MODULE, }, .probe = wm1250_ev1_probe, - .remove = __devexit_p(wm1250_ev1_remove), + .remove = wm1250_ev1_remove, .id_table = wm1250_ev1_i2c_id, }; diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index 683dc43b1d8..1cbe88f01d6 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[] = { static int wm2000_anc_power_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = w->codec; struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); if (SND_SOC_DAPM_EVENT_ON(event)) @@ -764,8 +764,8 @@ static struct snd_soc_codec_driver soc_codec_dev_wm2000 = { .num_controls = ARRAY_SIZE(wm2000_controls), }; -static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *i2c_id) +static int wm2000_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *i2c_id) { struct wm2000_priv *wm2000; struct wm2000_platform_data *pdata; @@ -871,7 +871,7 @@ out: return ret; } -static __devexit int wm2000_i2c_remove(struct i2c_client *i2c) +static int wm2000_i2c_remove(struct i2c_client *i2c) { snd_soc_unregister_codec(&i2c->dev); @@ -890,7 +890,7 @@ static struct i2c_driver wm2000_i2c_driver = { .owner = THIS_MODULE, }, .probe = wm2000_i2c_probe, - .remove = __devexit_p(wm2000_i2c_remove), + .remove = wm2000_i2c_remove, .id_table = wm2000_i2c_id, }; diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c index eab64a19398..afcf31df77e 100644 --- a/sound/soc/codecs/wm2200.c +++ b/sound/soc/codecs/wm2200.c @@ -15,6 +15,7 @@ #include <linux/init.h> #include <linux/delay.h> #include <linux/pm.h> +#include <linux/firmware.h> #include <linux/gcd.h> #include <linux/gpio.h> #include <linux/i2c.h> @@ -32,6 +33,40 @@ #include <sound/wm2200.h> #include "wm2200.h" +#include "wmfw.h" +#include "wm_adsp.h" + +#define WM2200_DSP_CONTROL_1 0x00 +#define WM2200_DSP_CONTROL_2 0x02 +#define WM2200_DSP_CONTROL_3 0x03 +#define WM2200_DSP_CONTROL_4 0x04 +#define WM2200_DSP_CONTROL_5 0x06 +#define WM2200_DSP_CONTROL_6 0x07 +#define WM2200_DSP_CONTROL_7 0x08 +#define WM2200_DSP_CONTROL_8 0x09 +#define WM2200_DSP_CONTROL_9 0x0A +#define WM2200_DSP_CONTROL_10 0x0B +#define WM2200_DSP_CONTROL_11 0x0C +#define WM2200_DSP_CONTROL_12 0x0D +#define WM2200_DSP_CONTROL_13 0x0F +#define WM2200_DSP_CONTROL_14 0x10 +#define WM2200_DSP_CONTROL_15 0x11 +#define WM2200_DSP_CONTROL_16 0x12 +#define WM2200_DSP_CONTROL_17 0x13 +#define WM2200_DSP_CONTROL_18 0x14 +#define WM2200_DSP_CONTROL_19 0x16 +#define WM2200_DSP_CONTROL_20 0x17 +#define WM2200_DSP_CONTROL_21 0x18 +#define WM2200_DSP_CONTROL_22 0x1A +#define WM2200_DSP_CONTROL_23 0x1B +#define WM2200_DSP_CONTROL_24 0x1C +#define WM2200_DSP_CONTROL_25 0x1E +#define WM2200_DSP_CONTROL_26 0x20 +#define WM2200_DSP_CONTROL_27 0x21 +#define WM2200_DSP_CONTROL_28 0x22 +#define WM2200_DSP_CONTROL_29 0x23 +#define WM2200_DSP_CONTROL_30 0x24 +#define WM2200_DSP_CONTROL_31 0x26 /* The code assumes DCVDD is generated internally */ #define WM2200_NUM_CORE_SUPPLIES 2 @@ -49,6 +84,7 @@ struct wm2200_fll { /* codec private data */ struct wm2200_priv { + struct wm_adsp dsp[2]; struct regmap *regmap; struct device *dev; struct snd_soc_codec *codec; @@ -64,6 +100,72 @@ struct wm2200_priv { int sysclk; }; +#define WM2200_DSP_RANGE_BASE (WM2200_MAX_REGISTER + 1) +#define WM2200_DSP_SPACING 12288 + +#define WM2200_DSP1_DM_BASE (WM2200_DSP_RANGE_BASE + (0 * WM2200_DSP_SPACING)) +#define WM2200_DSP1_PM_BASE (WM2200_DSP_RANGE_BASE + (1 * WM2200_DSP_SPACING)) +#define WM2200_DSP1_ZM_BASE (WM2200_DSP_RANGE_BASE + (2 * WM2200_DSP_SPACING)) +#define WM2200_DSP2_DM_BASE (WM2200_DSP_RANGE_BASE + (3 * WM2200_DSP_SPACING)) +#define WM2200_DSP2_PM_BASE (WM2200_DSP_RANGE_BASE + (4 * WM2200_DSP_SPACING)) +#define WM2200_DSP2_ZM_BASE (WM2200_DSP_RANGE_BASE + (5 * WM2200_DSP_SPACING)) + +static const struct regmap_range_cfg wm2200_ranges[] = { + { .name = "DSP1DM", .range_min = WM2200_DSP1_DM_BASE, + .range_max = WM2200_DSP1_DM_BASE + 12287, + .selector_reg = WM2200_DSP1_CONTROL_3, + .selector_mask = WM2200_DSP1_PAGE_BASE_DM_0_MASK, + .selector_shift = WM2200_DSP1_PAGE_BASE_DM_0_SHIFT, + .window_start = WM2200_DSP1_DM_0, .window_len = 2048, }, + + { .name = "DSP1PM", .range_min = WM2200_DSP1_PM_BASE, + .range_max = WM2200_DSP1_PM_BASE + 12287, + .selector_reg = WM2200_DSP1_CONTROL_2, + .selector_mask = WM2200_DSP1_PAGE_BASE_PM_0_MASK, + .selector_shift = WM2200_DSP1_PAGE_BASE_PM_0_SHIFT, + .window_start = WM2200_DSP1_PM_0, .window_len = 768, }, + + { .name = "DSP1ZM", .range_min = WM2200_DSP1_ZM_BASE, + .range_max = WM2200_DSP1_ZM_BASE + 2047, + .selector_reg = WM2200_DSP1_CONTROL_4, + .selector_mask = WM2200_DSP1_PAGE_BASE_ZM_0_MASK, + .selector_shift = WM2200_DSP1_PAGE_BASE_ZM_0_SHIFT, + .window_start = WM2200_DSP1_ZM_0, .window_len = 1024, }, + + { .name = "DSP2DM", .range_min = WM2200_DSP2_DM_BASE, + .range_max = WM2200_DSP2_DM_BASE + 4095, + .selector_reg = WM2200_DSP2_CONTROL_3, + .selector_mask = WM2200_DSP2_PAGE_BASE_DM_0_MASK, + .selector_shift = WM2200_DSP2_PAGE_BASE_DM_0_SHIFT, + .window_start = WM2200_DSP2_DM_0, .window_len = 2048, }, + + { .name = "DSP2PM", .range_min = WM2200_DSP2_PM_BASE, + .range_max = WM2200_DSP2_PM_BASE + 11287, + .selector_reg = WM2200_DSP2_CONTROL_2, + .selector_mask = WM2200_DSP2_PAGE_BASE_PM_0_MASK, + .selector_shift = WM2200_DSP2_PAGE_BASE_PM_0_SHIFT, + .window_start = WM2200_DSP2_PM_0, .window_len = 768, }, + + { .name = "DSP2ZM", .range_min = WM2200_DSP2_ZM_BASE, + .range_max = WM2200_DSP2_ZM_BASE + 2047, + .selector_reg = WM2200_DSP2_CONTROL_4, + .selector_mask = WM2200_DSP2_PAGE_BASE_ZM_0_MASK, + .selector_shift = WM2200_DSP2_PAGE_BASE_ZM_0_SHIFT, + .window_start = WM2200_DSP2_ZM_0, .window_len = 1024, }, +}; + +static const struct wm_adsp_region wm2200_dsp1_regions[] = { + { .type = WMFW_ADSP1_PM, .base = WM2200_DSP1_PM_BASE }, + { .type = WMFW_ADSP1_DM, .base = WM2200_DSP1_DM_BASE }, + { .type = WMFW_ADSP1_ZM, .base = WM2200_DSP1_ZM_BASE }, +}; + +static const struct wm_adsp_region wm2200_dsp2_regions[] = { + { .type = WMFW_ADSP1_PM, .base = WM2200_DSP2_PM_BASE }, + { .type = WMFW_ADSP1_DM, .base = WM2200_DSP2_DM_BASE }, + { .type = WMFW_ADSP1_ZM, .base = WM2200_DSP2_ZM_BASE }, +}; + static struct reg_default wm2200_reg_defaults[] = { { 0x000B, 0x0000 }, /* R11 - Tone Generator 1 */ { 0x0102, 0x0000 }, /* R258 - Clocking 3 */ @@ -407,6 +509,16 @@ static struct reg_default wm2200_reg_defaults[] = { static bool wm2200_volatile_register(struct device *dev, unsigned int reg) { + int i; + + for (i = 0; i < ARRAY_SIZE(wm2200_ranges); i++) + if ((reg >= wm2200_ranges[i].window_start && + reg <= wm2200_ranges[i].window_start + + wm2200_ranges[i].window_len) || + (reg >= wm2200_ranges[i].range_min && + reg <= wm2200_ranges[i].range_max)) + return true; + switch (reg) { case WM2200_SOFTWARE_RESET: case WM2200_DEVICE_REVISION: @@ -423,6 +535,16 @@ static bool wm2200_volatile_register(struct device *dev, unsigned int reg) static bool wm2200_readable_register(struct device *dev, unsigned int reg) { + int i; + + for (i = 0; i < ARRAY_SIZE(wm2200_ranges); i++) + if ((reg >= wm2200_ranges[i].window_start && + reg <= wm2200_ranges[i].window_start + + wm2200_ranges[i].window_len) || + (reg >= wm2200_ranges[i].range_min && + reg <= wm2200_ranges[i].range_max)) + return true; + switch (reg) { case WM2200_SOFTWARE_RESET: case WM2200_DEVICE_REVISION: @@ -880,7 +1002,7 @@ static DECLARE_TLV_DB_SCALE(out_tlv, -6400, 100, 0); static const char *wm2200_mixer_texts[] = { "None", "Tone Generator", - "AEC loopback", + "AEC Loopback", "IN1L", "IN1R", "IN2L", @@ -976,6 +1098,20 @@ static int wm2200_mixer_values[] = { static WM2200_MUX_CTL_DECL(name##_in3); \ static WM2200_MUX_CTL_DECL(name##_in4) +#define WM2200_DSP_ENUMS(name, base_reg) \ + static WM2200_MUX_ENUM_DECL(name##_aux1_enum, base_reg); \ + static WM2200_MUX_ENUM_DECL(name##_aux2_enum, base_reg + 1); \ + static WM2200_MUX_ENUM_DECL(name##_aux3_enum, base_reg + 2); \ + static WM2200_MUX_ENUM_DECL(name##_aux4_enum, base_reg + 3); \ + static WM2200_MUX_ENUM_DECL(name##_aux5_enum, base_reg + 4); \ + static WM2200_MUX_ENUM_DECL(name##_aux6_enum, base_reg + 5); \ + static WM2200_MUX_CTL_DECL(name##_aux1); \ + static WM2200_MUX_CTL_DECL(name##_aux2); \ + static WM2200_MUX_CTL_DECL(name##_aux3); \ + static WM2200_MUX_CTL_DECL(name##_aux4); \ + static WM2200_MUX_CTL_DECL(name##_aux5); \ + static WM2200_MUX_CTL_DECL(name##_aux6); + static const struct snd_kcontrol_new wm2200_snd_controls[] = { SOC_SINGLE("IN1 High Performance Switch", WM2200_IN1L_CONTROL, WM2200_IN1_OSR_SHIFT, 1, 0), @@ -1051,6 +1187,9 @@ WM2200_MIXER_ENUMS(DSP1R, WM2200_DSP1RMIX_INPUT_1_SOURCE); WM2200_MIXER_ENUMS(DSP2L, WM2200_DSP2LMIX_INPUT_1_SOURCE); WM2200_MIXER_ENUMS(DSP2R, WM2200_DSP2RMIX_INPUT_1_SOURCE); +WM2200_DSP_ENUMS(DSP1, WM2200_DSP1AUX1MIX_INPUT_1_SOURCE); +WM2200_DSP_ENUMS(DSP2, WM2200_DSP2AUX1MIX_INPUT_1_SOURCE); + WM2200_MIXER_ENUMS(LHPF1, WM2200_LHPF1MIX_INPUT_1_SOURCE); WM2200_MIXER_ENUMS(LHPF2, WM2200_LHPF2MIX_INPUT_1_SOURCE); @@ -1064,8 +1203,19 @@ WM2200_MIXER_ENUMS(LHPF2, WM2200_LHPF2MIX_INPUT_1_SOURCE); WM2200_MUX(name_str " Input 4", &name##_in4_mux), \ SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0) +#define WM2200_DSP_WIDGETS(name, name_str) \ + WM2200_MIXER_WIDGETS(name##L, name_str "L"), \ + WM2200_MIXER_WIDGETS(name##R, name_str "R"), \ + WM2200_MUX(name_str " Aux 1", &name##_aux1_mux), \ + WM2200_MUX(name_str " Aux 2", &name##_aux2_mux), \ + WM2200_MUX(name_str " Aux 3", &name##_aux3_mux), \ + WM2200_MUX(name_str " Aux 4", &name##_aux4_mux), \ + WM2200_MUX(name_str " Aux 5", &name##_aux5_mux), \ + WM2200_MUX(name_str " Aux 6", &name##_aux6_mux) + #define WM2200_MIXER_INPUT_ROUTES(name) \ { name, "Tone Generator", "Tone Generator" }, \ + { name, "AEC Loopback", "AEC Loopback" }, \ { name, "IN1L", "IN1L PGA" }, \ { name, "IN1R", "IN1R PGA" }, \ { name, "IN2L", "IN2L PGA" }, \ @@ -1106,6 +1256,33 @@ WM2200_MIXER_ENUMS(LHPF2, WM2200_LHPF2MIX_INPUT_1_SOURCE); WM2200_MIXER_INPUT_ROUTES(name " Input 3"), \ WM2200_MIXER_INPUT_ROUTES(name " Input 4") +#define WM2200_DSP_AUX_ROUTES(name) \ + { name, NULL, name " Aux 1" }, \ + { name, NULL, name " Aux 2" }, \ + { name, NULL, name " Aux 3" }, \ + { name, NULL, name " Aux 4" }, \ + { name, NULL, name " Aux 5" }, \ + { name, NULL, name " Aux 6" }, \ + WM2200_MIXER_INPUT_ROUTES(name " Aux 1"), \ + WM2200_MIXER_INPUT_ROUTES(name " Aux 2"), \ + WM2200_MIXER_INPUT_ROUTES(name " Aux 3"), \ + WM2200_MIXER_INPUT_ROUTES(name " Aux 4"), \ + WM2200_MIXER_INPUT_ROUTES(name " Aux 5"), \ + WM2200_MIXER_INPUT_ROUTES(name " Aux 6") + +static const char *wm2200_aec_loopback_texts[] = { + "OUT1L", "OUT1R", "OUT2L", "OUT2R", +}; + +static const struct soc_enum wm2200_aec_loopback = + SOC_ENUM_SINGLE(WM2200_DAC_AEC_CONTROL_1, + WM2200_AEC_LOOPBACK_SRC_SHIFT, + ARRAY_SIZE(wm2200_aec_loopback_texts), + wm2200_aec_loopback_texts); + +static const struct snd_kcontrol_new wm2200_aec_loopback_mux = + SOC_DAPM_ENUM("AEC Loopback", wm2200_aec_loopback); + static const struct snd_soc_dapm_widget wm2200_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("SYSCLK", WM2200_CLOCKING_3, WM2200_SYSCLK_ENA_SHIFT, 0, NULL, 0), @@ -1165,8 +1342,8 @@ SND_SOC_DAPM_PGA("LHPF1", WM2200_HPLPF1_1, WM2200_LHPF1_ENA_SHIFT, 0, SND_SOC_DAPM_PGA("LHPF2", WM2200_HPLPF2_1, WM2200_LHPF2_ENA_SHIFT, 0, NULL, 0), -SND_SOC_DAPM_PGA_E("DSP1", SND_SOC_NOPM, 0, 0, NULL, 0, NULL, 0), -SND_SOC_DAPM_PGA_E("DSP2", SND_SOC_NOPM, 1, 0, NULL, 0, NULL, 0), +WM_ADSP1("DSP1", 0), +WM_ADSP1("DSP2", 1), SND_SOC_DAPM_AIF_OUT("AIF1TX1", "Capture", 0, WM2200_AUDIO_IF_1_22, WM2200_AIF1TX1_ENA_SHIFT, 0), @@ -1181,6 +1358,9 @@ SND_SOC_DAPM_AIF_OUT("AIF1TX5", "Capture", 4, SND_SOC_DAPM_AIF_OUT("AIF1TX6", "Capture", 5, WM2200_AUDIO_IF_1_22, WM2200_AIF1TX6_ENA_SHIFT, 0), +SND_SOC_DAPM_MUX("AEC Loopback", WM2200_DAC_AEC_CONTROL_1, + WM2200_AEC_LOOPBACK_ENA_SHIFT, 0, &wm2200_aec_loopback_mux), + SND_SOC_DAPM_PGA_S("OUT1L", 0, WM2200_OUTPUT_ENABLES, WM2200_OUT1L_ENA_SHIFT, 0, NULL, 0), SND_SOC_DAPM_PGA_S("OUT1R", 0, WM2200_OUTPUT_ENABLES, @@ -1231,10 +1411,8 @@ WM2200_MIXER_WIDGETS(EQR, "EQR"), WM2200_MIXER_WIDGETS(LHPF1, "LHPF1"), WM2200_MIXER_WIDGETS(LHPF2, "LHPF2"), -WM2200_MIXER_WIDGETS(DSP1L, "DSP1L"), -WM2200_MIXER_WIDGETS(DSP1R, "DSP1R"), -WM2200_MIXER_WIDGETS(DSP2L, "DSP2L"), -WM2200_MIXER_WIDGETS(DSP2R, "DSP2R"), +WM2200_DSP_WIDGETS(DSP1, "DSP1"), +WM2200_DSP_WIDGETS(DSP2, "DSP2"), WM2200_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"), WM2200_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"), @@ -1326,11 +1504,19 @@ static const struct snd_soc_dapm_route wm2200_dapm_routes[] = { { "SPK", NULL, "OUT2L" }, { "SPK", NULL, "OUT2R" }, + { "AEC Loopback", "OUT1L", "OUT1L" }, + { "AEC Loopback", "OUT1R", "OUT1R" }, + { "AEC Loopback", "OUT2L", "OUT2L" }, + { "AEC Loopback", "OUT2R", "OUT2R" }, + WM2200_MIXER_ROUTES("DSP1", "DSP1L"), WM2200_MIXER_ROUTES("DSP1", "DSP1R"), WM2200_MIXER_ROUTES("DSP2", "DSP2L"), WM2200_MIXER_ROUTES("DSP2", "DSP2R"), + WM2200_DSP_AUX_ROUTES("DSP1"), + WM2200_DSP_AUX_ROUTES("DSP2"), + WM2200_MIXER_ROUTES("OUT1L", "OUT1L"), WM2200_MIXER_ROUTES("OUT1R", "OUT1R"), WM2200_MIXER_ROUTES("OUT2L", "OUT2L"), @@ -1968,12 +2154,15 @@ static const struct regmap_config wm2200_regmap = { .reg_bits = 16, .val_bits = 16, - .max_register = WM2200_MAX_REGISTER, + .max_register = WM2200_MAX_REGISTER + (ARRAY_SIZE(wm2200_ranges) * + WM2200_DSP_SPACING), .reg_defaults = wm2200_reg_defaults, .num_reg_defaults = ARRAY_SIZE(wm2200_reg_defaults), .volatile_reg = wm2200_volatile_register, .readable_reg = wm2200_readable_register, .cache_type = REGCACHE_RBTREE, + .ranges = wm2200_ranges, + .num_ranges = ARRAY_SIZE(wm2200_ranges), }; static const unsigned int wm2200_dig_vu[] = { @@ -1995,8 +2184,8 @@ static const unsigned int wm2200_mic_ctrl_reg[] = { WM2200_IN3L_CONTROL, }; -static __devinit int wm2200_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm2200_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm2200_pdata *pdata = dev_get_platdata(&i2c->dev); struct wm2200_priv *wm2200; @@ -2011,14 +2200,30 @@ static __devinit int wm2200_i2c_probe(struct i2c_client *i2c, wm2200->dev = &i2c->dev; init_completion(&wm2200->fll_lock); - wm2200->regmap = regmap_init_i2c(i2c, &wm2200_regmap); + wm2200->regmap = devm_regmap_init_i2c(i2c, &wm2200_regmap); if (IS_ERR(wm2200->regmap)) { ret = PTR_ERR(wm2200->regmap); dev_err(&i2c->dev, "Failed to allocate register map: %d\n", ret); - goto err; + return ret; + } + + for (i = 0; i < 2; i++) { + wm2200->dsp[i].type = WMFW_ADSP1; + wm2200->dsp[i].part = "wm2200"; + wm2200->dsp[i].num = i + 1; + wm2200->dsp[i].dev = &i2c->dev; + wm2200->dsp[i].regmap = wm2200->regmap; } + wm2200->dsp[0].base = WM2200_DSP1_CONTROL_1; + wm2200->dsp[0].mem = wm2200_dsp1_regions; + wm2200->dsp[0].num_mems = ARRAY_SIZE(wm2200_dsp1_regions); + + wm2200->dsp[1].base = WM2200_DSP2_CONTROL_1; + wm2200->dsp[1].mem = wm2200_dsp2_regions; + wm2200->dsp[1].num_mems = ARRAY_SIZE(wm2200_dsp2_regions); + if (pdata) wm2200->pdata = *pdata; @@ -2027,12 +2232,13 @@ static __devinit int wm2200_i2c_probe(struct i2c_client *i2c, for (i = 0; i < ARRAY_SIZE(wm2200->core_supplies); i++) wm2200->core_supplies[i].supply = wm2200_core_supply_names[i]; - ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm2200->core_supplies), - wm2200->core_supplies); + ret = devm_regulator_bulk_get(&i2c->dev, + ARRAY_SIZE(wm2200->core_supplies), + wm2200->core_supplies); if (ret != 0) { dev_err(&i2c->dev, "Failed to request core supplies: %d\n", ret); - goto err_regmap; + return ret; } ret = regulator_bulk_enable(ARRAY_SIZE(wm2200->core_supplies), @@ -2040,12 +2246,13 @@ static __devinit int wm2200_i2c_probe(struct i2c_client *i2c, if (ret != 0) { dev_err(&i2c->dev, "Failed to enable core supplies: %d\n", ret); - goto err_core; + return ret; } if (wm2200->pdata.ldo_ena) { - ret = gpio_request_one(wm2200->pdata.ldo_ena, - GPIOF_OUT_INIT_HIGH, "WM2200 LDOENA"); + ret = devm_gpio_request_one(&i2c->dev, wm2200->pdata.ldo_ena, + GPIOF_OUT_INIT_HIGH, + "WM2200 LDOENA"); if (ret < 0) { dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n", wm2200->pdata.ldo_ena, ret); @@ -2055,8 +2262,9 @@ static __devinit int wm2200_i2c_probe(struct i2c_client *i2c, } if (wm2200->pdata.reset) { - ret = gpio_request_one(wm2200->pdata.reset, - GPIOF_OUT_INIT_HIGH, "WM2200 /RESET"); + ret = devm_gpio_request_one(&i2c->dev, wm2200->pdata.reset, + GPIOF_OUT_INIT_HIGH, + "WM2200 /RESET"); if (ret < 0) { dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n", wm2200->pdata.reset, ret); @@ -2166,45 +2374,28 @@ static __devinit int wm2200_i2c_probe(struct i2c_client *i2c, err_pm_runtime: pm_runtime_disable(&i2c->dev); err_reset: - if (wm2200->pdata.reset) { + if (wm2200->pdata.reset) gpio_set_value_cansleep(wm2200->pdata.reset, 0); - gpio_free(wm2200->pdata.reset); - } err_ldo: - if (wm2200->pdata.ldo_ena) { + if (wm2200->pdata.ldo_ena) gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0); - gpio_free(wm2200->pdata.ldo_ena); - } err_enable: regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies), wm2200->core_supplies); -err_core: - regulator_bulk_free(ARRAY_SIZE(wm2200->core_supplies), - wm2200->core_supplies); -err_regmap: - regmap_exit(wm2200->regmap); -err: return ret; } -static __devexit int wm2200_i2c_remove(struct i2c_client *i2c) +static int wm2200_i2c_remove(struct i2c_client *i2c) { struct wm2200_priv *wm2200 = i2c_get_clientdata(i2c); snd_soc_unregister_codec(&i2c->dev); if (i2c->irq) free_irq(i2c->irq, wm2200); - if (wm2200->pdata.reset) { + if (wm2200->pdata.reset) gpio_set_value_cansleep(wm2200->pdata.reset, 0); - gpio_free(wm2200->pdata.reset); - } - if (wm2200->pdata.ldo_ena) { + if (wm2200->pdata.ldo_ena) gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0); - gpio_free(wm2200->pdata.ldo_ena); - } - regulator_bulk_free(ARRAY_SIZE(wm2200->core_supplies), - wm2200->core_supplies); - regmap_exit(wm2200->regmap); return 0; } @@ -2267,7 +2458,7 @@ static struct i2c_driver wm2200_i2c_driver = { .pm = &wm2200_pm, }, .probe = wm2200_i2c_probe, - .remove = __devexit_p(wm2200_i2c_remove), + .remove = wm2200_i2c_remove, .id_table = wm2200_i2c_id, }; diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index 7f567585832..5a5f3693623 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[] = { { "PWM2", NULL, "PWM2 Driver" }, }; -static const __devinitconst struct reg_default wm5100_reva_patches[] = { +static const struct reg_default wm5100_reva_patches[] = { { WM5100_AUDIO_IF_1_10, 0 }, { WM5100_AUDIO_IF_1_11, 1 }, { WM5100_AUDIO_IF_1_12, 2 }, @@ -2414,8 +2414,8 @@ static const unsigned int wm5100_mic_ctrl_reg[] = { WM5100_IN4L_CONTROL, }; -static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm5100_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm5100_pdata *pdata = dev_get_platdata(&i2c->dev); struct wm5100_priv *wm5100; @@ -2639,7 +2639,7 @@ err: return ret; } -static __devexit int wm5100_i2c_remove(struct i2c_client *i2c) +static int wm5100_i2c_remove(struct i2c_client *i2c) { struct wm5100_priv *wm5100 = i2c_get_clientdata(i2c); @@ -2717,7 +2717,7 @@ static struct i2c_driver wm5100_i2c_driver = { .pm = &wm5100_pm, }, .probe = wm5100_i2c_probe, - .remove = __devexit_p(wm5100_i2c_remove), + .remove = wm5100_i2c_remove, .id_table = wm5100_i2c_id, }; diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 7394e73fa43..688ade08058 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -31,6 +31,7 @@ #include "arizona.h" #include "wm5102.h" +#include "wm_adsp.h" struct wm5102_priv { struct arizona_priv core; @@ -42,6 +43,13 @@ static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0); static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0); +static const struct wm_adsp_region wm5102_dsp1_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x100000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x180000 }, + { .type = WMFW_ADSP2_XM, .base = 0x190000 }, + { .type = WMFW_ADSP2_YM, .base = 0x1a8000 }, +}; + static const struct reg_default wm5102_sysclk_reva_patch[] = { { 0x3000, 0x2225 }, { 0x3001, 0x3a03 }, @@ -627,11 +635,23 @@ SOC_DOUBLE_R_TLV("IN3 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_3L, ARIZONA_ADC_DIGITAL_VOLUME_3R, ARIZONA_IN3L_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv), +SOC_ENUM("Input Ramp Up", arizona_in_vi_ramp), +SOC_ENUM("Input Ramp Down", arizona_in_vd_ramp), + ARIZONA_MIXER_CONTROLS("EQ1", ARIZONA_EQ1MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE), +SND_SOC_BYTES_MASK("EQ1 Coefficeints", ARIZONA_EQ1_1, 21, + ARIZONA_EQ1_ENA_MASK), +SND_SOC_BYTES_MASK("EQ2 Coefficeints", ARIZONA_EQ2_1, 21, + ARIZONA_EQ2_ENA_MASK), +SND_SOC_BYTES_MASK("EQ3 Coefficeints", ARIZONA_EQ3_1, 21, + ARIZONA_EQ3_ENA_MASK), +SND_SOC_BYTES_MASK("EQ4 Coefficeints", ARIZONA_EQ4_1, 21, + ARIZONA_EQ4_ENA_MASK), + SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT, 24, 0, eq_tlv), SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT, @@ -687,6 +707,14 @@ ARIZONA_MIXER_CONTROLS("LHPF2", ARIZONA_HPLP2MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("LHPF3", ARIZONA_HPLP3MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("LHPF4", ARIZONA_HPLP4MIX_INPUT_1_SOURCE), +SND_SOC_BYTES("LHPF1 Coefficients", ARIZONA_HPLPF1_2, 1), +SND_SOC_BYTES("LHPF2 Coefficients", ARIZONA_HPLPF2_2, 1), +SND_SOC_BYTES("LHPF3 Coefficients", ARIZONA_HPLPF3_2, 1), +SND_SOC_BYTES("LHPF4 Coefficients", ARIZONA_HPLPF4_2, 1), + +ARIZONA_MIXER_CONTROLS("DSP1L", ARIZONA_DSP1LMIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("DSP1R", ARIZONA_DSP1RMIX_INPUT_1_SOURCE), + SOC_ENUM("LHPF1 Mode", arizona_lhpf1_mode), SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode), SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), @@ -708,14 +736,6 @@ ARIZONA_MIXER_CONTROLS("SPKOUTR", ARIZONA_OUT4RMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE), -SOC_SINGLE("HPOUT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_1L, - ARIZONA_OUT1_OSR_SHIFT, 1, 0), -SOC_SINGLE("OUT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_2L, - ARIZONA_OUT2_OSR_SHIFT, 1, 0), -SOC_SINGLE("EPOUT High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_3L, - ARIZONA_OUT3_OSR_SHIFT, 1, 0), -SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L, - ARIZONA_OUT4_OSR_SHIFT, 1, 0), SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L, ARIZONA_OUT5_OSR_SHIFT, 1, 0), @@ -745,16 +765,8 @@ SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L, ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT, 0xbf, 0, digital_tlv), -SOC_DOUBLE_R_RANGE_TLV("HPOUT1 Volume", ARIZONA_OUTPUT_PATH_CONFIG_1L, - ARIZONA_OUTPUT_PATH_CONFIG_1R, - ARIZONA_OUT1L_PGA_VOL_SHIFT, - 0x34, 0x40, 0, ana_tlv), -SOC_DOUBLE_R_RANGE_TLV("OUT2 Volume", ARIZONA_OUTPUT_PATH_CONFIG_2L, - ARIZONA_OUTPUT_PATH_CONFIG_2R, - ARIZONA_OUT2L_PGA_VOL_SHIFT, - 0x34, 0x40, 0, ana_tlv), -SOC_SINGLE_RANGE_TLV("EPOUT Volume", ARIZONA_OUTPUT_PATH_CONFIG_3L, - ARIZONA_OUT3L_PGA_VOL_SHIFT, 0x34, 0x40, 0, ana_tlv), +SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp), +SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp), SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT, ARIZONA_SPK1R_MUTE_SHIFT, 1, 1), @@ -819,11 +831,15 @@ ARIZONA_MIXER_ENUMS(AIF2TX2, ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE); ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE); ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE); -ARIZONA_MIXER_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE); -ARIZONA_MIXER_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE); -ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); -ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); + +ARIZONA_MIXER_ENUMS(DSP1L, ARIZONA_DSP1LMIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(DSP1R, ARIZONA_DSP1RMIX_INPUT_1_SOURCE); +ARIZONA_DSP_AUX_ENUMS(DSP1, ARIZONA_DSP1AUX1MIX_INPUT_1_SOURCE); static const char *wm5102_aec_loopback_texts[] = { "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "EPOUT", @@ -864,6 +880,7 @@ SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0, 0), SND_SOC_DAPM_SIGGEN("TONE"), SND_SOC_DAPM_SIGGEN("NOISE"), +SND_SOC_DAPM_SIGGEN("HAPTICS"), SND_SOC_DAPM_INPUT("IN1L"), SND_SOC_DAPM_INPUT("IN1R"), @@ -894,9 +911,9 @@ SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT, SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1, ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("MICBIAS2", ARIZONA_MIC_BIAS_CTRL_2, - ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), + ARIZONA_MICB2_ENA_SHIFT, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("MICBIAS3", ARIZONA_MIC_BIAS_CTRL_3, - ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), + ARIZONA_MICB3_ENA_SHIFT, 0, NULL, 0), SND_SOC_DAPM_PGA("Noise Generator", ARIZONA_COMFORT_NOISE_GENERATOR, ARIZONA_NOISE_GEN_ENA_SHIFT, 0, NULL, 0), @@ -996,6 +1013,8 @@ SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0, SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0, ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0), +ARIZONA_DSP_WIDGETS(DSP1, "DSP1"), + SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5102_aec_loopback_mux), @@ -1071,10 +1090,12 @@ ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"), ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"), ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"), -ARIZONA_MIXER_WIDGETS(ASRC1L, "ASRC1L"), -ARIZONA_MIXER_WIDGETS(ASRC1R, "ASRC1R"), -ARIZONA_MIXER_WIDGETS(ASRC2L, "ASRC2L"), -ARIZONA_MIXER_WIDGETS(ASRC2R, "ASRC2R"), +ARIZONA_MUX_WIDGETS(ASRC1L, "ASRC1L"), +ARIZONA_MUX_WIDGETS(ASRC1R, "ASRC1R"), +ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"), +ARIZONA_MUX_WIDGETS(ASRC2R, "ASRC2R"), + +WM_ADSP2("DSP1", 0), SND_SOC_DAPM_OUTPUT("HPOUT1L"), SND_SOC_DAPM_OUTPUT("HPOUT1R"), @@ -1094,6 +1115,7 @@ SND_SOC_DAPM_OUTPUT("SPKDAT1R"), { name, "Noise Generator", "Noise Generator" }, \ { name, "Tone Generator 1", "Tone Generator 1" }, \ { name, "Tone Generator 2", "Tone Generator 2" }, \ + { name, "Haptics", "HAPTICS" }, \ { name, "AEC", "AEC Loopback" }, \ { name, "IN1L", "IN1L PGA" }, \ { name, "IN1R", "IN1R PGA" }, \ @@ -1127,7 +1149,13 @@ SND_SOC_DAPM_OUTPUT("SPKDAT1R"), { name, "ASRC1L", "ASRC1L" }, \ { name, "ASRC1R", "ASRC1R" }, \ { name, "ASRC2L", "ASRC2L" }, \ - { name, "ASRC2R", "ASRC2R" } + { name, "ASRC2R", "ASRC2R" }, \ + { name, "DSP1.1", "DSP1" }, \ + { name, "DSP1.2", "DSP1" }, \ + { name, "DSP1.3", "DSP1" }, \ + { name, "DSP1.4", "DSP1" }, \ + { name, "DSP1.5", "DSP1" }, \ + { name, "DSP1.6", "DSP1" } static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { { "AIF2 Capture", NULL, "DBVDD2" }, @@ -1213,6 +1241,11 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { { "IN3L PGA", NULL, "IN3L" }, { "IN3R PGA", NULL, "IN3R" }, + { "ASRC1L", NULL, "ASRC1L Input" }, + { "ASRC1R", NULL, "ASRC1R Input" }, + { "ASRC2L", NULL, "ASRC2L Input" }, + { "ASRC2R", NULL, "ASRC2R Input" }, + ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"), ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"), ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"), @@ -1255,10 +1288,12 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"), ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"), - ARIZONA_MIXER_ROUTES("ASRC1L", "ASRC1L"), - ARIZONA_MIXER_ROUTES("ASRC1R", "ASRC1R"), - ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"), - ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"), + ARIZONA_MUX_ROUTES("ASRC1L"), + ARIZONA_MUX_ROUTES("ASRC1R"), + ARIZONA_MUX_ROUTES("ASRC2L"), + ARIZONA_MUX_ROUTES("ASRC2R"), + + ARIZONA_DSP_ROUTES("DSP1"), { "AEC Loopback", "HPOUT1L", "OUT1L" }, { "AEC Loopback", "HPOUT1R", "OUT1R" }, @@ -1377,9 +1412,28 @@ static struct snd_soc_dai_driver wm5102_dai[] = { static int wm5102_codec_probe(struct snd_soc_codec *codec) { struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); + int ret; codec->control_data = priv->core.arizona->regmap; - return snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP); + + ret = snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP); + if (ret != 0) + return ret; + + snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS"); + + priv->core.arizona->dapm = &codec->dapm; + + return 0; +} + +static int wm5102_codec_remove(struct snd_soc_codec *codec) +{ + struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); + + priv->core.arizona->dapm = NULL; + + return 0; } #define WM5102_DIG_VU 0x0200 @@ -1406,6 +1460,7 @@ static unsigned int wm5102_digital_vu[] = { static struct snd_soc_codec_driver soc_codec_dev_wm5102 = { .probe = wm5102_codec_probe, + .remove = wm5102_codec_remove, .idle_bias_off = true, @@ -1420,11 +1475,11 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5102 = { .num_dapm_routes = ARRAY_SIZE(wm5102_dapm_routes), }; -static int __devinit wm5102_probe(struct platform_device *pdev) +static int wm5102_probe(struct platform_device *pdev) { struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); struct wm5102_priv *wm5102; - int i; + int i, ret; wm5102 = devm_kzalloc(&pdev->dev, sizeof(struct wm5102_priv), GFP_KERNEL); @@ -1434,6 +1489,19 @@ static int __devinit wm5102_probe(struct platform_device *pdev) wm5102->core.arizona = arizona; + wm5102->core.adsp[0].part = "wm5102"; + wm5102->core.adsp[0].num = 1; + wm5102->core.adsp[0].type = WMFW_ADSP2; + wm5102->core.adsp[0].base = ARIZONA_DSP1_CONTROL_1; + wm5102->core.adsp[0].dev = arizona->dev; + wm5102->core.adsp[0].regmap = arizona->regmap; + wm5102->core.adsp[0].mem = wm5102_dsp1_regions; + wm5102->core.adsp[0].num_mems = ARRAY_SIZE(wm5102_dsp1_regions); + + ret = wm_adsp2_init(&wm5102->core.adsp[0], true); + if (ret != 0) + return ret; + for (i = 0; i < ARRAY_SIZE(wm5102->fll); i++) wm5102->fll[i].vco_mult = 1; @@ -1459,7 +1527,7 @@ static int __devinit wm5102_probe(struct platform_device *pdev) wm5102_dai, ARRAY_SIZE(wm5102_dai)); } -static int __devexit wm5102_remove(struct platform_device *pdev) +static int wm5102_remove(struct platform_device *pdev) { snd_soc_unregister_codec(&pdev->dev); pm_runtime_disable(&pdev->dev); @@ -1473,7 +1541,7 @@ static struct platform_driver wm5102_codec_driver = { .owner = THIS_MODULE, }, .probe = wm5102_probe, - .remove = __devexit_p(wm5102_remove), + .remove = wm5102_remove, }; module_platform_driver(wm5102_codec_driver); diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 9211e4192f7..ae80c8c2853 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -84,11 +84,23 @@ SOC_DOUBLE_R_TLV("IN4 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_4L, ARIZONA_ADC_DIGITAL_VOLUME_4R, ARIZONA_IN4L_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv), +SOC_ENUM("Input Ramp Up", arizona_in_vi_ramp), +SOC_ENUM("Input Ramp Down", arizona_in_vd_ramp), + ARIZONA_MIXER_CONTROLS("EQ1", ARIZONA_EQ1MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE), +SND_SOC_BYTES_MASK("EQ1 Coefficeints", ARIZONA_EQ1_1, 21, + ARIZONA_EQ1_ENA_MASK), +SND_SOC_BYTES_MASK("EQ2 Coefficeints", ARIZONA_EQ2_1, 21, + ARIZONA_EQ2_ENA_MASK), +SND_SOC_BYTES_MASK("EQ3 Coefficeints", ARIZONA_EQ3_1, 21, + ARIZONA_EQ3_ENA_MASK), +SND_SOC_BYTES_MASK("EQ4 Coefficeints", ARIZONA_EQ4_1, 21, + ARIZONA_EQ4_ENA_MASK), + SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT, 24, 0, eq_tlv), SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT, @@ -148,6 +160,11 @@ ARIZONA_MIXER_CONTROLS("LHPF2", ARIZONA_HPLP2MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("LHPF3", ARIZONA_HPLP3MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("LHPF4", ARIZONA_HPLP4MIX_INPUT_1_SOURCE), +SND_SOC_BYTES("LHPF1 Coefficients", ARIZONA_HPLPF1_2, 1), +SND_SOC_BYTES("LHPF2 Coefficients", ARIZONA_HPLPF2_2, 1), +SND_SOC_BYTES("LHPF3 Coefficients", ARIZONA_HPLPF3_2, 1), +SND_SOC_BYTES("LHPF4 Coefficients", ARIZONA_HPLPF4_2, 1), + SOC_ENUM("LHPF1 Mode", arizona_lhpf1_mode), SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode), SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), @@ -243,6 +260,9 @@ SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT, SOC_DOUBLE("SPKDAT2 Switch", ARIZONA_PDM_SPK2_CTRL_1, ARIZONA_SPK2L_MUTE_SHIFT, ARIZONA_SPK2R_MUTE_SHIFT, 1, 1), +SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp), +SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp), + ARIZONA_MIXER_CONTROLS("AIF1TX1", ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("AIF1TX2", ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("AIF1TX3", ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE), @@ -308,10 +328,10 @@ ARIZONA_MIXER_ENUMS(AIF2TX2, ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE); ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE); ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE); -ARIZONA_MIXER_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE); -ARIZONA_MIXER_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE); -ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); -ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); static const char *wm5110_aec_loopback_texts[] = { "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "HPOUT3L", "HPOUT3R", @@ -352,6 +372,7 @@ SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0, 0), SND_SOC_DAPM_SIGGEN("TONE"), SND_SOC_DAPM_SIGGEN("NOISE"), +SND_SOC_DAPM_SIGGEN("HAPTICS"), SND_SOC_DAPM_INPUT("IN1L"), SND_SOC_DAPM_INPUT("IN1R"), @@ -585,10 +606,10 @@ ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"), ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"), ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"), -ARIZONA_MIXER_WIDGETS(ASRC1L, "ASRC1L"), -ARIZONA_MIXER_WIDGETS(ASRC1R, "ASRC1R"), -ARIZONA_MIXER_WIDGETS(ASRC2L, "ASRC2L"), -ARIZONA_MIXER_WIDGETS(ASRC2R, "ASRC2R"), +ARIZONA_MUX_WIDGETS(ASRC1L, "ASRC1L"), +ARIZONA_MUX_WIDGETS(ASRC1R, "ASRC1R"), +ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"), +ARIZONA_MUX_WIDGETS(ASRC2R, "ASRC2R"), SND_SOC_DAPM_OUTPUT("HPOUT1L"), SND_SOC_DAPM_OUTPUT("HPOUT1R"), @@ -610,6 +631,7 @@ SND_SOC_DAPM_OUTPUT("SPKDAT2R"), { name, "Noise Generator", "Noise Generator" }, \ { name, "Tone Generator 1", "Tone Generator 1" }, \ { name, "Tone Generator 2", "Tone Generator 2" }, \ + { name, "Haptics", "HAPTICS" }, \ { name, "AEC", "AEC Loopback" }, \ { name, "IN1L", "IN1L PGA" }, \ { name, "IN1R", "IN1R PGA" }, \ @@ -786,10 +808,10 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = { ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"), ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"), - ARIZONA_MIXER_ROUTES("ASRC1L", "ASRC1L"), - ARIZONA_MIXER_ROUTES("ASRC1R", "ASRC1R"), - ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"), - ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"), + ARIZONA_MUX_ROUTES("ASRC1L"), + ARIZONA_MUX_ROUTES("ASRC1R"), + ARIZONA_MUX_ROUTES("ASRC2L"), + ARIZONA_MUX_ROUTES("ASRC2R"), { "HPOUT1L", NULL, "OUT1L" }, { "HPOUT1R", NULL, "OUT1R" }, @@ -902,9 +924,29 @@ static struct snd_soc_dai_driver wm5110_dai[] = { static int wm5110_codec_probe(struct snd_soc_codec *codec) { struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec); + int ret; codec->control_data = priv->core.arizona->regmap; - return snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP); + priv->core.arizona->dapm = &codec->dapm; + + ret = snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP); + if (ret != 0) + return ret; + + snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS"); + + priv->core.arizona->dapm = &codec->dapm; + + return 0; +} + +static int wm5110_codec_remove(struct snd_soc_codec *codec) +{ + struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec); + + priv->core.arizona->dapm = NULL; + + return 0; } #define WM5110_DIG_VU 0x0200 @@ -935,6 +977,7 @@ static unsigned int wm5110_digital_vu[] = { static struct snd_soc_codec_driver soc_codec_dev_wm5110 = { .probe = wm5110_codec_probe, + .remove = wm5110_codec_remove, .idle_bias_off = true, @@ -949,7 +992,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5110 = { .num_dapm_routes = ARRAY_SIZE(wm5110_dapm_routes), }; -static int __devinit wm5110_probe(struct platform_device *pdev) +static int wm5110_probe(struct platform_device *pdev) { struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); struct wm5110_priv *wm5110; @@ -988,7 +1031,7 @@ static int __devinit wm5110_probe(struct platform_device *pdev) wm5110_dai, ARRAY_SIZE(wm5110_dai)); } -static int __devexit wm5110_remove(struct platform_device *pdev) +static int wm5110_remove(struct platform_device *pdev) { snd_soc_unregister_codec(&pdev->dev); pm_runtime_disable(&pdev->dev); @@ -1002,7 +1045,7 @@ static struct platform_driver wm5110_codec_driver = { .owner = THIS_MODULE, }, .probe = wm5110_probe, - .remove = __devexit_p(wm5110_remove), + .remove = wm5110_remove, }; module_platform_driver(wm5110_codec_driver); diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index a4cae060bf2..fb92fb47d63 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) for (i = 0; i < ARRAY_SIZE(supply_names); i++) priv->supplies[i].supply = supply_names[i]; - ret = regulator_bulk_get(wm8350->dev, ARRAY_SIZE(priv->supplies), + ret = devm_regulator_bulk_get(wm8350->dev, ARRAY_SIZE(priv->supplies), priv->supplies); if (ret != 0) return ret; @@ -1607,8 +1607,6 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec) wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); - regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies); - return 0; } @@ -1627,13 +1625,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8350 = { .num_dapm_routes = ARRAY_SIZE(wm8350_dapm_routes), }; -static int __devinit wm8350_probe(struct platform_device *pdev) +static int wm8350_probe(struct platform_device *pdev) { return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8350, &wm8350_dai, 1); } -static int __devexit wm8350_remove(struct platform_device *pdev) +static int wm8350_remove(struct platform_device *pdev) { snd_soc_unregister_codec(&pdev->dev); return 0; @@ -1645,7 +1643,7 @@ static struct platform_driver wm8350_codec_driver = { .owner = THIS_MODULE, }, .probe = wm8350_probe, - .remove = __devexit_p(wm8350_remove), + .remove = wm8350_remove, }; module_platform_driver(wm8350_codec_driver); diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index 5d277a915f8..af6d227e67b 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) codec->control_data = priv->wm8400 = wm8400; priv->codec = codec; - ret = regulator_bulk_get(wm8400->dev, + ret = devm_regulator_bulk_get(wm8400->dev, ARRAY_SIZE(power), &power[0]); if (ret != 0) { 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) snd_soc_write(codec, WM8400_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); snd_soc_write(codec, WM8400_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); - if (!schedule_work(&priv->work)) { - ret = -EINVAL; - goto err_regulator; - } + if (!schedule_work(&priv->work)) + return -EINVAL; return 0; - -err_regulator: - regulator_bulk_free(ARRAY_SIZE(power), power); - return ret; } static int wm8400_codec_remove(struct snd_soc_codec *codec) @@ -1417,8 +1411,6 @@ static int wm8400_codec_remove(struct snd_soc_codec *codec) snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, reg & (~WM8400_CODEC_ENA)); - regulator_bulk_free(ARRAY_SIZE(power), power); - return 0; } @@ -1439,13 +1431,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8400 = { .num_dapm_routes = ARRAY_SIZE(wm8400_dapm_routes), }; -static int __devinit wm8400_probe(struct platform_device *pdev) +static int wm8400_probe(struct platform_device *pdev) { return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8400, &wm8400_dai, 1); } -static int __devexit wm8400_remove(struct platform_device *pdev) +static int wm8400_remove(struct platform_device *pdev) { snd_soc_unregister_codec(&pdev->dev); return 0; @@ -1457,7 +1449,7 @@ static struct platform_driver wm8400_codec_driver = { .owner = THIS_MODULE, }, .probe = wm8400_probe, - .remove = __devexit_p(wm8400_remove), + .remove = wm8400_remove, }; module_platform_driver(wm8400_codec_driver); diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index c12a54e72e8..6ed5433943e 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) /* power down chip */ static int wm8510_remove(struct snd_soc_codec *codec) { - struct wm8510_priv *wm8510 = snd_soc_codec_get_drvdata(codec); - wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF); - kfree(wm8510); return 0; } @@ -648,7 +645,7 @@ static const struct regmap_config wm8510_regmap = { }; #if defined(CONFIG_SPI_MASTER) -static int __devinit wm8510_spi_probe(struct spi_device *spi) +static int wm8510_spi_probe(struct spi_device *spi) { struct wm8510_priv *wm8510; int ret; @@ -670,7 +667,7 @@ static int __devinit wm8510_spi_probe(struct spi_device *spi) return ret; } -static int __devexit wm8510_spi_remove(struct spi_device *spi) +static int wm8510_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev); return 0; @@ -683,13 +680,13 @@ static struct spi_driver wm8510_spi_driver = { .of_match_table = wm8510_of_match, }, .probe = wm8510_spi_probe, - .remove = __devexit_p(wm8510_spi_remove), + .remove = wm8510_spi_remove, }; #endif /* CONFIG_SPI_MASTER */ #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static __devinit int wm8510_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8510_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8510_priv *wm8510; int ret; @@ -711,7 +708,7 @@ static __devinit int wm8510_i2c_probe(struct i2c_client *i2c, return ret; } -static __devexit int wm8510_i2c_remove(struct i2c_client *client) +static int wm8510_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -730,7 +727,7 @@ static struct i2c_driver wm8510_i2c_driver = { .of_match_table = wm8510_of_match, }, .probe = wm8510_i2c_probe, - .remove = __devexit_p(wm8510_i2c_remove), + .remove = wm8510_i2c_remove, .id_table = wm8510_i2c_id, }; #endif diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c index 8d5c2767350..139bf9ac940 100644 --- a/sound/soc/codecs/wm8523.c +++ b/sound/soc/codecs/wm8523.c @@ -453,8 +453,8 @@ static const struct regmap_config wm8523_regmap = { }; #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static __devinit int wm8523_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8523_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8523_priv *wm8523; unsigned int val; @@ -528,7 +528,7 @@ err_enable: return ret; } -static __devexit int wm8523_i2c_remove(struct i2c_client *client) +static int wm8523_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -547,7 +547,7 @@ static struct i2c_driver wm8523_i2c_driver = { .of_match_table = wm8523_of_match, }, .probe = wm8523_i2c_probe, - .remove = __devexit_p(wm8523_i2c_remove), + .remove = wm8523_i2c_remove, .id_table = wm8523_i2c_id, }; #endif diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c index 8b8bb70f1eb..5b428b060d4 100644 --- a/sound/soc/codecs/wm8711.c +++ b/sound/soc/codecs/wm8711.c @@ -429,7 +429,7 @@ static const struct regmap_config wm8711_regmap = { }; #if defined(CONFIG_SPI_MASTER) -static int __devinit wm8711_spi_probe(struct spi_device *spi) +static int wm8711_spi_probe(struct spi_device *spi) { struct wm8711_priv *wm8711; int ret; @@ -451,7 +451,7 @@ static int __devinit wm8711_spi_probe(struct spi_device *spi) return ret; } -static int __devexit wm8711_spi_remove(struct spi_device *spi) +static int wm8711_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev); @@ -465,13 +465,13 @@ static struct spi_driver wm8711_spi_driver = { .of_match_table = wm8711_of_match, }, .probe = wm8711_spi_probe, - .remove = __devexit_p(wm8711_spi_remove), + .remove = wm8711_spi_remove, }; #endif /* CONFIG_SPI_MASTER */ #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static __devinit int wm8711_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int wm8711_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) { struct wm8711_priv *wm8711; int ret; @@ -493,7 +493,7 @@ static __devinit int wm8711_i2c_probe(struct i2c_client *client, return ret; } -static __devexit int wm8711_i2c_remove(struct i2c_client *client) +static int wm8711_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -512,7 +512,7 @@ static struct i2c_driver wm8711_i2c_driver = { .of_match_table = wm8711_of_match, }, .probe = wm8711_i2c_probe, - .remove = __devexit_p(wm8711_i2c_remove), + .remove = wm8711_i2c_remove, .id_table = wm8711_i2c_id, }; #endif diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c index e8170562071..462f5e4d5c0 100644 --- a/sound/soc/codecs/wm8727.c +++ b/sound/soc/codecs/wm8727.c @@ -45,13 +45,13 @@ static struct snd_soc_dai_driver wm8727_dai = { static struct snd_soc_codec_driver soc_codec_dev_wm8727; -static __devinit int wm8727_probe(struct platform_device *pdev) +static int wm8727_probe(struct platform_device *pdev) { return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8727, &wm8727_dai, 1); } -static int __devexit wm8727_remove(struct platform_device *pdev) +static int wm8727_remove(struct platform_device *pdev) { snd_soc_unregister_codec(&pdev->dev); return 0; @@ -64,7 +64,7 @@ static struct platform_driver wm8727_codec_driver = { }, .probe = wm8727_probe, - .remove = __devexit_p(wm8727_remove), + .remove = wm8727_remove, }; module_platform_driver(wm8727_codec_driver); diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c index 00a12a0c391..c6a292dcded 100644 --- a/sound/soc/codecs/wm8728.c +++ b/sound/soc/codecs/wm8728.c @@ -280,7 +280,7 @@ static const struct regmap_config wm8728_regmap = { }; #if defined(CONFIG_SPI_MASTER) -static int __devinit wm8728_spi_probe(struct spi_device *spi) +static int wm8728_spi_probe(struct spi_device *spi) { struct wm8728_priv *wm8728; int ret; @@ -302,7 +302,7 @@ static int __devinit wm8728_spi_probe(struct spi_device *spi) return ret; } -static int __devexit wm8728_spi_remove(struct spi_device *spi) +static int wm8728_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev); @@ -316,13 +316,13 @@ static struct spi_driver wm8728_spi_driver = { .of_match_table = wm8728_of_match, }, .probe = wm8728_spi_probe, - .remove = __devexit_p(wm8728_spi_remove), + .remove = wm8728_spi_remove, }; #endif /* CONFIG_SPI_MASTER */ #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static __devinit int wm8728_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8728_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8728_priv *wm8728; int ret; @@ -344,7 +344,7 @@ static __devinit int wm8728_i2c_probe(struct i2c_client *i2c, return ret; } -static __devexit int wm8728_i2c_remove(struct i2c_client *client) +static int wm8728_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -363,7 +363,7 @@ static struct i2c_driver wm8728_i2c_driver = { .of_match_table = wm8728_of_match, }, .probe = wm8728_i2c_probe, - .remove = __devexit_p(wm8728_i2c_remove), + .remove = wm8728_i2c_remove, .id_table = wm8728_i2c_id, }; #endif diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index bb1d26919b1..5276062d6c7 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -631,7 +631,7 @@ static const struct regmap_config wm8731_regmap = { }; #if defined(CONFIG_SPI_MASTER) -static int __devinit wm8731_spi_probe(struct spi_device *spi) +static int wm8731_spi_probe(struct spi_device *spi) { struct wm8731_priv *wm8731; int ret; @@ -661,7 +661,7 @@ static int __devinit wm8731_spi_probe(struct spi_device *spi) return 0; } -static int __devexit wm8731_spi_remove(struct spi_device *spi) +static int wm8731_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev); return 0; @@ -674,13 +674,13 @@ static struct spi_driver wm8731_spi_driver = { .of_match_table = wm8731_of_match, }, .probe = wm8731_spi_probe, - .remove = __devexit_p(wm8731_spi_remove), + .remove = wm8731_spi_remove, }; #endif /* CONFIG_SPI_MASTER */ #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static __devinit int wm8731_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8731_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8731_priv *wm8731; int ret; @@ -710,7 +710,7 @@ static __devinit int wm8731_i2c_probe(struct i2c_client *i2c, return 0; } -static __devexit int wm8731_i2c_remove(struct i2c_client *client) +static int wm8731_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -729,7 +729,7 @@ static struct i2c_driver wm8731_i2c_driver = { .of_match_table = wm8731_of_match, }, .probe = wm8731_i2c_probe, - .remove = __devexit_p(wm8731_i2c_remove), + .remove = wm8731_i2c_remove, .id_table = wm8731_i2c_id, }; #endif diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c index 5c9634f4c1f..2f167a8ca01 100644 --- a/sound/soc/codecs/wm8737.c +++ b/sound/soc/codecs/wm8737.c @@ -645,8 +645,8 @@ static const struct regmap_config wm8737_regmap = { }; #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static __devinit int wm8737_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8737_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8737_priv *wm8737; int ret, i; @@ -679,7 +679,7 @@ static __devinit int wm8737_i2c_probe(struct i2c_client *i2c, } -static __devexit int wm8737_i2c_remove(struct i2c_client *client) +static int wm8737_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); @@ -699,13 +699,13 @@ static struct i2c_driver wm8737_i2c_driver = { .of_match_table = wm8737_of_match, }, .probe = wm8737_i2c_probe, - .remove = __devexit_p(wm8737_i2c_remove), + .remove = wm8737_i2c_remove, .id_table = wm8737_i2c_id, }; #endif #if defined(CONFIG_SPI_MASTER) -static int __devinit wm8737_spi_probe(struct spi_device *spi) +static int wm8737_spi_probe(struct spi_device *spi) { struct wm8737_priv *wm8737; int ret, i; @@ -737,7 +737,7 @@ static int __devinit wm8737_spi_probe(struct spi_device *spi) return ret; } -static int __devexit wm8737_spi_remove(struct spi_device *spi) +static int wm8737_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev); @@ -751,7 +751,7 @@ static struct spi_driver wm8737_spi_driver = { .of_match_table = wm8737_of_match, }, .probe = wm8737_spi_probe, - .remove = __devexit_p(wm8737_spi_remove), + .remove = wm8737_spi_remove, }; #endif /* CONFIG_SPI_MASTER */ diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c index 4281a080213..b18813cc7ba 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, return ret; } - wm8741->regmap = regmap_init_i2c(i2c, &wm8741_regmap); + wm8741->regmap = devm_regmap_init_i2c(i2c, &wm8741_regmap); if (IS_ERR(wm8741->regmap)) { ret = PTR_ERR(wm8741->regmap); dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret); @@ -562,7 +562,7 @@ static struct i2c_driver wm8741_i2c_driver = { #endif #if defined(CONFIG_SPI_MASTER) -static int __devinit wm8741_spi_probe(struct spi_device *spi) +static int wm8741_spi_probe(struct spi_device *spi) { struct wm8741_priv *wm8741; int ret, i; @@ -582,7 +582,7 @@ static int __devinit wm8741_spi_probe(struct spi_device *spi) return ret; } - wm8741->regmap = regmap_init_spi(spi, &wm8741_regmap); + wm8741->regmap = devm_regmap_init_spi(spi, &wm8741_regmap); if (IS_ERR(wm8741->regmap)) { ret = PTR_ERR(wm8741->regmap); dev_err(&spi->dev, "Failed to init regmap: %d\n", ret); @@ -596,7 +596,7 @@ static int __devinit wm8741_spi_probe(struct spi_device *spi) return ret; } -static int __devexit wm8741_spi_remove(struct spi_device *spi) +static int wm8741_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev); return 0; @@ -609,7 +609,7 @@ static struct spi_driver wm8741_spi_driver = { .of_match_table = wm8741_of_match, }, .probe = wm8741_spi_probe, - .remove = __devexit_p(wm8741_spi_remove), + .remove = wm8741_spi_remove, }; #endif /* CONFIG_SPI_MASTER */ diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index 89151ca5e77..50d5ff61623 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c @@ -18,6 +18,7 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> +#include <linux/regmap.h> #include <linux/spi/spi.h> #include <linux/slab.h> #include <linux/of_device.h> @@ -34,24 +35,55 @@ * We can't read the WM8750 register space when we * are using 2 wire for device control, so we cache them instead. */ -static const u16 wm8750_reg[] = { - 0x0097, 0x0097, 0x0079, 0x0079, /* 0 */ - 0x0000, 0x0008, 0x0000, 0x000a, /* 4 */ - 0x0000, 0x0000, 0x00ff, 0x00ff, /* 8 */ - 0x000f, 0x000f, 0x0000, 0x0000, /* 12 */ - 0x0000, 0x007b, 0x0000, 0x0032, /* 16 */ - 0x0000, 0x00c3, 0x00c3, 0x00c0, /* 20 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */ - 0x0000, 0x0000, 0x0050, 0x0050, /* 32 */ - 0x0050, 0x0050, 0x0050, 0x0050, /* 36 */ - 0x0079, 0x0079, 0x0079, /* 40 */ +static const struct reg_default wm8750_reg_defaults[] = { + { 0, 0x0097 }, + { 1, 0x0097 }, + { 2, 0x0079 }, + { 3, 0x0079 }, + { 4, 0x0000 }, + { 5, 0x0008 }, + { 6, 0x0000 }, + { 7, 0x000a }, + { 8, 0x0000 }, + { 9, 0x0000 }, + { 10, 0x00ff }, + { 11, 0x00ff }, + { 12, 0x000f }, + { 13, 0x000f }, + { 14, 0x0000 }, + { 15, 0x0000 }, + { 16, 0x0000 }, + { 17, 0x007b }, + { 18, 0x0000 }, + { 19, 0x0032 }, + { 20, 0x0000 }, + { 21, 0x00c3 }, + { 22, 0x00c3 }, + { 23, 0x00c0 }, + { 24, 0x0000 }, + { 25, 0x0000 }, + { 26, 0x0000 }, + { 27, 0x0000 }, + { 28, 0x0000 }, + { 29, 0x0000 }, + { 30, 0x0000 }, + { 31, 0x0000 }, + { 32, 0x0000 }, + { 33, 0x0000 }, + { 34, 0x0050 }, + { 35, 0x0050 }, + { 36, 0x0050 }, + { 37, 0x0050 }, + { 38, 0x0050 }, + { 39, 0x0050 }, + { 40, 0x0079 }, + { 41, 0x0079 }, + { 42, 0x0079 }, }; /* codec private data */ struct wm8750_priv { unsigned int sysclk; - enum snd_soc_control_type control_type; }; #define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0) @@ -668,10 +700,9 @@ static int wm8750_resume(struct snd_soc_codec *codec) static int wm8750_probe(struct snd_soc_codec *codec) { - struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec); int ret; - ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8750->control_type); + ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); if (ret < 0) { printk(KERN_ERR "wm8750: failed to set cache I/O: %d\n", ret); return ret; @@ -711,9 +742,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8750 = { .suspend = wm8750_suspend, .resume = wm8750_resume, .set_bias_level = wm8750_set_bias_level, - .reg_cache_size = ARRAY_SIZE(wm8750_reg), - .reg_word_size = sizeof(u16), - .reg_cache_default = wm8750_reg, .controls = wm8750_snd_controls, .num_controls = ARRAY_SIZE(wm8750_snd_controls), @@ -730,10 +758,21 @@ static const struct of_device_id wm8750_of_match[] = { }; MODULE_DEVICE_TABLE(of, wm8750_of_match); +static const struct regmap_config wm8750_regmap = { + .reg_bits = 7, + .val_bits = 9, + .max_register = WM8750_MOUTV, + + .reg_defaults = wm8750_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(wm8750_reg_defaults), + .cache_type = REGCACHE_RBTREE, +}; + #if defined(CONFIG_SPI_MASTER) -static int __devinit wm8750_spi_probe(struct spi_device *spi) +static int wm8750_spi_probe(struct spi_device *spi) { struct wm8750_priv *wm8750; + struct regmap *regmap; int ret; wm8750 = devm_kzalloc(&spi->dev, sizeof(struct wm8750_priv), @@ -741,7 +780,10 @@ static int __devinit wm8750_spi_probe(struct spi_device *spi) if (wm8750 == NULL) return -ENOMEM; - wm8750->control_type = SND_SOC_SPI; + regmap = devm_regmap_init_spi(spi, &wm8750_regmap); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + spi_set_drvdata(spi, wm8750); ret = snd_soc_register_codec(&spi->dev, @@ -749,7 +791,7 @@ static int __devinit wm8750_spi_probe(struct spi_device *spi) return ret; } -static int __devexit wm8750_spi_remove(struct spi_device *spi) +static int wm8750_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev); return 0; @@ -770,15 +812,16 @@ static struct spi_driver wm8750_spi_driver = { }, .id_table = wm8750_spi_ids, .probe = wm8750_spi_probe, - .remove = __devexit_p(wm8750_spi_remove), + .remove = wm8750_spi_remove, }; #endif /* CONFIG_SPI_MASTER */ #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static __devinit int wm8750_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8750_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8750_priv *wm8750; + struct regmap *regmap; int ret; wm8750 = devm_kzalloc(&i2c->dev, sizeof(struct wm8750_priv), @@ -787,14 +830,17 @@ static __devinit int wm8750_i2c_probe(struct i2c_client *i2c, return -ENOMEM; i2c_set_clientdata(i2c, wm8750); - wm8750->control_type = SND_SOC_I2C; + + regmap = devm_regmap_init_i2c(i2c, &wm8750_regmap); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8750, &wm8750_dai, 1); return ret; } -static __devexit int wm8750_i2c_remove(struct i2c_client *client) +static int wm8750_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -814,7 +860,7 @@ static struct i2c_driver wm8750_i2c_driver = { .of_match_table = wm8750_of_match, }, .probe = wm8750_i2c_probe, - .remove = __devexit_p(wm8750_i2c_remove), + .remove = wm8750_i2c_remove, .id_table = wm8750_i2c_id, }; #endif diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index 2e4a775ae56..0a4ab4c423d 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -1550,7 +1550,7 @@ static const struct regmap_config wm8753_regmap = { }; #if defined(CONFIG_SPI_MASTER) -static int __devinit wm8753_spi_probe(struct spi_device *spi) +static int wm8753_spi_probe(struct spi_device *spi) { struct wm8753_priv *wm8753; int ret; @@ -1562,36 +1562,25 @@ static int __devinit wm8753_spi_probe(struct spi_device *spi) spi_set_drvdata(spi, wm8753); - wm8753->regmap = regmap_init_spi(spi, &wm8753_regmap); + wm8753->regmap = devm_regmap_init_spi(spi, &wm8753_regmap); if (IS_ERR(wm8753->regmap)) { ret = PTR_ERR(wm8753->regmap); dev_err(&spi->dev, "Failed to allocate register map: %d\n", ret); - goto err; + return ret; } ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_wm8753, wm8753_dai, ARRAY_SIZE(wm8753_dai)); - if (ret != 0) { + if (ret != 0) dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret); - goto err_regmap; - } - return 0; - -err_regmap: - regmap_exit(wm8753->regmap); -err: return ret; } -static int __devexit wm8753_spi_remove(struct spi_device *spi) +static int wm8753_spi_remove(struct spi_device *spi) { - struct wm8753_priv *wm8753 = spi_get_drvdata(spi); - snd_soc_unregister_codec(&spi->dev); - regmap_exit(wm8753->regmap); - kfree(wm8753); return 0; } @@ -1602,13 +1591,13 @@ static struct spi_driver wm8753_spi_driver = { .of_match_table = wm8753_of_match, }, .probe = wm8753_spi_probe, - .remove = __devexit_p(wm8753_spi_remove), + .remove = wm8753_spi_remove, }; #endif /* CONFIG_SPI_MASTER */ #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static __devinit int wm8753_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8753_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8753_priv *wm8753; int ret; @@ -1620,35 +1609,25 @@ static __devinit int wm8753_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, wm8753); - wm8753->regmap = regmap_init_i2c(i2c, &wm8753_regmap); + wm8753->regmap = devm_regmap_init_i2c(i2c, &wm8753_regmap); if (IS_ERR(wm8753->regmap)) { ret = PTR_ERR(wm8753->regmap); dev_err(&i2c->dev, "Failed to allocate register map: %d\n", ret); - goto err; + return ret; } ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8753, wm8753_dai, ARRAY_SIZE(wm8753_dai)); - if (ret != 0) { + if (ret != 0) dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); - goto err_regmap; - } - return 0; - -err_regmap: - regmap_exit(wm8753->regmap); -err: return ret; } -static __devexit int wm8753_i2c_remove(struct i2c_client *client) +static int wm8753_i2c_remove(struct i2c_client *client) { - struct wm8753_priv *wm8753 = i2c_get_clientdata(client); - snd_soc_unregister_codec(&client->dev); - regmap_exit(wm8753->regmap); return 0; } @@ -1665,7 +1644,7 @@ static struct i2c_driver wm8753_i2c_driver = { .of_match_table = wm8753_of_match, }, .probe = wm8753_i2c_probe, - .remove = __devexit_p(wm8753_i2c_remove), + .remove = wm8753_i2c_remove, .id_table = wm8753_i2c_id, }; #endif diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c index c7c0034d396..89a18d82f30 100644 --- a/sound/soc/codecs/wm8770.c +++ b/sound/soc/codecs/wm8770.c @@ -17,6 +17,7 @@ #include <linux/of_device.h> #include <linux/pm.h> #include <linux/spi/spi.h> +#include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/slab.h> #include <sound/core.h> @@ -35,19 +36,52 @@ static const char *wm8770_supply_names[WM8770_NUM_SUPPLIES] = { "DVDD" }; -static const u16 wm8770_reg_defs[WM8770_CACHEREGNUM] = { - 0x7f, 0x7f, 0x7f, 0x7f, - 0x7f, 0x7f, 0x7f, 0x7f, - 0x7f, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0, 0x90, 0, - 0, 0x22, 0x22, 0x3e, - 0xc, 0xc, 0x100, 0x189, - 0x189, 0x8770 +static const struct reg_default wm8770_reg_defaults[] = { + { 0, 0x7f }, + { 1, 0x7f }, + { 2, 0x7f }, + { 3, 0x7f }, + { 4, 0x7f }, + { 5, 0x7f }, + { 6, 0x7f }, + { 7, 0x7f }, + { 8, 0x7f }, + { 9, 0xff }, + { 10, 0xff }, + { 11, 0xff }, + { 12, 0xff }, + { 13, 0xff }, + { 14, 0xff }, + { 15, 0xff }, + { 16, 0xff }, + { 17, 0xff }, + { 18, 0 }, + { 19, 0x90 }, + { 20, 0 }, + { 21, 0 }, + { 22, 0x22 }, + { 23, 0x22 }, + { 24, 0x3e }, + { 25, 0xc }, + { 26, 0xc }, + { 27, 0x100 }, + { 28, 0x189 }, + { 29, 0x189 }, + { 30, 0x8770 }, }; +static bool wm8770_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case WM8770_RESET: + return true; + default: + return false; + } +} + struct wm8770_priv { - enum snd_soc_control_type control_type; + struct regmap *regmap; struct regulator_bulk_data supplies[WM8770_NUM_SUPPLIES]; struct notifier_block disable_nb[WM8770_NUM_SUPPLIES]; struct snd_soc_codec *codec; @@ -71,7 +105,7 @@ static int wm8770_regulator_event_##n(struct notifier_block *nb, \ struct wm8770_priv *wm8770 = container_of(nb, struct wm8770_priv, \ disable_nb[n]); \ if (event & REGULATOR_EVENT_DISABLE) { \ - wm8770->codec->cache_sync = 1; \ + regcache_mark_dirty(wm8770->regmap); \ } \ return 0; \ } @@ -466,24 +500,6 @@ static int wm8770_set_sysclk(struct snd_soc_dai *dai, return 0; } -static void wm8770_sync_cache(struct snd_soc_codec *codec) -{ - int i; - u16 *cache; - - if (!codec->cache_sync) - return; - - codec->cache_only = 0; - cache = codec->reg_cache; - for (i = 0; i < codec->driver->reg_cache_size; i++) { - if (i == WM8770_RESET || cache[i] == wm8770_reg_defs[i]) - continue; - snd_soc_write(codec, i, cache[i]); - } - codec->cache_sync = 0; -} - static int wm8770_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { @@ -507,7 +523,9 @@ static int wm8770_set_bias_level(struct snd_soc_codec *codec, ret); return ret; } - wm8770_sync_cache(codec); + + regcache_sync(wm8770->regmap); + /* global powerup */ snd_soc_write(codec, WM8770_PWDNCTRL, 0); } @@ -554,68 +572,25 @@ static struct snd_soc_dai_driver wm8770_dai = { .symmetric_rates = 1 }; -#ifdef CONFIG_PM -static int wm8770_suspend(struct snd_soc_codec *codec) -{ - wm8770_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int wm8770_resume(struct snd_soc_codec *codec) -{ - wm8770_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; -} -#else -#define wm8770_suspend NULL -#define wm8770_resume NULL -#endif - static int wm8770_probe(struct snd_soc_codec *codec) { struct wm8770_priv *wm8770; int ret; - int i; wm8770 = snd_soc_codec_get_drvdata(codec); wm8770->codec = codec; - ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8770->control_type); + ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); if (ret < 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); return ret; } - for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++) - wm8770->supplies[i].supply = wm8770_supply_names[i]; - - ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8770->supplies), - wm8770->supplies); - if (ret) { - dev_err(codec->dev, "Failed to request supplies: %d\n", ret); - return ret; - } - - wm8770->disable_nb[0].notifier_call = wm8770_regulator_event_0; - wm8770->disable_nb[1].notifier_call = wm8770_regulator_event_1; - wm8770->disable_nb[2].notifier_call = wm8770_regulator_event_2; - - /* This should really be moved into the regulator core */ - for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++) { - ret = regulator_register_notifier(wm8770->supplies[i].consumer, - &wm8770->disable_nb[i]); - if (ret) { - dev_err(codec->dev, - "Failed to register regulator notifier: %d\n", - ret); - } - } - ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies), wm8770->supplies); if (ret) { dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); - goto err_reg_get; + return ret; } ret = wm8770_reset(codec); @@ -624,8 +599,6 @@ static int wm8770_probe(struct snd_soc_codec *codec) goto err_reg_enable; } - wm8770_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - /* latch the volume update bits */ snd_soc_update_bits(codec, WM8770_MSDIGVOL, 0x100, 0x100); snd_soc_update_bits(codec, WM8770_MSALGVOL, 0x100, 0x100); @@ -641,46 +614,22 @@ static int wm8770_probe(struct snd_soc_codec *codec) /* mute all DACs */ snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10, 0x10); - snd_soc_add_codec_controls(codec, wm8770_snd_controls, - ARRAY_SIZE(wm8770_snd_controls)); - snd_soc_dapm_new_controls(&codec->dapm, wm8770_dapm_widgets, - ARRAY_SIZE(wm8770_dapm_widgets)); - snd_soc_dapm_add_routes(&codec->dapm, wm8770_intercon, - ARRAY_SIZE(wm8770_intercon)); - return 0; - err_reg_enable: regulator_bulk_disable(ARRAY_SIZE(wm8770->supplies), wm8770->supplies); -err_reg_get: - regulator_bulk_free(ARRAY_SIZE(wm8770->supplies), wm8770->supplies); return ret; } -static int wm8770_remove(struct snd_soc_codec *codec) -{ - struct wm8770_priv *wm8770; - int i; - - wm8770 = snd_soc_codec_get_drvdata(codec); - wm8770_set_bias_level(codec, SND_SOC_BIAS_OFF); - - for (i = 0; i < ARRAY_SIZE(wm8770->supplies); ++i) - regulator_unregister_notifier(wm8770->supplies[i].consumer, - &wm8770->disable_nb[i]); - regulator_bulk_free(ARRAY_SIZE(wm8770->supplies), wm8770->supplies); - return 0; -} - static struct snd_soc_codec_driver soc_codec_dev_wm8770 = { .probe = wm8770_probe, - .remove = wm8770_remove, - .suspend = wm8770_suspend, - .resume = wm8770_resume, .set_bias_level = wm8770_set_bias_level, .idle_bias_off = true, - .reg_cache_size = ARRAY_SIZE(wm8770_reg_defs), - .reg_word_size = sizeof (u16), - .reg_cache_default = wm8770_reg_defs + + .controls = wm8770_snd_controls, + .num_controls = ARRAY_SIZE(wm8770_snd_controls), + .dapm_widgets = wm8770_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8770_dapm_widgets), + .dapm_routes = wm8770_intercon, + .num_dapm_routes = ARRAY_SIZE(wm8770_intercon), }; static const struct of_device_id wm8770_of_match[] = { @@ -689,17 +638,57 @@ static const struct of_device_id wm8770_of_match[] = { }; MODULE_DEVICE_TABLE(of, wm8770_of_match); -static int __devinit wm8770_spi_probe(struct spi_device *spi) +static const struct regmap_config wm8770_regmap = { + .reg_bits = 7, + .val_bits = 9, + .max_register = WM8770_RESET, + + .reg_defaults = wm8770_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(wm8770_reg_defaults), + .cache_type = REGCACHE_RBTREE, + + .volatile_reg = wm8770_volatile_reg, +}; + +static int wm8770_spi_probe(struct spi_device *spi) { struct wm8770_priv *wm8770; - int ret; + int ret, i; wm8770 = devm_kzalloc(&spi->dev, sizeof(struct wm8770_priv), GFP_KERNEL); if (!wm8770) return -ENOMEM; - wm8770->control_type = SND_SOC_SPI; + for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++) + wm8770->supplies[i].supply = wm8770_supply_names[i]; + + ret = devm_regulator_bulk_get(&spi->dev, ARRAY_SIZE(wm8770->supplies), + wm8770->supplies); + if (ret) { + dev_err(&spi->dev, "Failed to request supplies: %d\n", ret); + return ret; + } + + wm8770->disable_nb[0].notifier_call = wm8770_regulator_event_0; + wm8770->disable_nb[1].notifier_call = wm8770_regulator_event_1; + wm8770->disable_nb[2].notifier_call = wm8770_regulator_event_2; + + /* This should really be moved into the regulator core */ + for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++) { + ret = regulator_register_notifier(wm8770->supplies[i].consumer, + &wm8770->disable_nb[i]); + if (ret) { + dev_err(&spi->dev, + "Failed to register regulator notifier: %d\n", + ret); + } + } + + wm8770->regmap = devm_regmap_init_spi(spi, &wm8770_regmap); + if (IS_ERR(wm8770->regmap)) + return PTR_ERR(wm8770->regmap); + spi_set_drvdata(spi, wm8770); ret = snd_soc_register_codec(&spi->dev, @@ -708,9 +697,17 @@ static int __devinit wm8770_spi_probe(struct spi_device *spi) return ret; } -static int __devexit wm8770_spi_remove(struct spi_device *spi) +static int wm8770_spi_remove(struct spi_device *spi) { + struct wm8770_priv *wm8770 = spi_get_drvdata(spi); + int i; + + for (i = 0; i < ARRAY_SIZE(wm8770->supplies); ++i) + regulator_unregister_notifier(wm8770->supplies[i].consumer, + &wm8770->disable_nb[i]); + snd_soc_unregister_codec(&spi->dev); + return 0; } @@ -721,7 +718,7 @@ static struct spi_driver wm8770_spi_driver = { .of_match_table = wm8770_of_match, }, .probe = wm8770_spi_probe, - .remove = __devexit_p(wm8770_spi_remove) + .remove = wm8770_spi_remove }; module_spi_driver(wm8770_spi_driver); diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index c32249ddb2e..f31017ed138 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.c @@ -492,7 +492,7 @@ static const struct regmap_config wm8776_regmap = { }; #if defined(CONFIG_SPI_MASTER) -static int __devinit wm8776_spi_probe(struct spi_device *spi) +static int wm8776_spi_probe(struct spi_device *spi) { struct wm8776_priv *wm8776; int ret; @@ -514,7 +514,7 @@ static int __devinit wm8776_spi_probe(struct spi_device *spi) return ret; } -static int __devexit wm8776_spi_remove(struct spi_device *spi) +static int wm8776_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev); return 0; @@ -527,13 +527,13 @@ static struct spi_driver wm8776_spi_driver = { .of_match_table = wm8776_of_match, }, .probe = wm8776_spi_probe, - .remove = __devexit_p(wm8776_spi_remove), + .remove = wm8776_spi_remove, }; #endif /* CONFIG_SPI_MASTER */ #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static __devinit int wm8776_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8776_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8776_priv *wm8776; int ret; @@ -555,7 +555,7 @@ static __devinit int wm8776_i2c_probe(struct i2c_client *i2c, return ret; } -static __devexit int wm8776_i2c_remove(struct i2c_client *client) +static int wm8776_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -575,7 +575,7 @@ static struct i2c_driver wm8776_i2c_driver = { .of_match_table = wm8776_of_match, }, .probe = wm8776_i2c_probe, - .remove = __devexit_p(wm8776_i2c_remove), + .remove = wm8776_i2c_remove, .id_table = wm8776_i2c_id, }; #endif diff --git a/sound/soc/codecs/wm8782.c b/sound/soc/codecs/wm8782.c index 3fdea98f732..f1fdbf63abb 100644 --- a/sound/soc/codecs/wm8782.c +++ b/sound/soc/codecs/wm8782.c @@ -42,13 +42,13 @@ static struct snd_soc_dai_driver wm8782_dai = { static struct snd_soc_codec_driver soc_codec_dev_wm8782; -static __devinit int wm8782_probe(struct platform_device *pdev) +static int wm8782_probe(struct platform_device *pdev) { return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8782, &wm8782_dai, 1); } -static int __devexit wm8782_remove(struct platform_device *pdev) +static int wm8782_remove(struct platform_device *pdev) { snd_soc_unregister_codec(&pdev->dev); return 0; @@ -60,7 +60,7 @@ static struct platform_driver wm8782_codec_driver = { .owner = THIS_MODULE, }, .probe = wm8782_probe, - .remove = __devexit_p(wm8782_remove), + .remove = wm8782_remove, }; module_platform_driver(wm8782_codec_driver); diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index c088020172a..d321a875b02 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -702,7 +702,7 @@ static struct regmap_config wm8804_regmap_config = { }; #if defined(CONFIG_SPI_MASTER) -static int __devinit wm8804_spi_probe(struct spi_device *spi) +static int wm8804_spi_probe(struct spi_device *spi) { struct wm8804_priv *wm8804; int ret; @@ -711,7 +711,7 @@ static int __devinit wm8804_spi_probe(struct spi_device *spi) if (!wm8804) return -ENOMEM; - wm8804->regmap = regmap_init_spi(spi, &wm8804_regmap_config); + wm8804->regmap = devm_regmap_init_spi(spi, &wm8804_regmap_config); if (IS_ERR(wm8804->regmap)) { ret = PTR_ERR(wm8804->regmap); return ret; @@ -725,11 +725,9 @@ static int __devinit wm8804_spi_probe(struct spi_device *spi) return ret; } -static int __devexit wm8804_spi_remove(struct spi_device *spi) +static int wm8804_spi_remove(struct spi_device *spi) { - struct wm8804_priv *wm8804 = spi_get_drvdata(spi); snd_soc_unregister_codec(&spi->dev); - regmap_exit(wm8804->regmap); return 0; } @@ -740,13 +738,13 @@ static struct spi_driver wm8804_spi_driver = { .of_match_table = wm8804_of_match, }, .probe = wm8804_spi_probe, - .remove = __devexit_p(wm8804_spi_remove) + .remove = wm8804_spi_remove }; #endif #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static __devinit int wm8804_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8804_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8804_priv *wm8804; int ret; @@ -755,7 +753,7 @@ static __devinit int wm8804_i2c_probe(struct i2c_client *i2c, if (!wm8804) return -ENOMEM; - wm8804->regmap = regmap_init_i2c(i2c, &wm8804_regmap_config); + wm8804->regmap = devm_regmap_init_i2c(i2c, &wm8804_regmap_config); if (IS_ERR(wm8804->regmap)) { ret = PTR_ERR(wm8804->regmap); return ret; @@ -765,23 +763,12 @@ static __devinit int wm8804_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8804, &wm8804_dai, 1); - if (ret != 0) - goto err; - - return 0; - -err: - regmap_exit(wm8804->regmap); return ret; } -static __devexit int wm8804_i2c_remove(struct i2c_client *i2c) +static int wm8804_i2c_remove(struct i2c_client *i2c) { - struct wm8804_priv *wm8804 = i2c_get_clientdata(i2c); - snd_soc_unregister_codec(&i2c->dev); - regmap_exit(wm8804->regmap); - return 0; } @@ -798,7 +785,7 @@ static struct i2c_driver wm8804_i2c_driver = { .of_match_table = wm8804_of_match, }, .probe = wm8804_i2c_probe, - .remove = __devexit_p(wm8804_i2c_remove), + .remove = wm8804_i2c_remove, .id_table = wm8804_i2c_id }; #endif diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index e781f865e5d..7c8257c5a17 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c @@ -1247,7 +1247,7 @@ static const struct regmap_config wm8900_regmap = { }; #if defined(CONFIG_SPI_MASTER) -static int __devinit wm8900_spi_probe(struct spi_device *spi) +static int wm8900_spi_probe(struct spi_device *spi) { struct wm8900_priv *wm8900; int ret; @@ -1269,7 +1269,7 @@ static int __devinit wm8900_spi_probe(struct spi_device *spi) return ret; } -static int __devexit wm8900_spi_remove(struct spi_device *spi) +static int wm8900_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev); return 0; @@ -1281,13 +1281,13 @@ static struct spi_driver wm8900_spi_driver = { .owner = THIS_MODULE, }, .probe = wm8900_spi_probe, - .remove = __devexit_p(wm8900_spi_remove), + .remove = wm8900_spi_remove, }; #endif /* CONFIG_SPI_MASTER */ #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static __devinit int wm8900_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8900_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8900_priv *wm8900; int ret; @@ -1309,7 +1309,7 @@ static __devinit int wm8900_i2c_probe(struct i2c_client *i2c, return ret; } -static __devexit int wm8900_i2c_remove(struct i2c_client *client) +static int wm8900_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -1327,7 +1327,7 @@ static struct i2c_driver wm8900_i2c_driver = { .owner = THIS_MODULE, }, .probe = wm8900_i2c_probe, - .remove = __devexit_p(wm8900_i2c_remove), + .remove = wm8900_i2c_remove, .id_table = wm8900_i2c_id, }; #endif diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 839414f9e2e..134e41c870b 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -2020,8 +2020,8 @@ static int wm8903_set_pdata_from_of(struct i2c_client *i2c, return 0; } -static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8903_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8903_platform_data *pdata = dev_get_platdata(&i2c->dev); struct wm8903_priv *wm8903; @@ -2206,7 +2206,7 @@ err: return ret; } -static __devexit int wm8903_i2c_remove(struct i2c_client *client) +static int wm8903_i2c_remove(struct i2c_client *client) { struct wm8903_priv *wm8903 = i2c_get_clientdata(client); @@ -2237,7 +2237,7 @@ static struct i2c_driver wm8903_i2c_driver = { .of_match_table = wm8903_of_match, }, .probe = wm8903_i2c_probe, - .remove = __devexit_p(wm8903_i2c_remove), + .remove = wm8903_i2c_remove, .id_table = wm8903_i2c_id, }; diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 7c8df52a8d9..3ff195c541d 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -2111,8 +2111,8 @@ static const struct regmap_config wm8904_regmap = { .num_reg_defaults = ARRAY_SIZE(wm8904_reg_defaults), }; -static __devinit int wm8904_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8904_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8904_priv *wm8904; unsigned int val; @@ -2247,7 +2247,7 @@ err_enable: return ret; } -static __devexit int wm8904_i2c_remove(struct i2c_client *client) +static int wm8904_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -2267,7 +2267,7 @@ static struct i2c_driver wm8904_i2c_driver = { .owner = THIS_MODULE, }, .probe = wm8904_i2c_probe, - .remove = __devexit_p(wm8904_i2c_remove), + .remove = wm8904_i2c_remove, .id_table = wm8904_i2c_id, }; diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index b20aa4e7c3f..b1591c61c25 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c @@ -742,8 +742,8 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8940 = { .volatile_register = wm8940_volatile_register, }; -static __devinit int wm8940_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8940_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8940_priv *wm8940; int ret; @@ -762,7 +762,7 @@ static __devinit int wm8940_i2c_probe(struct i2c_client *i2c, return ret; } -static __devexit int wm8940_i2c_remove(struct i2c_client *client) +static int wm8940_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); @@ -781,7 +781,7 @@ static struct i2c_driver wm8940_i2c_driver = { .owner = THIS_MODULE, }, .probe = wm8940_i2c_probe, - .remove = __devexit_p(wm8940_i2c_remove), + .remove = wm8940_i2c_remove, .id_table = wm8940_i2c_id, }; diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index 2f1c075755b..82c8ba97572 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c @@ -1012,8 +1012,8 @@ static const struct regmap_config wm8955_regmap = { .num_reg_defaults = ARRAY_SIZE(wm8955_reg_defaults), }; -static __devinit int wm8955_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8955_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8955_priv *wm8955; int ret; @@ -1023,7 +1023,7 @@ static __devinit int wm8955_i2c_probe(struct i2c_client *i2c, if (wm8955 == NULL) return -ENOMEM; - wm8955->regmap = regmap_init_i2c(i2c, &wm8955_regmap); + wm8955->regmap = devm_regmap_init_i2c(i2c, &wm8955_regmap); if (IS_ERR(wm8955->regmap)) { ret = PTR_ERR(wm8955->regmap); 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, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8955, &wm8955_dai, 1); - if (ret != 0) - goto err; return ret; - -err: - regmap_exit(wm8955->regmap); - return ret; } -static __devexit int wm8955_i2c_remove(struct i2c_client *client) +static int wm8955_i2c_remove(struct i2c_client *client) { - struct wm8955_priv *wm8955 = i2c_get_clientdata(client); - snd_soc_unregister_codec(&client->dev); - regmap_exit(wm8955->regmap); return 0; } @@ -1067,7 +1058,7 @@ static struct i2c_driver wm8955_i2c_driver = { .owner = THIS_MODULE, }, .probe = wm8955_i2c_probe, - .remove = __devexit_p(wm8955_i2c_remove), + .remove = wm8955_i2c_remove, .id_table = wm8955_i2c_id, }; diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c index 00121ba3659..b0710d817a6 100644 --- a/sound/soc/codecs/wm8958-dsp2.c +++ b/sound/soc/codecs/wm8958-dsp2.c @@ -195,7 +195,7 @@ ok: static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - struct wm8994_pdata *pdata = wm8994->pdata; + struct wm8994 *control = wm8994->wm8994; int i; /* 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) WM8958_DSP2_ENA, WM8958_DSP2_ENA); /* If we've got user supplied MBC settings use them */ - if (pdata && pdata->num_mbc_cfgs) { + if (control->pdata.num_mbc_cfgs) { struct wm8958_mbc_cfg *cfg - = &pdata->mbc_cfgs[wm8994->mbc_cfg]; + = &control->pdata.mbc_cfgs[wm8994->mbc_cfg]; for (i = 0; i < ARRAY_SIZE(cfg->coeff_regs); i++) 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) static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - struct wm8994_pdata *pdata = wm8994->pdata; + struct wm8994 *control = wm8994->wm8994; int i, ena; if (wm8994->mbc_vss) @@ -249,26 +249,26 @@ static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path) WM8958_DSP2_ENA, WM8958_DSP2_ENA); /* If we've got user supplied settings use them */ - if (pdata && pdata->num_mbc_cfgs) { + if (control->pdata.num_mbc_cfgs) { struct wm8958_mbc_cfg *cfg - = &pdata->mbc_cfgs[wm8994->mbc_cfg]; + = &control->pdata.mbc_cfgs[wm8994->mbc_cfg]; for (i = 0; i < ARRAY_SIZE(cfg->combined_regs); i++) snd_soc_write(codec, i + 0x2800, cfg->combined_regs[i]); } - if (pdata && pdata->num_vss_cfgs) { + if (control->pdata.num_vss_cfgs) { struct wm8958_vss_cfg *cfg - = &pdata->vss_cfgs[wm8994->vss_cfg]; + = &control->pdata.vss_cfgs[wm8994->vss_cfg]; for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) snd_soc_write(codec, i + 0x2600, cfg->regs[i]); } - if (pdata && pdata->num_vss_hpf_cfgs) { + if (control->pdata.num_vss_hpf_cfgs) { struct wm8958_vss_hpf_cfg *cfg - = &pdata->vss_hpf_cfgs[wm8994->vss_hpf_cfg]; + = &control->pdata.vss_hpf_cfgs[wm8994->vss_hpf_cfg]; for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) 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) static void wm8958_dsp_start_enh_eq(struct snd_soc_codec *codec, int path) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - struct wm8994_pdata *pdata = wm8994->pdata; + struct wm8994 *control = wm8994->wm8994; int i; 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) WM8958_DSP2_ENA, WM8958_DSP2_ENA); /* If we've got user supplied settings use them */ - if (pdata && pdata->num_enh_eq_cfgs) { + if (control->pdata.num_enh_eq_cfgs) { struct wm8958_enh_eq_cfg *cfg - = &pdata->enh_eq_cfgs[wm8994->enh_eq_cfg]; + = &control->pdata.enh_eq_cfgs[wm8994->enh_eq_cfg]; for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) snd_soc_write(codec, i + 0x2200, @@ -458,7 +458,7 @@ static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - struct wm8994_pdata *pdata = wm8994->pdata; + struct wm8994 *control = wm8994->wm8994; int value = ucontrol->value.integer.value[0]; int reg; @@ -467,7 +467,7 @@ static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol, if (reg < 0 || reg & WM8958_DSP2CLK_ENA) return -EBUSY; - if (value >= pdata->num_mbc_cfgs) + if (value >= control->pdata.num_mbc_cfgs) return -EINVAL; wm8994->mbc_cfg = value; @@ -548,7 +548,7 @@ static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - struct wm8994_pdata *pdata = wm8994->pdata; + struct wm8994 *control = wm8994->wm8994; int value = ucontrol->value.integer.value[0]; int reg; @@ -557,7 +557,7 @@ static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol, if (reg < 0 || reg & WM8958_DSP2CLK_ENA) return -EBUSY; - if (value >= pdata->num_vss_cfgs) + if (value >= control->pdata.num_vss_cfgs) return -EINVAL; wm8994->vss_cfg = value; @@ -581,7 +581,7 @@ static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - struct wm8994_pdata *pdata = wm8994->pdata; + struct wm8994 *control = wm8994->wm8994; int value = ucontrol->value.integer.value[0]; int reg; @@ -590,7 +590,7 @@ static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol, if (reg < 0 || reg & WM8958_DSP2CLK_ENA) return -EBUSY; - if (value >= pdata->num_vss_hpf_cfgs) + if (value >= control->pdata.num_vss_hpf_cfgs) return -EINVAL; wm8994->vss_hpf_cfg = value; @@ -748,7 +748,7 @@ static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - struct wm8994_pdata *pdata = wm8994->pdata; + struct wm8994 *control = wm8994->wm8994; int value = ucontrol->value.integer.value[0]; int reg; @@ -757,7 +757,7 @@ static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol, if (reg < 0 || reg & WM8958_DSP2CLK_ENA) return -EBUSY; - if (value >= pdata->num_enh_eq_cfgs) + if (value >= control->pdata.num_enh_eq_cfgs) return -EINVAL; wm8994->enh_eq_cfg = value; @@ -883,13 +883,6 @@ static void wm8958_mbc_vss_loaded(const struct firmware *fw, void *context) wm8994->mbc_vss = fw; mutex_unlock(&codec->mutex); } - - /* We can't have more than one request outstanding at once so - * we daisy chain. - */ - request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, - "wm8958_enh_eq.wfw", codec->dev, GFP_KERNEL, - codec, wm8958_enh_eq_loaded); } 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) struct snd_soc_codec *codec = context; struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - if (wm8958_dsp2_fw(codec, "MBC", fw, true) != 0) - return; - - mutex_lock(&codec->mutex); - wm8994->mbc = fw; - mutex_unlock(&codec->mutex); - - /* We can't have more than one request outstanding at once so - * we daisy chain. - */ - request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, - "wm8958_mbc_vss.wfw", codec->dev, GFP_KERNEL, - codec, wm8958_mbc_vss_loaded); + if (fw && (wm8958_dsp2_fw(codec, "MBC", fw, true) == 0)) { + mutex_lock(&codec->mutex); + wm8994->mbc = fw; + mutex_unlock(&codec->mutex); + } } void wm8958_dsp2_init(struct snd_soc_codec *codec) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - struct wm8994_pdata *pdata = wm8994->pdata; + struct wm8994 *control = wm8994->wm8994; + struct wm8994_pdata *pdata = &control->pdata; int ret, i; wm8994->dsp_active = -1; @@ -932,9 +918,12 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, "wm8958_mbc.wfw", codec->dev, GFP_KERNEL, codec, wm8958_mbc_loaded); - - if (!pdata) - return; + request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, + "wm8958_mbc_vss.wfw", codec->dev, GFP_KERNEL, + codec, wm8958_mbc_vss_loaded); + request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, + "wm8958_enh_eq.wfw", codec->dev, GFP_KERNEL, + codec, wm8958_enh_eq_loaded); if (pdata->num_mbc_cfgs) { struct snd_kcontrol_new control[] = { diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index f0f6f660178..9bb92732599 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -1028,8 +1028,8 @@ static const struct regmap_config wm8960_regmap = { .volatile_reg = wm8960_volatile, }; -static __devinit int wm8960_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8960_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8960_data *pdata = dev_get_platdata(&i2c->dev); struct wm8960_priv *wm8960; @@ -1040,7 +1040,7 @@ static __devinit int wm8960_i2c_probe(struct i2c_client *i2c, if (wm8960 == NULL) return -ENOMEM; - wm8960->regmap = regmap_init_i2c(i2c, &wm8960_regmap); + wm8960->regmap = devm_regmap_init_i2c(i2c, &wm8960_regmap); if (IS_ERR(wm8960->regmap)) return PTR_ERR(wm8960->regmap); @@ -1062,7 +1062,7 @@ static __devinit int wm8960_i2c_probe(struct i2c_client *i2c, return ret; } -static __devexit int wm8960_i2c_remove(struct i2c_client *client) +static int wm8960_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -1080,7 +1080,7 @@ static struct i2c_driver wm8960_i2c_driver = { .owner = THIS_MODULE, }, .probe = wm8960_i2c_probe, - .remove = __devexit_p(wm8960_i2c_remove), + .remove = wm8960_i2c_remove, .id_table = wm8960_i2c_id, }; diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c index f387670d0d7..900328e28a1 100644 --- a/sound/soc/codecs/wm8961.c +++ b/sound/soc/codecs/wm8961.c @@ -937,8 +937,8 @@ static const struct regmap_config wm8961_regmap = { .readable_reg = wm8961_readable, }; -static __devinit int wm8961_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8961_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8961_priv *wm8961; unsigned int val; @@ -993,7 +993,7 @@ static __devinit int wm8961_i2c_probe(struct i2c_client *i2c, return ret; } -static __devexit int wm8961_i2c_remove(struct i2c_client *client) +static int wm8961_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); @@ -1012,7 +1012,7 @@ static struct i2c_driver wm8961_i2c_driver = { .owner = THIS_MODULE, }, .probe = wm8961_i2c_probe, - .remove = __devexit_p(wm8961_i2c_remove), + .remove = wm8961_i2c_remove, .id_table = wm8961_i2c_id, }; diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index ce672007379..bd4b0db4cda 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -3588,8 +3588,8 @@ static const struct regmap_config wm8962_regmap = { .cache_type = REGCACHE_RBTREE, }; -static __devinit int wm8962_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8962_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8962_pdata *pdata = dev_get_platdata(&i2c->dev); struct wm8962_priv *wm8962; @@ -3610,7 +3610,7 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c, for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++) wm8962->supplies[i].supply = wm8962_supply_names[i]; - ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8962->supplies), + ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8962->supplies), wm8962->supplies); if (ret != 0) { dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); @@ -3621,10 +3621,10 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c, wm8962->supplies); if (ret != 0) { dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); - goto err_get; + return ret; } - wm8962->regmap = regmap_init_i2c(i2c, &wm8962_regmap); + wm8962->regmap = devm_regmap_init_i2c(i2c, &wm8962_regmap); if (IS_ERR(wm8962->regmap)) { ret = PTR_ERR(wm8962->regmap); dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret); @@ -3641,20 +3641,20 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c, ret = regmap_read(wm8962->regmap, WM8962_SOFTWARE_RESET, ®); if (ret < 0) { dev_err(&i2c->dev, "Failed to read ID register\n"); - goto err_regmap; + goto err_enable; } if (reg != 0x6243) { dev_err(&i2c->dev, "Device is not a WM8962, ID %x != 0x6243\n", reg); ret = -EINVAL; - goto err_regmap; + goto err_enable; } ret = regmap_read(wm8962->regmap, WM8962_RIGHT_INPUT_VOLUME, ®); if (ret < 0) { dev_err(&i2c->dev, "Failed to read device revision: %d\n", ret); - goto err_regmap; + goto err_enable; } dev_info(&i2c->dev, "customer id %x revision %c\n", @@ -3667,7 +3667,7 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c, ret = wm8962_reset(wm8962); if (ret < 0) { dev_err(&i2c->dev, "Failed to issue reset\n"); - goto err_regmap; + goto err_enable; } if (pdata && pdata->in4_dc_measure) { @@ -3686,30 +3686,22 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8962, &wm8962_dai, 1); if (ret < 0) - goto err_regmap; + goto err_enable; /* The drivers should power up as needed */ regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); return 0; -err_regmap: - regmap_exit(wm8962->regmap); err_enable: regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); -err_get: - regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); err: return ret; } -static __devexit int wm8962_i2c_remove(struct i2c_client *client) +static int wm8962_i2c_remove(struct i2c_client *client) { - struct wm8962_priv *wm8962 = dev_get_drvdata(&client->dev); - snd_soc_unregister_codec(&client->dev); - regmap_exit(wm8962->regmap); - regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); return 0; } @@ -3773,7 +3765,7 @@ static struct i2c_driver wm8962_i2c_driver = { .pm = &wm8962_pm, }, .probe = wm8962_i2c_probe, - .remove = __devexit_p(wm8962_i2c_remove), + .remove = wm8962_i2c_remove, .id_table = wm8962_i2c_id, }; diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c index 5ce64775844..67aba78a7ca 100644 --- a/sound/soc/codecs/wm8971.c +++ b/sound/soc/codecs/wm8971.c @@ -19,6 +19,7 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> +#include <linux/regmap.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> @@ -34,7 +35,6 @@ static struct workqueue_struct *wm8971_workq = NULL; /* codec private data */ struct wm8971_priv { - enum snd_soc_control_type control_type; unsigned int sysclk; }; @@ -43,18 +43,50 @@ struct wm8971_priv { * We can't read the WM8971 register space when we * are using 2 wire for device control, so we cache them instead. */ -static const u16 wm8971_reg[] = { - 0x0097, 0x0097, 0x0079, 0x0079, /* 0 */ - 0x0000, 0x0008, 0x0000, 0x000a, /* 4 */ - 0x0000, 0x0000, 0x00ff, 0x00ff, /* 8 */ - 0x000f, 0x000f, 0x0000, 0x0000, /* 12 */ - 0x0000, 0x007b, 0x0000, 0x0032, /* 16 */ - 0x0000, 0x00c3, 0x00c3, 0x00c0, /* 20 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */ - 0x0000, 0x0000, 0x0050, 0x0050, /* 32 */ - 0x0050, 0x0050, 0x0050, 0x0050, /* 36 */ - 0x0079, 0x0079, 0x0079, /* 40 */ +static const struct reg_default wm8971_reg_defaults[] = { + { 0, 0x0097 }, + { 1, 0x0097 }, + { 2, 0x0079 }, + { 3, 0x0079 }, + { 4, 0x0000 }, + { 5, 0x0008 }, + { 6, 0x0000 }, + { 7, 0x000a }, + { 8, 0x0000 }, + { 9, 0x0000 }, + { 10, 0x00ff }, + { 11, 0x00ff }, + { 12, 0x000f }, + { 13, 0x000f }, + { 14, 0x0000 }, + { 15, 0x0000 }, + { 16, 0x0000 }, + { 17, 0x007b }, + { 18, 0x0000 }, + { 19, 0x0032 }, + { 20, 0x0000 }, + { 21, 0x00c3 }, + { 22, 0x00c3 }, + { 23, 0x00c0 }, + { 24, 0x0000 }, + { 25, 0x0000 }, + { 26, 0x0000 }, + { 27, 0x0000 }, + { 28, 0x0000 }, + { 29, 0x0000 }, + { 30, 0x0000 }, + { 31, 0x0000 }, + { 32, 0x0000 }, + { 33, 0x0000 }, + { 34, 0x0050 }, + { 35, 0x0050 }, + { 36, 0x0050 }, + { 37, 0x0050 }, + { 38, 0x0050 }, + { 39, 0x0050 }, + { 40, 0x0079 }, + { 41, 0x0079 }, + { 42, 0x0079 }, }; #define wm8971_reset(c) snd_soc_write(c, WM8971_RESET, 0) @@ -613,11 +645,10 @@ static int wm8971_resume(struct snd_soc_codec *codec) static int wm8971_probe(struct snd_soc_codec *codec) { - struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec); int ret = 0; u16 reg; - ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8971->control_type); + ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); if (ret < 0) { printk(KERN_ERR "wm8971: failed to set cache I/O: %d\n", ret); return ret; @@ -667,9 +698,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8971 = { .suspend = wm8971_suspend, .resume = wm8971_resume, .set_bias_level = wm8971_set_bias_level, - .reg_cache_size = ARRAY_SIZE(wm8971_reg), - .reg_word_size = sizeof(u16), - .reg_cache_default = wm8971_reg, .controls = wm8971_snd_controls, .num_controls = ARRAY_SIZE(wm8971_snd_controls), @@ -679,10 +707,21 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8971 = { .num_dapm_routes = ARRAY_SIZE(wm8971_dapm_routes), }; -static __devinit int wm8971_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static const struct regmap_config wm8971_regmap = { + .reg_bits = 7, + .val_bits = 9, + .max_register = WM8971_MOUTV, + + .reg_defaults = wm8971_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(wm8971_reg_defaults), + .cache_type = REGCACHE_RBTREE, +}; + +static int wm8971_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8971_priv *wm8971; + struct regmap *regmap; int ret; wm8971 = devm_kzalloc(&i2c->dev, sizeof(struct wm8971_priv), @@ -690,7 +729,10 @@ static __devinit int wm8971_i2c_probe(struct i2c_client *i2c, if (wm8971 == NULL) return -ENOMEM; - wm8971->control_type = SND_SOC_I2C; + regmap = devm_regmap_init_i2c(i2c, &wm8971_regmap); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + i2c_set_clientdata(i2c, wm8971); ret = snd_soc_register_codec(&i2c->dev, @@ -699,7 +741,7 @@ static __devinit int wm8971_i2c_probe(struct i2c_client *i2c, return ret; } -static __devexit int wm8971_i2c_remove(struct i2c_client *client) +static int wm8971_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -717,7 +759,7 @@ static struct i2c_driver wm8971_i2c_driver = { .owner = THIS_MODULE, }, .probe = wm8971_i2c_probe, - .remove = __devexit_p(wm8971_i2c_remove), + .remove = wm8971_i2c_remove, .id_table = wm8971_i2c_id, }; diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index 9a39511af52..ea58b73e86b 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c @@ -625,8 +625,8 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8974 = { .num_dapm_routes = ARRAY_SIZE(wm8974_dapm_routes), }; -static __devinit int wm8974_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8974_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { int ret; @@ -636,7 +636,7 @@ static __devinit int wm8974_i2c_probe(struct i2c_client *i2c, return ret; } -static __devexit int wm8974_i2c_remove(struct i2c_client *client) +static int wm8974_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); @@ -655,7 +655,7 @@ static struct i2c_driver wm8974_i2c_driver = { .owner = THIS_MODULE, }, .probe = wm8974_i2c_probe, - .remove = __devexit_p(wm8974_i2c_remove), + .remove = wm8974_i2c_remove, .id_table = wm8974_i2c_id, }; diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index 4c0a8e49613..f347af3a67c 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) return idx; wm8978->mclk_idx = idx; - - /* GPIO1 into default mode as input - before configuring PLL */ - snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 7, 0); } else { return -EINVAL; } @@ -1038,8 +1035,8 @@ static const struct regmap_config wm8978_regmap_config = { .num_reg_defaults = ARRAY_SIZE(wm8978_reg_defaults), }; -static __devinit int wm8978_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8978_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8978_priv *wm8978; int ret; @@ -1049,7 +1046,7 @@ static __devinit int wm8978_i2c_probe(struct i2c_client *i2c, if (wm8978 == NULL) return -ENOMEM; - wm8978->regmap = regmap_init_i2c(i2c, &wm8978_regmap_config); + wm8978->regmap = devm_regmap_init_i2c(i2c, &wm8978_regmap_config); if (IS_ERR(wm8978->regmap)) { ret = PTR_ERR(wm8978->regmap); dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret); @@ -1062,29 +1059,22 @@ static __devinit int wm8978_i2c_probe(struct i2c_client *i2c, ret = regmap_write(wm8978->regmap, WM8978_RESET, 0); if (ret != 0) { dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret); - goto err; + return ret; } ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8978, &wm8978_dai, 1); if (ret != 0) { dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); - goto err; + return ret; } return 0; - -err: - regmap_exit(wm8978->regmap); - return ret; } -static __devexit int wm8978_i2c_remove(struct i2c_client *client) +static int wm8978_i2c_remove(struct i2c_client *client) { - struct wm8978_priv *wm8978 = i2c_get_clientdata(client); - snd_soc_unregister_codec(&client->dev); - regmap_exit(wm8978->regmap); return 0; } @@ -1101,7 +1091,7 @@ static struct i2c_driver wm8978_i2c_driver = { .owner = THIS_MODULE, }, .probe = wm8978_i2c_probe, - .remove = __devexit_p(wm8978_i2c_remove), + .remove = wm8978_i2c_remove, .id_table = wm8978_i2c_id, }; diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c index d8879f262d2..9fe1e041da4 100644 --- a/sound/soc/codecs/wm8983.c +++ b/sound/soc/codecs/wm8983.c @@ -1087,7 +1087,7 @@ static const struct regmap_config wm8983_regmap = { }; #if defined(CONFIG_SPI_MASTER) -static int __devinit wm8983_spi_probe(struct spi_device *spi) +static int wm8983_spi_probe(struct spi_device *spi) { struct wm8983_priv *wm8983; int ret; @@ -1110,7 +1110,7 @@ static int __devinit wm8983_spi_probe(struct spi_device *spi) return ret; } -static int __devexit wm8983_spi_remove(struct spi_device *spi) +static int wm8983_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev); return 0; @@ -1122,13 +1122,13 @@ static struct spi_driver wm8983_spi_driver = { .owner = THIS_MODULE, }, .probe = wm8983_spi_probe, - .remove = __devexit_p(wm8983_spi_remove) + .remove = wm8983_spi_remove }; #endif #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static __devinit int wm8983_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8983_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8983_priv *wm8983; int ret; @@ -1152,7 +1152,7 @@ static __devinit int wm8983_i2c_probe(struct i2c_client *i2c, return ret; } -static __devexit int wm8983_i2c_remove(struct i2c_client *client) +static int wm8983_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; @@ -1170,7 +1170,7 @@ static struct i2c_driver wm8983_i2c_driver = { .owner = THIS_MODULE, }, .probe = wm8983_i2c_probe, - .remove = __devexit_p(wm8983_i2c_remove), + .remove = wm8983_i2c_remove, .id_table = wm8983_i2c_id }; #endif diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index 14f666398d0..ab3782657ac 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c @@ -1111,7 +1111,7 @@ static const struct regmap_config wm8985_regmap = { }; #if defined(CONFIG_SPI_MASTER) -static int __devinit wm8985_spi_probe(struct spi_device *spi) +static int wm8985_spi_probe(struct spi_device *spi) { struct wm8985_priv *wm8985; int ret; @@ -1122,33 +1122,22 @@ static int __devinit wm8985_spi_probe(struct spi_device *spi) spi_set_drvdata(spi, wm8985); - wm8985->regmap = regmap_init_spi(spi, &wm8985_regmap); + wm8985->regmap = devm_regmap_init_spi(spi, &wm8985_regmap); if (IS_ERR(wm8985->regmap)) { ret = PTR_ERR(wm8985->regmap); dev_err(&spi->dev, "Failed to allocate register map: %d\n", ret); - goto err; + return ret; } ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_wm8985, &wm8985_dai, 1); - if (ret != 0) - goto err; - - return 0; - -err: - regmap_exit(wm8985->regmap); return ret; } -static int __devexit wm8985_spi_remove(struct spi_device *spi) +static int wm8985_spi_remove(struct spi_device *spi) { - struct wm8985_priv *wm8985 = spi_get_drvdata(spi); - snd_soc_unregister_codec(&spi->dev); - regmap_exit(wm8985->regmap); - return 0; } @@ -1158,13 +1147,13 @@ static struct spi_driver wm8985_spi_driver = { .owner = THIS_MODULE, }, .probe = wm8985_spi_probe, - .remove = __devexit_p(wm8985_spi_remove) + .remove = wm8985_spi_remove }; #endif #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static __devinit int wm8985_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8985_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8985_priv *wm8985; int ret; @@ -1175,33 +1164,22 @@ static __devinit int wm8985_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, wm8985); - wm8985->regmap = regmap_init_i2c(i2c, &wm8985_regmap); + wm8985->regmap = devm_regmap_init_i2c(i2c, &wm8985_regmap); if (IS_ERR(wm8985->regmap)) { ret = PTR_ERR(wm8985->regmap); dev_err(&i2c->dev, "Failed to allocate register map: %d\n", ret); - goto err; + return ret; } ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8985, &wm8985_dai, 1); - if (ret != 0) - goto err; - - return 0; - -err: - regmap_exit(wm8985->regmap); return ret; } -static __devexit int wm8985_i2c_remove(struct i2c_client *i2c) +static int wm8985_i2c_remove(struct i2c_client *i2c) { - struct wm8985_priv *wm8985 = i2c_get_clientdata(i2c); - snd_soc_unregister_codec(&i2c->dev); - regmap_exit(wm8985->regmap); - return 0; } @@ -1217,7 +1195,7 @@ static struct i2c_driver wm8985_i2c_driver = { .owner = THIS_MODULE, }, .probe = wm8985_i2c_probe, - .remove = __devexit_p(wm8985_i2c_remove), + .remove = wm8985_i2c_remove, .id_table = wm8985_i2c_id }; #endif diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index 1d4c5cf47b0..39b9acceb59 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c @@ -872,7 +872,7 @@ static struct regmap_config wm8988_regmap = { }; #if defined(CONFIG_SPI_MASTER) -static int __devinit wm8988_spi_probe(struct spi_device *spi) +static int wm8988_spi_probe(struct spi_device *spi) { struct wm8988_priv *wm8988; int ret; @@ -882,7 +882,7 @@ static int __devinit wm8988_spi_probe(struct spi_device *spi) if (wm8988 == NULL) return -ENOMEM; - wm8988->regmap = regmap_init_spi(spi, &wm8988_regmap); + wm8988->regmap = devm_regmap_init_spi(spi, &wm8988_regmap); if (IS_ERR(wm8988->regmap)) { ret = PTR_ERR(wm8988->regmap); 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) ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_wm8988, &wm8988_dai, 1); - if (ret != 0) - regmap_exit(wm8988->regmap); - return ret; } -static int __devexit wm8988_spi_remove(struct spi_device *spi) +static int wm8988_spi_remove(struct spi_device *spi) { - struct wm8988_priv *wm8988 = spi_get_drvdata(spi); snd_soc_unregister_codec(&spi->dev); - regmap_exit(wm8988->regmap); return 0; } @@ -913,13 +908,13 @@ static struct spi_driver wm8988_spi_driver = { .owner = THIS_MODULE, }, .probe = wm8988_spi_probe, - .remove = __devexit_p(wm8988_spi_remove), + .remove = wm8988_spi_remove, }; #endif /* CONFIG_SPI_MASTER */ #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static __devinit int wm8988_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8988_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8988_priv *wm8988; int ret; @@ -931,7 +926,7 @@ static __devinit int wm8988_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, wm8988); - wm8988->regmap = regmap_init_i2c(i2c, &wm8988_regmap); + wm8988->regmap = devm_regmap_init_i2c(i2c, &wm8988_regmap); if (IS_ERR(wm8988->regmap)) { ret = PTR_ERR(wm8988->regmap); 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, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8988, &wm8988_dai, 1); - if (ret != 0) - regmap_exit(wm8988->regmap); - return ret; } -static __devexit int wm8988_i2c_remove(struct i2c_client *client) +static int wm8988_i2c_remove(struct i2c_client *client) { - struct wm8988_priv *wm8988 = i2c_get_clientdata(client); snd_soc_unregister_codec(&client->dev); - regmap_exit(wm8988->regmap); return 0; } @@ -966,7 +956,7 @@ static struct i2c_driver wm8988_i2c_driver = { .owner = THIS_MODULE, }, .probe = wm8988_i2c_probe, - .remove = __devexit_p(wm8988_i2c_remove), + .remove = wm8988_i2c_remove, .id_table = wm8988_i2c_id, }; #endif diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index c28c83e5395..837978e16e9 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c @@ -1382,8 +1382,8 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8990 = { }; #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static __devinit int wm8990_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8990_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8990_priv *wm8990; int ret; @@ -1401,7 +1401,7 @@ static __devinit int wm8990_i2c_probe(struct i2c_client *i2c, return ret; } -static __devexit int wm8990_i2c_remove(struct i2c_client *client) +static int wm8990_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); @@ -1420,7 +1420,7 @@ static struct i2c_driver wm8990_i2c_driver = { .owner = THIS_MODULE, }, .probe = wm8990_i2c_probe, - .remove = __devexit_p(wm8990_i2c_remove), + .remove = wm8990_i2c_remove, .id_table = wm8990_i2c_id, }; #endif diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c index fe439f027e1..3a39df7a382 100644 --- a/sound/soc/codecs/wm8991.c +++ b/sound/soc/codecs/wm8991.c @@ -1357,8 +1357,8 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8991 = { .reg_cache_default = wm8991_reg_defs }; -static __devinit int wm8991_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8991_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8991_priv *wm8991; int ret; @@ -1376,7 +1376,7 @@ static __devinit int wm8991_i2c_probe(struct i2c_client *i2c, return ret; } -static __devexit int wm8991_i2c_remove(struct i2c_client *client) +static int wm8991_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); @@ -1395,7 +1395,7 @@ static struct i2c_driver wm8991_i2c_driver = { .owner = THIS_MODULE, }, .probe = wm8991_i2c_probe, - .remove = __devexit_p(wm8991_i2c_remove), + .remove = wm8991_i2c_remove, .id_table = wm8991_i2c_id, }; diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 94737a30716..433d59a0f3e 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -1645,8 +1645,8 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8993 = { .set_bias_level = wm8993_set_bias_level, }; -static __devinit int wm8993_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8993_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8993_priv *wm8993; unsigned int reg; @@ -1660,7 +1660,7 @@ static __devinit int wm8993_i2c_probe(struct i2c_client *i2c, wm8993->dev = &i2c->dev; init_completion(&wm8993->fll_lock); - wm8993->regmap = regmap_init_i2c(i2c, &wm8993_regmap); + wm8993->regmap = devm_regmap_init_i2c(i2c, &wm8993_regmap); if (IS_ERR(wm8993->regmap)) { ret = PTR_ERR(wm8993->regmap); 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, for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++) wm8993->supplies[i].supply = wm8993_supply_names[i]; - ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8993->supplies), + ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8993->supplies), wm8993->supplies); if (ret != 0) { dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); - goto err; + return ret; } ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); if (ret != 0) { dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); - goto err_get; + return ret; } ret = regmap_read(wm8993->regmap, WM8993_SOFTWARE_RESET, ®); @@ -1742,23 +1742,17 @@ err_irq: free_irq(i2c->irq, wm8993); err_enable: regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); -err_get: - regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); -err: - regmap_exit(wm8993->regmap); return ret; } -static __devexit int wm8993_i2c_remove(struct i2c_client *i2c) +static int wm8993_i2c_remove(struct i2c_client *i2c) { struct wm8993_priv *wm8993 = i2c_get_clientdata(i2c); snd_soc_unregister_codec(&i2c->dev); if (i2c->irq) free_irq(i2c->irq, wm8993); - regmap_exit(wm8993->regmap); regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); - regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); return 0; } @@ -1775,7 +1769,7 @@ static struct i2c_driver wm8993_i2c_driver = { .owner = THIS_MODULE, }, .probe = wm8993_i2c_probe, - .remove = __devexit_p(wm8993_i2c_remove), + .remove = wm8993_i2c_remove, .id_table = wm8993_i2c_id, }; diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index b2b2b37131b..3b269fa226b 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -91,8 +91,6 @@ static int wm8994_retune_mobile_base[] = { WM8994_AIF2_EQ_GAINS_1, }; -static void wm8958_default_micdet(u16 status, void *data); - static const struct wm8958_micd_rate micdet_rates[] = { { 32768, true, 1, 4 }, { 32768, false, 1, 1 }, @@ -110,15 +108,12 @@ static const struct wm8958_micd_rate jackdet_rates[] = { static void wm8958_micd_set_rate(struct snd_soc_codec *codec) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994 *control = wm8994->wm8994; int best, i, sysclk, val; bool idle; const struct wm8958_micd_rate *rates; int num_rates; - if (!(wm8994->pdata && wm8994->pdata->micd_rates) && - wm8994->jack_cb != wm8958_default_micdet) - return; - idle = !wm8994->jack_mic; sysclk = snd_soc_read(codec, WM8994_CLOCKING_1); @@ -127,9 +122,9 @@ static void wm8958_micd_set_rate(struct snd_soc_codec *codec) else sysclk = wm8994->aifclk[0]; - if (wm8994->pdata && wm8994->pdata->micd_rates) { - rates = wm8994->pdata->micd_rates; - num_rates = wm8994->pdata->num_micd_rates; + if (control->pdata.micd_rates) { + rates = control->pdata.micd_rates; + num_rates = control->pdata.num_micd_rates; } else if (wm8994->jackdet) { rates = jackdet_rates; num_rates = ARRAY_SIZE(jackdet_rates); @@ -326,7 +321,8 @@ static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol, static void wm8994_set_drc(struct snd_soc_codec *codec, int drc) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - struct wm8994_pdata *pdata = wm8994->pdata; + struct wm8994 *control = wm8994->wm8994; + struct wm8994_pdata *pdata = &control->pdata; int base = wm8994_drc_base[drc]; int cfg = wm8994->drc_cfg[drc]; int save, i; @@ -362,7 +358,8 @@ static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - struct wm8994_pdata *pdata = wm8994->pdata; + struct wm8994 *control = wm8994->wm8994; + struct wm8994_pdata *pdata = &control->pdata; int drc = wm8994_get_drc(kcontrol->id.name); int value = ucontrol->value.integer.value[0]; @@ -394,7 +391,8 @@ static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol, static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - struct wm8994_pdata *pdata = wm8994->pdata; + struct wm8994 *control = wm8994->wm8994; + struct wm8994_pdata *pdata = &control->pdata; int base = wm8994_retune_mobile_base[block]; int iface, best, best_val, save, i, cfg; @@ -465,7 +463,8 @@ static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - struct wm8994_pdata *pdata = wm8994->pdata; + struct wm8994 *control = wm8994->wm8994; + struct wm8994_pdata *pdata = &control->pdata; int block = wm8994_get_retune_mobile_block(kcontrol->id.name); int value = ucontrol->value.integer.value[0]; @@ -736,7 +735,7 @@ static void wm1811_jackdet_set_mode(struct snd_soc_codec *codec, u16 mode) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - if (!wm8994->jackdet || !wm8994->jack_cb) + if (!wm8994->jackdet || !wm8994->micdet[0].jack) return; if (wm8994->active_refcount) @@ -862,7 +861,7 @@ static void vmid_reference(struct snd_soc_codec *codec) WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA | WM8994_VMID_BUF_ENA | - (0x3 << WM8994_VMID_RAMP_SHIFT)); + (0x2 << WM8994_VMID_RAMP_SHIFT)); /* Main bias enable, VMID=2x40k */ snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, @@ -870,7 +869,7 @@ static void vmid_reference(struct snd_soc_codec *codec) WM8994_VMID_SEL_MASK, WM8994_BIAS_ENA | 0x2); - msleep(50); + msleep(300); snd_soc_update_bits(codec, WM8994_ANTIPOP_2, WM8994_VMID_RAMP_MASK | @@ -939,16 +938,10 @@ static void vmid_dereference(struct snd_soc_codec *codec) WM8994_BIAS_SRC | WM8994_VMID_DISCH); - switch (wm8994->vmid_mode) { - case WM8994_VMID_FORCE: - msleep(350); - break; - default: - break; - } + snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, + WM8994_VMID_SEL_MASK, 0); - snd_soc_update_bits(codec, WM8994_ADDITIONAL_CONTROL, - WM8994_VROI, WM8994_VROI); + msleep(400); /* Active discharge */ snd_soc_update_bits(codec, WM8994_ANTIPOP_1, @@ -957,17 +950,12 @@ static void vmid_dereference(struct snd_soc_codec *codec) WM8994_LINEOUT1_DISCH | WM8994_LINEOUT2_DISCH); - msleep(150); - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_3, WM8994_LINEOUT1N_ENA | WM8994_LINEOUT1P_ENA | WM8994_LINEOUT2N_ENA | WM8994_LINEOUT2P_ENA, 0); - snd_soc_update_bits(codec, WM8994_ADDITIONAL_CONTROL, - WM8994_VROI, 0); - /* Switch off startup biases */ snd_soc_update_bits(codec, WM8994_ANTIPOP_2, WM8994_BIAS_SRC | @@ -976,10 +964,7 @@ static void vmid_dereference(struct snd_soc_codec *codec) WM8994_VMID_RAMP_MASK, 0); snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, - WM8994_BIAS_ENA | WM8994_VMID_SEL_MASK, 0); - - snd_soc_update_bits(codec, WM8994_ANTIPOP_2, - WM8994_VMID_RAMP_MASK, 0); + WM8994_VMID_SEL_MASK, 0); } pm_runtime_put(codec->dev); @@ -2277,6 +2262,18 @@ out: configure_clock(codec); + /* + * If SYSCLK will be less than 50kHz adjust AIFnCLK dividers + * for detection. + */ + if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) { + dev_dbg(codec->dev, "Configuring AIFs for 128fs\n"); + snd_soc_update_bits(codec, WM8994_AIF1_RATE, + WM8994_AIF1CLK_RATE_MASK, 0x1); + snd_soc_update_bits(codec, WM8994_AIF2_RATE, + WM8994_AIF2CLK_RATE_MASK, 0x1); + } + return 0; } @@ -2365,6 +2362,18 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, configure_clock(codec); + /* + * If SYSCLK will be less than 50kHz adjust AIFnCLK dividers + * for detection. + */ + if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) { + dev_dbg(codec->dev, "Configuring AIFs for 128fs\n"); + snd_soc_update_bits(codec, WM8994_AIF1_RATE, + WM8994_AIF1CLK_RATE_MASK, 0x1); + snd_soc_update_bits(codec, WM8994_AIF2_RATE, + WM8994_AIF2CLK_RATE_MASK, 0x1); + } + return 0; } @@ -3082,7 +3091,8 @@ static int wm8994_codec_resume(struct snd_soc_codec *codec) static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) { struct snd_soc_codec *codec = wm8994->hubs.codec; - struct wm8994_pdata *pdata = wm8994->pdata; + struct wm8994 *control = wm8994->wm8994; + struct wm8994_pdata *pdata = &control->pdata; struct snd_kcontrol_new controls[] = { SOC_ENUM_EXT("AIF1.1 EQ Mode", wm8994->retune_mobile_enum, @@ -3149,7 +3159,8 @@ static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) static void wm8994_handle_pdata(struct wm8994_priv *wm8994) { struct snd_soc_codec *codec = wm8994->hubs.codec; - struct wm8994_pdata *pdata = wm8994->pdata; + struct wm8994 *control = wm8994->wm8994; + struct wm8994_pdata *pdata = &control->pdata; int ret, i; if (!pdata) @@ -3389,38 +3400,80 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data) return IRQ_HANDLED; } -/* Default microphone detection handler for WM8958 - the user can - * override this if they wish. - */ -static void wm8958_default_micdet(u16 status, void *data) +static void wm1811_micd_stop(struct snd_soc_codec *codec) +{ + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + if (!wm8994->jackdet) + return; + + mutex_lock(&wm8994->accdet_lock); + + snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, WM8958_MICD_ENA, 0); + + wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_JACK); + + mutex_unlock(&wm8994->accdet_lock); + + if (wm8994->wm8994->pdata.jd_ext_cap) + snd_soc_dapm_disable_pin(&codec->dapm, + "MICBIAS2"); +} + +static void wm8958_button_det(struct snd_soc_codec *codec, u16 status) { - struct snd_soc_codec *codec = data; struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); int report; - dev_dbg(codec->dev, "MICDET %x\n", status); + report = 0; + if (status & 0x4) + report |= SND_JACK_BTN_0; + + if (status & 0x8) + report |= SND_JACK_BTN_1; + + if (status & 0x10) + report |= SND_JACK_BTN_2; + + if (status & 0x20) + report |= SND_JACK_BTN_3; + + if (status & 0x40) + report |= SND_JACK_BTN_4; + + if (status & 0x80) + report |= SND_JACK_BTN_5; + + snd_soc_jack_report(wm8994->micdet[0].jack, report, + wm8994->btn_mask); +} + +static void wm8958_mic_id(void *data, u16 status) +{ + struct snd_soc_codec *codec = data; + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); /* Either nothing present or just starting detection */ if (!(status & WM8958_MICD_STS)) { - if (!wm8994->jackdet) { - /* If nothing present then clear our statuses */ - dev_dbg(codec->dev, "Detected open circuit\n"); - wm8994->jack_mic = false; - wm8994->mic_detecting = true; + /* If nothing present then clear our statuses */ + dev_dbg(codec->dev, "Detected open circuit\n"); + wm8994->jack_mic = false; + wm8994->mic_detecting = true; - wm8958_micd_set_rate(codec); + wm1811_micd_stop(codec); - snd_soc_jack_report(wm8994->micdet[0].jack, 0, - wm8994->btn_mask | - SND_JACK_HEADSET); - } + wm8958_micd_set_rate(codec); + + snd_soc_jack_report(wm8994->micdet[0].jack, 0, + wm8994->btn_mask | + SND_JACK_HEADSET); return; } /* If the measurement is showing a high impedence we've got a * microphone. */ - if (wm8994->mic_detecting && (status & 0x600)) { + if (status & 0x600) { dev_dbg(codec->dev, "Detected microphone\n"); wm8994->mic_detecting = false; @@ -3433,64 +3486,67 @@ static void wm8958_default_micdet(u16 status, void *data) } - if (wm8994->mic_detecting && status & 0xfc) { + if (status & 0xfc) { dev_dbg(codec->dev, "Detected headphone\n"); wm8994->mic_detecting = false; wm8958_micd_set_rate(codec); /* If we have jackdet that will detect removal */ - if (wm8994->jackdet) { - mutex_lock(&wm8994->accdet_lock); - - snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, - WM8958_MICD_ENA, 0); - - wm1811_jackdet_set_mode(codec, - WM1811_JACKDET_MODE_JACK); - - mutex_unlock(&wm8994->accdet_lock); - - if (wm8994->pdata->jd_ext_cap) - snd_soc_dapm_disable_pin(&codec->dapm, - "MICBIAS2"); - } + wm1811_micd_stop(codec); snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADPHONE, SND_JACK_HEADSET); } +} - /* Report short circuit as a button */ - if (wm8994->jack_mic) { - report = 0; - if (status & 0x4) - report |= SND_JACK_BTN_0; +/* Deferred mic detection to allow for extra settling time */ +static void wm1811_mic_work(struct work_struct *work) +{ + struct wm8994_priv *wm8994 = container_of(work, struct wm8994_priv, + mic_work.work); + struct wm8994 *control = wm8994->wm8994; + struct snd_soc_codec *codec = wm8994->hubs.codec; - if (status & 0x8) - report |= SND_JACK_BTN_1; + pm_runtime_get_sync(codec->dev); - if (status & 0x10) - report |= SND_JACK_BTN_2; + /* If required for an external cap force MICBIAS on */ + if (control->pdata.jd_ext_cap) { + snd_soc_dapm_force_enable_pin(&codec->dapm, + "MICBIAS2"); + snd_soc_dapm_sync(&codec->dapm); + } - if (status & 0x20) - report |= SND_JACK_BTN_3; + mutex_lock(&wm8994->accdet_lock); - if (status & 0x40) - report |= SND_JACK_BTN_4; + dev_dbg(codec->dev, "Starting mic detection\n"); - if (status & 0x80) - report |= SND_JACK_BTN_5; + /* Use a user-supplied callback if we have one */ + if (wm8994->micd_cb) { + wm8994->micd_cb(wm8994->micd_cb_data); + } else { + /* + * Start off measument of microphone impedence to find out + * what's actually there. + */ + wm8994->mic_detecting = true; + wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC); - snd_soc_jack_report(wm8994->micdet[0].jack, report, - wm8994->btn_mask); + snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, + WM8958_MICD_ENA, WM8958_MICD_ENA); } + + mutex_unlock(&wm8994->accdet_lock); + + pm_runtime_put(codec->dev); } static irqreturn_t wm1811_jackdet_irq(int irq, void *data) { struct wm8994_priv *wm8994 = data; + struct wm8994 *control = wm8994->wm8994; struct snd_soc_codec *codec = wm8994->hubs.codec; - int reg; + int reg, delay; bool present; pm_runtime_get_sync(codec->dev); @@ -3521,18 +3577,14 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) snd_soc_update_bits(codec, WM1811_JACKDET_CTRL, WM1811_JACKDET_DB, 0); - /* - * Start off measument of microphone impedence to find - * out what's actually there. - */ - wm8994->mic_detecting = true; - wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC); - - snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, - WM8958_MICD_ENA, WM8958_MICD_ENA); + delay = control->pdata.micdet_delay; + schedule_delayed_work(&wm8994->mic_work, + msecs_to_jiffies(delay)); } else { dev_dbg(codec->dev, "Jack not detected\n"); + cancel_delayed_work_sync(&wm8994->mic_work); + snd_soc_update_bits(codec, WM8958_MICBIAS2, WM8958_MICB2_DISCH, WM8958_MICB2_DISCH); @@ -3549,14 +3601,9 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) mutex_unlock(&wm8994->accdet_lock); - /* If required for an external cap force MICBIAS on */ - if (wm8994->pdata->jd_ext_cap) { - if (present) - snd_soc_dapm_force_enable_pin(&codec->dapm, - "MICBIAS2"); - else - snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2"); - } + /* Turn off MICBIAS if it was on for an external cap */ + if (control->pdata.jd_ext_cap && !present) + snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2"); if (present) snd_soc_jack_report(wm8994->micdet[0].jack, @@ -3599,7 +3646,8 @@ static void wm1811_jackdet_bootstrap(struct work_struct *work) * detection algorithm. */ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, - wm8958_micdet_cb cb, void *cb_data) + wm1811_micdet_cb det_cb, void *det_cb_data, + wm1811_mic_id_cb id_cb, void *id_cb_data) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994 *control = wm8994->wm8994; @@ -3614,27 +3662,32 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, } if (jack) { - if (!cb) { - dev_dbg(codec->dev, "Using default micdet callback\n"); - cb = wm8958_default_micdet; - cb_data = codec; - } - snd_soc_dapm_force_enable_pin(&codec->dapm, "CLK_SYS"); snd_soc_dapm_sync(&codec->dapm); wm8994->micdet[0].jack = jack; - wm8994->jack_cb = cb; - wm8994->jack_cb_data = cb_data; - wm8994->mic_detecting = true; - wm8994->jack_mic = false; + if (det_cb) { + wm8994->micd_cb = det_cb; + wm8994->micd_cb_data = det_cb_data; + } else { + wm8994->mic_detecting = true; + wm8994->jack_mic = false; + } + + if (id_cb) { + wm8994->mic_id_cb = id_cb; + wm8994->mic_id_cb_data = id_cb_data; + } else { + wm8994->mic_id_cb = wm8958_mic_id; + wm8994->mic_id_cb_data = codec; + } wm8958_micd_set_rate(codec); /* Detect microphones and short circuits by default */ - if (wm8994->pdata->micd_lvl_sel) - micd_lvl_sel = wm8994->pdata->micd_lvl_sel; + if (control->pdata.micd_lvl_sel) + micd_lvl_sel = control->pdata.micd_lvl_sel; else micd_lvl_sel = 0x41; @@ -3728,10 +3781,22 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) trace_snd_soc_jack_irq(dev_name(codec->dev)); #endif - if (wm8994->jack_cb) - wm8994->jack_cb(reg, wm8994->jack_cb_data); + /* Avoid a transient report when the accessory is being removed */ + if (wm8994->jackdet) { + reg = snd_soc_read(codec, WM1811_JACKDET_CTRL); + if (reg < 0) { + dev_err(codec->dev, "Failed to read jack status: %d\n", + reg); + } else if (!(reg & WM1811_JACKDET_LVL)) { + dev_dbg(codec->dev, "Ignoring removed jack\n"); + return IRQ_HANDLED; + } + } + + if (wm8994->mic_detecting) + wm8994->mic_id_cb(wm8994->mic_id_cb_data, reg); else - dev_warn(codec->dev, "Accessory detection with no callback\n"); + wm8958_button_det(codec, reg); out: pm_runtime_put(codec->dev); @@ -3779,15 +3844,24 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); mutex_init(&wm8994->accdet_lock); - INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work); INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap, wm1811_jackdet_bootstrap); + switch (control->type) { + case WM8994: + INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work); + break; + case WM1811: + INIT_DELAYED_WORK(&wm8994->mic_work, wm1811_mic_work); + break; + default: + break; + } + for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) init_completion(&wm8994->fll_locked[i]); - if (wm8994->pdata && wm8994->pdata->micdet_irq) - wm8994->micdet_irq = wm8994->pdata->micdet_irq; + wm8994->micdet_irq = control->pdata.micdet_irq; pm_runtime_enable(codec->dev); pm_runtime_idle(codec->dev); @@ -3800,8 +3874,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) switch (control->type) { case WM8994: /* Single ended line outputs should have VMID on. */ - if (!wm8994->pdata->lineout1_diff || - !wm8994->pdata->lineout2_diff) + if (!control->pdata.lineout1_diff || + !control->pdata.lineout2_diff) codec->dapm.idle_bias_off = 0; switch (wm8994->revision) { @@ -3839,20 +3913,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) wm8994->hubs.no_cache_dac_hp_direct = true; wm8994->fll_byp = true; - switch (control->cust_id) { - case 0: - case 2: - wm8994->hubs.dcs_codes_l = -9; - wm8994->hubs.dcs_codes_r = -7; - break; - case 1: - case 3: - wm8994->hubs.dcs_codes_l = -8; - wm8994->hubs.dcs_codes_r = -7; - break; - default: - break; - } + wm8994->hubs.dcs_codes_l = -9; + wm8994->hubs.dcs_codes_r = -7; snd_soc_update_bits(codec, WM8994_ANALOGUE_HP_1, WM1811_HPOUT1_ATTN, WM1811_HPOUT1_ATTN); @@ -4225,7 +4287,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8994 = { .set_bias_level = wm8994_set_bias_level, }; -static int __devinit wm8994_probe(struct platform_device *pdev) +static int wm8994_probe(struct platform_device *pdev) { struct wm8994_priv *wm8994; @@ -4236,13 +4298,12 @@ static int __devinit wm8994_probe(struct platform_device *pdev) platform_set_drvdata(pdev, wm8994); wm8994->wm8994 = dev_get_drvdata(pdev->dev.parent); - wm8994->pdata = dev_get_platdata(pdev->dev.parent); return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8994, wm8994_dai, ARRAY_SIZE(wm8994_dai)); } -static int __devexit wm8994_remove(struct platform_device *pdev) +static int wm8994_remove(struct platform_device *pdev) { snd_soc_unregister_codec(&pdev->dev); return 0; @@ -4266,7 +4327,7 @@ static int wm8994_resume(struct device *dev) { struct wm8994_priv *wm8994 = dev_get_drvdata(dev); - if (wm8994->jackdet && wm8994->jack_cb) + if (wm8994->jackdet && wm8994->jackdet_mode) regmap_update_bits(wm8994->wm8994->regmap, WM8994_ANTIPOP_2, WM1811_JACKDET_MODE_MASK, WM1811_JACKDET_MODE_AUDIO); @@ -4286,7 +4347,7 @@ static struct platform_driver wm8994_codec_driver = { .pm = &wm8994_pm_ops, }, .probe = wm8994_probe, - .remove = __devexit_p(wm8994_remove), + .remove = wm8994_remove, }; module_platform_driver(wm8994_codec_driver); diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index ccbce5791e9..45f19270202 100644 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h @@ -39,12 +39,14 @@ enum wm8994_vmid_mode { WM8994_VMID_FORCE, }; -typedef void (*wm8958_micdet_cb)(u16 status, void *data); +typedef void (*wm1811_micdet_cb)(void *data); +typedef void (*wm1811_mic_id_cb)(void *data, u16 status); int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, int micbias); int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, - wm8958_micdet_cb cb, void *cb_data); + wm1811_micdet_cb cb, void *det_cb_data, + wm1811_mic_id_cb id_cb, void *id_cb_data); int wm8994_vmid_mode(struct snd_soc_codec *codec, enum wm8994_vmid_mode mode); @@ -138,12 +140,13 @@ struct wm8994_priv { int jackdet_mode; struct delayed_work jackdet_bootstrap; - wm8958_micdet_cb jack_cb; - void *jack_cb_data; int micdet_irq; + wm1811_micdet_cb micd_cb; + void *micd_cb_data; + wm1811_mic_id_cb mic_id_cb; + void *mic_id_cb_data; int revision; - struct wm8994_pdata *pdata; unsigned int aif1clk_enable:1; unsigned int aif2clk_enable:1; diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c index 28c89b094c6..90a65c42754 100644 --- a/sound/soc/codecs/wm8995.c +++ b/sound/soc/codecs/wm8995.c @@ -2256,46 +2256,33 @@ static struct regmap_config wm8995_regmap = { }; #if defined(CONFIG_SPI_MASTER) -static int __devinit wm8995_spi_probe(struct spi_device *spi) +static int wm8995_spi_probe(struct spi_device *spi) { struct wm8995_priv *wm8995; int ret; - wm8995 = kzalloc(sizeof *wm8995, GFP_KERNEL); + wm8995 = devm_kzalloc(&spi->dev, sizeof(*wm8995), GFP_KERNEL); if (!wm8995) return -ENOMEM; spi_set_drvdata(spi, wm8995); - wm8995->regmap = regmap_init_spi(spi, &wm8995_regmap); + wm8995->regmap = devm_regmap_init_spi(spi, &wm8995_regmap); if (IS_ERR(wm8995->regmap)) { ret = PTR_ERR(wm8995->regmap); dev_err(&spi->dev, "Failed to register regmap: %d\n", ret); - goto err_alloc; + return ret; } ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_wm8995, wm8995_dai, ARRAY_SIZE(wm8995_dai)); - if (ret < 0) - goto err_regmap; - - return ret; - -err_regmap: - regmap_exit(wm8995->regmap); -err_alloc: - kfree(wm8995); - return ret; } -static int __devexit wm8995_spi_remove(struct spi_device *spi) +static int wm8995_spi_remove(struct spi_device *spi) { - struct wm8995_priv *wm8995 = spi_get_drvdata(spi); snd_soc_unregister_codec(&spi->dev); - regmap_exit(wm8995->regmap); - kfree(wm8995); return 0; } @@ -2305,55 +2292,42 @@ static struct spi_driver wm8995_spi_driver = { .owner = THIS_MODULE, }, .probe = wm8995_spi_probe, - .remove = __devexit_p(wm8995_spi_remove) + .remove = wm8995_spi_remove }; #endif #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static __devinit int wm8995_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8995_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8995_priv *wm8995; int ret; - wm8995 = kzalloc(sizeof *wm8995, GFP_KERNEL); + wm8995 = devm_kzalloc(&i2c->dev, sizeof(*wm8995), GFP_KERNEL); if (!wm8995) return -ENOMEM; i2c_set_clientdata(i2c, wm8995); - wm8995->regmap = regmap_init_i2c(i2c, &wm8995_regmap); + wm8995->regmap = devm_regmap_init_i2c(i2c, &wm8995_regmap); if (IS_ERR(wm8995->regmap)) { ret = PTR_ERR(wm8995->regmap); dev_err(&i2c->dev, "Failed to register regmap: %d\n", ret); - goto err_alloc; + return ret; } ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8995, wm8995_dai, ARRAY_SIZE(wm8995_dai)); - if (ret < 0) { + if (ret < 0) dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); - goto err_regmap; - } - - return ret; - -err_regmap: - regmap_exit(wm8995->regmap); -err_alloc: - kfree(wm8995); return ret; } -static __devexit int wm8995_i2c_remove(struct i2c_client *client) +static int wm8995_i2c_remove(struct i2c_client *client) { - struct wm8995_priv *wm8995 = i2c_get_clientdata(client); - snd_soc_unregister_codec(&client->dev); - regmap_exit(wm8995->regmap); - kfree(wm8995); return 0; } @@ -2370,7 +2344,7 @@ static struct i2c_driver wm8995_i2c_driver = { .owner = THIS_MODULE, }, .probe = wm8995_i2c_probe, - .remove = __devexit_p(wm8995_i2c_remove), + .remove = wm8995_i2c_remove, .id_table = wm8995_i2c_id }; #endif diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index 6dcb02c3666..46fe83d2b22 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c @@ -2765,8 +2765,8 @@ static struct snd_soc_dai_driver wm8996_dai[] = { }, }; -static __devinit int wm8996_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8996_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8996_priv *wm8996; int ret, i; @@ -3077,7 +3077,7 @@ err: return ret; } -static __devexit int wm8996_i2c_remove(struct i2c_client *client) +static int wm8996_i2c_remove(struct i2c_client *client) { struct wm8996_priv *wm8996 = i2c_get_clientdata(client); int i; @@ -3107,7 +3107,7 @@ static struct i2c_driver wm8996_i2c_driver = { .owner = THIS_MODULE, }, .probe = wm8996_i2c_probe, - .remove = __devexit_p(wm8996_i2c_remove), + .remove = wm8996_i2c_remove, .id_table = wm8996_i2c_id, }; diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index 2de74e1ea22..630b3d776ec 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c @@ -1327,8 +1327,8 @@ static const struct regmap_config wm9081_regmap = { }; #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static __devinit int wm9081_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm9081_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm9081_priv *wm9081; unsigned int reg; @@ -1341,28 +1341,27 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, wm9081); - wm9081->regmap = regmap_init_i2c(i2c, &wm9081_regmap); + wm9081->regmap = devm_regmap_init_i2c(i2c, &wm9081_regmap); if (IS_ERR(wm9081->regmap)) { ret = PTR_ERR(wm9081->regmap); dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); - goto err; + return ret; } ret = regmap_read(wm9081->regmap, WM9081_SOFTWARE_RESET, ®); if (ret != 0) { dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret); - goto err_regmap; + return ret; } if (reg != 0x9081) { dev_err(&i2c->dev, "Device is not a WM9081: ID=0x%x\n", reg); - ret = -EINVAL; - goto err_regmap; + return -EINVAL; } ret = wm9081_reset(wm9081->regmap); if (ret < 0) { dev_err(&i2c->dev, "Failed to issue reset\n"); - goto err_regmap; + return ret; } if (dev_get_platdata(&i2c->dev)) @@ -1382,23 +1381,14 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm9081, &wm9081_dai, 1); if (ret < 0) - goto err_regmap; + return ret; return 0; - -err_regmap: - regmap_exit(wm9081->regmap); -err: - - return ret; } -static __devexit int wm9081_i2c_remove(struct i2c_client *client) +static int wm9081_i2c_remove(struct i2c_client *client) { - struct wm9081_priv *wm9081 = i2c_get_clientdata(client); - snd_soc_unregister_codec(&client->dev); - regmap_exit(wm9081->regmap); return 0; } @@ -1414,7 +1404,7 @@ static struct i2c_driver wm9081_i2c_driver = { .owner = THIS_MODULE, }, .probe = wm9081_i2c_probe, - .remove = __devexit_p(wm9081_i2c_remove), + .remove = wm9081_i2c_remove, .id_table = wm9081_i2c_id, }; #endif diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c index c7ddc56175d..a07fe1618ee 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, return -ENOMEM; } - wm9090->regmap = regmap_init_i2c(i2c, &wm9090_regmap); + wm9090->regmap = devm_regmap_init_i2c(i2c, &wm9090_regmap); if (IS_ERR(wm9090->regmap)) { ret = PTR_ERR(wm9090->regmap); dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret); @@ -637,16 +637,16 @@ static int wm9090_i2c_probe(struct i2c_client *i2c, ret = regmap_read(wm9090->regmap, WM9090_SOFTWARE_RESET, ®); if (ret < 0) - goto err; + return ret; + if (reg != 0x9093) { dev_err(&i2c->dev, "Device is not a WM9090, ID=%x\n", reg); - ret = -ENODEV; - goto err; + return -ENODEV; } ret = regmap_write(wm9090->regmap, WM9090_SOFTWARE_RESET, 0); if (ret < 0) - goto err; + return ret; if (i2c->dev.platform_data) memcpy(&wm9090->pdata, i2c->dev.platform_data, @@ -658,23 +658,15 @@ static int wm9090_i2c_probe(struct i2c_client *i2c, &soc_codec_dev_wm9090, NULL, 0); if (ret != 0) { dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); - goto err; + return ret; } return 0; - -err: - regmap_exit(wm9090->regmap); - return ret; } -static int __devexit wm9090_i2c_remove(struct i2c_client *i2c) +static int wm9090_i2c_remove(struct i2c_client *i2c) { - struct wm9090_priv *wm9090 = i2c_get_clientdata(i2c); - snd_soc_unregister_codec(&i2c->dev); - regmap_exit(wm9090->regmap); - return 0; } @@ -691,7 +683,7 @@ static struct i2c_driver wm9090_i2c_driver = { .owner = THIS_MODULE, }, .probe = wm9090_i2c_probe, - .remove = __devexit_p(wm9090_i2c_remove), + .remove = wm9090_i2c_remove, .id_table = wm9090_id, }; diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c index e8e782a0c78..05b1f346695 100644 --- a/sound/soc/codecs/wm9705.c +++ b/sound/soc/codecs/wm9705.c @@ -382,13 +382,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9705 = { .num_dapm_routes = ARRAY_SIZE(wm9705_audio_map), }; -static __devinit int wm9705_probe(struct platform_device *pdev) +static int wm9705_probe(struct platform_device *pdev) { return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm9705, wm9705_dai, ARRAY_SIZE(wm9705_dai)); } -static int __devexit wm9705_remove(struct platform_device *pdev) +static int wm9705_remove(struct platform_device *pdev) { snd_soc_unregister_codec(&pdev->dev); return 0; @@ -401,7 +401,7 @@ static struct platform_driver wm9705_codec_driver = { }, .probe = wm9705_probe, - .remove = __devexit_p(wm9705_remove), + .remove = wm9705_remove, }; module_platform_driver(wm9705_codec_driver); diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 4dd73ea08d0..8e9a6a3eeb1 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -685,13 +685,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9712 = { .num_dapm_routes = ARRAY_SIZE(wm9712_audio_map), }; -static __devinit int wm9712_probe(struct platform_device *pdev) +static int wm9712_probe(struct platform_device *pdev) { return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm9712, wm9712_dai, ARRAY_SIZE(wm9712_dai)); } -static int __devexit wm9712_remove(struct platform_device *pdev) +static int wm9712_remove(struct platform_device *pdev) { snd_soc_unregister_codec(&pdev->dev); return 0; @@ -704,7 +704,7 @@ static struct platform_driver wm9712_codec_driver = { }, .probe = wm9712_probe, - .remove = __devexit_p(wm9712_remove), + .remove = wm9712_remove, }; module_platform_driver(wm9712_codec_driver); diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 3eb19fb71d1..f7afa68d8c7 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -1254,13 +1254,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9713 = { .num_dapm_routes = ARRAY_SIZE(wm9713_audio_map), }; -static __devinit int wm9713_probe(struct platform_device *pdev) +static int wm9713_probe(struct platform_device *pdev) { return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm9713, wm9713_dai, ARRAY_SIZE(wm9713_dai)); } -static int __devexit wm9713_remove(struct platform_device *pdev) +static int wm9713_remove(struct platform_device *pdev) { snd_soc_unregister_codec(&pdev->dev); return 0; @@ -1273,7 +1273,7 @@ static struct platform_driver wm9713_codec_driver = { }, .probe = wm9713_probe, - .remove = __devexit_p(wm9713_remove), + .remove = wm9713_remove, }; module_platform_driver(wm9713_codec_driver); diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c new file mode 100644 index 00000000000..ffc89fab96f --- /dev/null +++ b/sound/soc/codecs/wm_adsp.c @@ -0,0 +1,699 @@ +/* + * wm_adsp.c -- Wolfson ADSP support + * + * Copyright 2012 Wolfson Microelectronics plc + * + * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/firmware.h> +#include <linux/pm.h> +#include <linux/pm_runtime.h> +#include <linux/regmap.h> +#include <linux/regulator/consumer.h> +#include <linux/slab.h> +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/soc.h> +#include <sound/jack.h> +#include <sound/initval.h> +#include <sound/tlv.h> + +#include <linux/mfd/arizona/registers.h> + +#include "wm_adsp.h" + +#define adsp_crit(_dsp, fmt, ...) \ + dev_crit(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) +#define adsp_err(_dsp, fmt, ...) \ + dev_err(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) +#define adsp_warn(_dsp, fmt, ...) \ + dev_warn(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) +#define adsp_info(_dsp, fmt, ...) \ + dev_info(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) +#define adsp_dbg(_dsp, fmt, ...) \ + dev_dbg(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) + +#define ADSP1_CONTROL_1 0x00 +#define ADSP1_CONTROL_2 0x02 +#define ADSP1_CONTROL_3 0x03 +#define ADSP1_CONTROL_4 0x04 +#define ADSP1_CONTROL_5 0x06 +#define ADSP1_CONTROL_6 0x07 +#define ADSP1_CONTROL_7 0x08 +#define ADSP1_CONTROL_8 0x09 +#define ADSP1_CONTROL_9 0x0A +#define ADSP1_CONTROL_10 0x0B +#define ADSP1_CONTROL_11 0x0C +#define ADSP1_CONTROL_12 0x0D +#define ADSP1_CONTROL_13 0x0F +#define ADSP1_CONTROL_14 0x10 +#define ADSP1_CONTROL_15 0x11 +#define ADSP1_CONTROL_16 0x12 +#define ADSP1_CONTROL_17 0x13 +#define ADSP1_CONTROL_18 0x14 +#define ADSP1_CONTROL_19 0x16 +#define ADSP1_CONTROL_20 0x17 +#define ADSP1_CONTROL_21 0x18 +#define ADSP1_CONTROL_22 0x1A +#define ADSP1_CONTROL_23 0x1B +#define ADSP1_CONTROL_24 0x1C +#define ADSP1_CONTROL_25 0x1E +#define ADSP1_CONTROL_26 0x20 +#define ADSP1_CONTROL_27 0x21 +#define ADSP1_CONTROL_28 0x22 +#define ADSP1_CONTROL_29 0x23 +#define ADSP1_CONTROL_30 0x24 +#define ADSP1_CONTROL_31 0x26 + +/* + * ADSP1 Control 19 + */ +#define ADSP1_WDMA_BUFFER_LENGTH_MASK 0x00FF /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ +#define ADSP1_WDMA_BUFFER_LENGTH_SHIFT 0 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ +#define ADSP1_WDMA_BUFFER_LENGTH_WIDTH 8 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ + + +/* + * ADSP1 Control 30 + */ +#define ADSP1_DBG_CLK_ENA 0x0008 /* DSP1_DBG_CLK_ENA */ +#define ADSP1_DBG_CLK_ENA_MASK 0x0008 /* DSP1_DBG_CLK_ENA */ +#define ADSP1_DBG_CLK_ENA_SHIFT 3 /* DSP1_DBG_CLK_ENA */ +#define ADSP1_DBG_CLK_ENA_WIDTH 1 /* DSP1_DBG_CLK_ENA */ +#define ADSP1_SYS_ENA 0x0004 /* DSP1_SYS_ENA */ +#define ADSP1_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */ +#define ADSP1_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */ +#define ADSP1_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */ +#define ADSP1_CORE_ENA 0x0002 /* DSP1_CORE_ENA */ +#define ADSP1_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */ +#define ADSP1_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */ +#define ADSP1_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */ +#define ADSP1_START 0x0001 /* DSP1_START */ +#define ADSP1_START_MASK 0x0001 /* DSP1_START */ +#define ADSP1_START_SHIFT 0 /* DSP1_START */ +#define ADSP1_START_WIDTH 1 /* DSP1_START */ + +#define ADSP2_CONTROL 0 +#define ADSP2_CLOCKING 1 +#define ADSP2_STATUS1 4 + +/* + * ADSP2 Control + */ + +#define ADSP2_MEM_ENA 0x0010 /* DSP1_MEM_ENA */ +#define ADSP2_MEM_ENA_MASK 0x0010 /* DSP1_MEM_ENA */ +#define ADSP2_MEM_ENA_SHIFT 4 /* DSP1_MEM_ENA */ +#define ADSP2_MEM_ENA_WIDTH 1 /* DSP1_MEM_ENA */ +#define ADSP2_SYS_ENA 0x0004 /* DSP1_SYS_ENA */ +#define ADSP2_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */ +#define ADSP2_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */ +#define ADSP2_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */ +#define ADSP2_CORE_ENA 0x0002 /* DSP1_CORE_ENA */ +#define ADSP2_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */ +#define ADSP2_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */ +#define ADSP2_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */ +#define ADSP2_START 0x0001 /* DSP1_START */ +#define ADSP2_START_MASK 0x0001 /* DSP1_START */ +#define ADSP2_START_SHIFT 0 /* DSP1_START */ +#define ADSP2_START_WIDTH 1 /* DSP1_START */ + +/* + * ADSP2 clocking + */ +#define ADSP2_CLK_SEL_MASK 0x0007 /* CLK_SEL_ENA */ +#define ADSP2_CLK_SEL_SHIFT 0 /* CLK_SEL_ENA */ +#define ADSP2_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ + +/* + * ADSP2 Status 1 + */ +#define ADSP2_RAM_RDY 0x0001 +#define ADSP2_RAM_RDY_MASK 0x0001 +#define ADSP2_RAM_RDY_SHIFT 0 +#define ADSP2_RAM_RDY_WIDTH 1 + + +static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp, + int type) +{ + int i; + + for (i = 0; i < dsp->num_mems; i++) + if (dsp->mem[i].type == type) + return &dsp->mem[i]; + + return NULL; +} + +static int wm_adsp_load(struct wm_adsp *dsp) +{ + const struct firmware *firmware; + struct regmap *regmap = dsp->regmap; + unsigned int pos = 0; + const struct wmfw_header *header; + const struct wmfw_adsp1_sizes *adsp1_sizes; + const struct wmfw_adsp2_sizes *adsp2_sizes; + const struct wmfw_footer *footer; + const struct wmfw_region *region; + const struct wm_adsp_region *mem; + const char *region_name; + char *file, *text; + unsigned int reg; + int regions = 0; + int ret, offset, type, sizes; + + file = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (file == NULL) + return -ENOMEM; + + snprintf(file, PAGE_SIZE, "%s-dsp%d.wmfw", dsp->part, dsp->num); + file[PAGE_SIZE - 1] = '\0'; + + ret = request_firmware(&firmware, file, dsp->dev); + if (ret != 0) { + adsp_err(dsp, "Failed to request '%s'\n", file); + goto out; + } + ret = -EINVAL; + + pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer); + if (pos >= firmware->size) { + adsp_err(dsp, "%s: file too short, %zu bytes\n", + file, firmware->size); + goto out_fw; + } + + header = (void*)&firmware->data[0]; + + if (memcmp(&header->magic[0], "WMFW", 4) != 0) { + adsp_err(dsp, "%s: invalid magic\n", file); + goto out_fw; + } + + if (header->ver != 0) { + adsp_err(dsp, "%s: unknown file format %d\n", + file, header->ver); + goto out_fw; + } + + if (header->core != dsp->type) { + adsp_err(dsp, "%s: invalid core %d != %d\n", + file, header->core, dsp->type); + goto out_fw; + } + + switch (dsp->type) { + case WMFW_ADSP1: + pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer); + adsp1_sizes = (void *)&(header[1]); + footer = (void *)&(adsp1_sizes[1]); + sizes = sizeof(*adsp1_sizes); + + adsp_dbg(dsp, "%s: %d DM, %d PM, %d ZM\n", + file, le32_to_cpu(adsp1_sizes->dm), + le32_to_cpu(adsp1_sizes->pm), + le32_to_cpu(adsp1_sizes->zm)); + break; + + case WMFW_ADSP2: + pos = sizeof(*header) + sizeof(*adsp2_sizes) + sizeof(*footer); + adsp2_sizes = (void *)&(header[1]); + footer = (void *)&(adsp2_sizes[1]); + sizes = sizeof(*adsp2_sizes); + + adsp_dbg(dsp, "%s: %d XM, %d YM %d PM, %d ZM\n", + file, le32_to_cpu(adsp2_sizes->xm), + le32_to_cpu(adsp2_sizes->ym), + le32_to_cpu(adsp2_sizes->pm), + le32_to_cpu(adsp2_sizes->zm)); + break; + + default: + BUG_ON(NULL == "Unknown DSP type"); + goto out_fw; + } + + if (le32_to_cpu(header->len) != sizeof(*header) + + sizes + sizeof(*footer)) { + adsp_err(dsp, "%s: unexpected header length %d\n", + file, le32_to_cpu(header->len)); + goto out_fw; + } + + adsp_dbg(dsp, "%s: timestamp %llu\n", file, + le64_to_cpu(footer->timestamp)); + + while (pos < firmware->size && + pos - firmware->size > sizeof(*region)) { + region = (void *)&(firmware->data[pos]); + region_name = "Unknown"; + reg = 0; + text = NULL; + offset = le32_to_cpu(region->offset) & 0xffffff; + type = be32_to_cpu(region->type) & 0xff; + mem = wm_adsp_find_region(dsp, type); + + switch (type) { + case WMFW_NAME_TEXT: + region_name = "Firmware name"; + text = kzalloc(le32_to_cpu(region->len) + 1, + GFP_KERNEL); + break; + case WMFW_INFO_TEXT: + region_name = "Information"; + text = kzalloc(le32_to_cpu(region->len) + 1, + GFP_KERNEL); + break; + case WMFW_ABSOLUTE: + region_name = "Absolute"; + reg = offset; + break; + case WMFW_ADSP1_PM: + BUG_ON(!mem); + region_name = "PM"; + reg = mem->base + (offset * 3); + break; + case WMFW_ADSP1_DM: + BUG_ON(!mem); + region_name = "DM"; + reg = mem->base + (offset * 2); + break; + case WMFW_ADSP2_XM: + BUG_ON(!mem); + region_name = "XM"; + reg = mem->base + (offset * 2); + break; + case WMFW_ADSP2_YM: + BUG_ON(!mem); + region_name = "YM"; + reg = mem->base + (offset * 2); + break; + case WMFW_ADSP1_ZM: + BUG_ON(!mem); + region_name = "ZM"; + reg = mem->base + (offset * 2); + break; + default: + adsp_warn(dsp, + "%s.%d: Unknown region type %x at %d(%x)\n", + file, regions, type, pos, pos); + break; + } + + adsp_dbg(dsp, "%s.%d: %d bytes at %d in %s\n", file, + regions, le32_to_cpu(region->len), offset, + region_name); + + if (text) { + memcpy(text, region->data, le32_to_cpu(region->len)); + adsp_info(dsp, "%s: %s\n", file, text); + kfree(text); + } + + if (reg) { + ret = regmap_raw_write(regmap, reg, region->data, + le32_to_cpu(region->len)); + if (ret != 0) { + adsp_err(dsp, + "%s.%d: Failed to write %d bytes at %d in %s: %d\n", + file, regions, + le32_to_cpu(region->len), offset, + region_name, ret); + goto out_fw; + } + } + + pos += le32_to_cpu(region->len) + sizeof(*region); + regions++; + } + + if (pos > firmware->size) + adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", + file, regions, pos - firmware->size); + +out_fw: + release_firmware(firmware); +out: + kfree(file); + + return ret; +} + +static int wm_adsp_load_coeff(struct wm_adsp *dsp) +{ + struct regmap *regmap = dsp->regmap; + struct wmfw_coeff_hdr *hdr; + struct wmfw_coeff_item *blk; + const struct firmware *firmware; + const char *region_name; + int ret, pos, blocks, type, offset, reg; + char *file; + + file = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (file == NULL) + return -ENOMEM; + + snprintf(file, PAGE_SIZE, "%s-dsp%d.bin", dsp->part, dsp->num); + file[PAGE_SIZE - 1] = '\0'; + + ret = request_firmware(&firmware, file, dsp->dev); + if (ret != 0) { + adsp_warn(dsp, "Failed to request '%s'\n", file); + ret = 0; + goto out; + } + ret = -EINVAL; + + if (sizeof(*hdr) >= firmware->size) { + adsp_err(dsp, "%s: file too short, %zu bytes\n", + file, firmware->size); + goto out_fw; + } + + hdr = (void*)&firmware->data[0]; + if (memcmp(hdr->magic, "WMDR", 4) != 0) { + adsp_err(dsp, "%s: invalid magic\n", file); + return -EINVAL; + } + + adsp_dbg(dsp, "%s: v%d.%d.%d\n", file, + (le32_to_cpu(hdr->ver) >> 16) & 0xff, + (le32_to_cpu(hdr->ver) >> 8) & 0xff, + le32_to_cpu(hdr->ver) & 0xff); + + pos = le32_to_cpu(hdr->len); + + blocks = 0; + while (pos < firmware->size && + pos - firmware->size > sizeof(*blk)) { + blk = (void*)(&firmware->data[pos]); + + type = be32_to_cpu(blk->type) & 0xff; + offset = le32_to_cpu(blk->offset) & 0xffffff; + + adsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n", + file, blocks, le32_to_cpu(blk->id), + (le32_to_cpu(blk->ver) >> 16) & 0xff, + (le32_to_cpu(blk->ver) >> 8) & 0xff, + le32_to_cpu(blk->ver) & 0xff); + adsp_dbg(dsp, "%s.%d: %d bytes at 0x%x in %x\n", + file, blocks, le32_to_cpu(blk->len), offset, type); + + reg = 0; + region_name = "Unknown"; + switch (type) { + case WMFW_NAME_TEXT: + case WMFW_INFO_TEXT: + break; + case WMFW_ABSOLUTE: + region_name = "register"; + reg = offset; + break; + default: + adsp_err(dsp, "Unknown region type %x\n", type); + break; + } + + if (reg) { + ret = regmap_raw_write(regmap, reg, blk->data, + le32_to_cpu(blk->len)); + if (ret != 0) { + adsp_err(dsp, + "%s.%d: Failed to write to %x in %s\n", + file, blocks, reg, region_name); + } + } + + pos += le32_to_cpu(blk->len) + sizeof(*blk); + blocks++; + } + + if (pos > firmware->size) + adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", + file, blocks, pos - firmware->size); + +out_fw: + release_firmware(firmware); +out: + kfree(file); + return 0; +} + +int wm_adsp1_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = w->codec; + struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); + struct wm_adsp *dsp = &dsps[w->shift]; + int ret; + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, + ADSP1_SYS_ENA, ADSP1_SYS_ENA); + + ret = wm_adsp_load(dsp); + if (ret != 0) + goto err; + + ret = wm_adsp_load_coeff(dsp); + if (ret != 0) + goto err; + + /* Start the core running */ + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, + ADSP1_CORE_ENA | ADSP1_START, + ADSP1_CORE_ENA | ADSP1_START); + break; + + case SND_SOC_DAPM_PRE_PMD: + /* Halt the core */ + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, + ADSP1_CORE_ENA | ADSP1_START, 0); + + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_19, + ADSP1_WDMA_BUFFER_LENGTH_MASK, 0); + + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, + ADSP1_SYS_ENA, 0); + break; + + default: + break; + } + + return 0; + +err: + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, + ADSP1_SYS_ENA, 0); + return ret; +} +EXPORT_SYMBOL_GPL(wm_adsp1_event); + +static int wm_adsp2_ena(struct wm_adsp *dsp) +{ + unsigned int val; + int ret, count; + + ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_SYS_ENA, ADSP2_SYS_ENA); + if (ret != 0) + return ret; + + /* Wait for the RAM to start, should be near instantaneous */ + count = 0; + do { + ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1, + &val); + if (ret != 0) + return ret; + } while (!(val & ADSP2_RAM_RDY) && ++count < 10); + + if (!(val & ADSP2_RAM_RDY)) { + adsp_err(dsp, "Failed to start DSP RAM\n"); + return -EBUSY; + } + + adsp_dbg(dsp, "RAM ready after %d polls\n", count); + adsp_info(dsp, "RAM ready after %d polls\n", count); + + return 0; +} + +int wm_adsp2_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); + struct wm_adsp *dsp = &dsps[w->shift]; + unsigned int val; + int ret; + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + /* + * For simplicity set the DSP clock rate to be the + * SYSCLK rate rather than making it configurable. + */ + ret = regmap_read(dsp->regmap, ARIZONA_SYSTEM_CLOCK_1, &val); + if (ret != 0) { + adsp_err(dsp, "Failed to read SYSCLK state: %d\n", + ret); + return ret; + } + val = (val & ARIZONA_SYSCLK_FREQ_MASK) + >> ARIZONA_SYSCLK_FREQ_SHIFT; + + ret = regmap_update_bits(dsp->regmap, + dsp->base + ADSP2_CLOCKING, + ADSP2_CLK_SEL_MASK, val); + if (ret != 0) { + adsp_err(dsp, "Failed to set clock rate: %d\n", + ret); + return ret; + } + + if (dsp->dvfs) { + ret = regmap_read(dsp->regmap, + dsp->base + ADSP2_CLOCKING, &val); + if (ret != 0) { + dev_err(dsp->dev, + "Failed to read clocking: %d\n", ret); + return ret; + } + + if ((val & ADSP2_CLK_SEL_MASK) >= 3) { + ret = regulator_enable(dsp->dvfs); + if (ret != 0) { + dev_err(dsp->dev, + "Failed to enable supply: %d\n", + ret); + return ret; + } + + ret = regulator_set_voltage(dsp->dvfs, + 1800000, + 1800000); + if (ret != 0) { + dev_err(dsp->dev, + "Failed to raise supply: %d\n", + ret); + return ret; + } + } + } + + ret = wm_adsp2_ena(dsp); + if (ret != 0) + return ret; + + ret = wm_adsp_load(dsp); + if (ret != 0) + goto err; + + ret = wm_adsp_load_coeff(dsp); + if (ret != 0) + goto err; + + ret = regmap_update_bits(dsp->regmap, + dsp->base + ADSP2_CONTROL, + ADSP2_CORE_ENA | ADSP2_START, + ADSP2_CORE_ENA | ADSP2_START); + if (ret != 0) + goto err; + break; + + case SND_SOC_DAPM_PRE_PMD: + regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_SYS_ENA | ADSP2_CORE_ENA | + ADSP2_START, 0); + + if (dsp->dvfs) { + ret = regulator_set_voltage(dsp->dvfs, 1200000, + 1800000); + if (ret != 0) + dev_warn(dsp->dev, + "Failed to lower supply: %d\n", + ret); + + ret = regulator_disable(dsp->dvfs); + if (ret != 0) + dev_err(dsp->dev, + "Failed to enable supply: %d\n", + ret); + } + break; + + default: + break; + } + + return 0; +err: + regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_SYS_ENA | ADSP2_CORE_ENA | ADSP2_START, 0); + return ret; +} +EXPORT_SYMBOL_GPL(wm_adsp2_event); + +int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs) +{ + int ret; + + /* + * Disable the DSP memory by default when in reset for a small + * power saving. + */ + ret = regmap_update_bits(adsp->regmap, adsp->base + ADSP2_CONTROL, + ADSP2_MEM_ENA, 0); + if (ret != 0) { + adsp_err(adsp, "Failed to clear memory retention: %d\n", ret); + return ret; + } + + if (dvfs) { + adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD"); + if (IS_ERR(adsp->dvfs)) { + ret = PTR_ERR(adsp->dvfs); + dev_err(adsp->dev, "Failed to get DCVDD: %d\n", ret); + return ret; + } + + ret = regulator_enable(adsp->dvfs); + if (ret != 0) { + dev_err(adsp->dev, "Failed to enable DCVDD: %d\n", + ret); + return ret; + } + + ret = regulator_set_voltage(adsp->dvfs, 1200000, 1800000); + if (ret != 0) { + dev_err(adsp->dev, "Failed to initialise DVFS: %d\n", + ret); + return ret; + } + + ret = regulator_disable(adsp->dvfs); + if (ret != 0) { + dev_err(adsp->dev, "Failed to disable DCVDD: %d\n", + ret); + return ret; + } + } + + return 0; +} +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 00000000000..ffd29a4609e --- /dev/null +++ b/sound/soc/codecs/wm_adsp.h @@ -0,0 +1,59 @@ +/* + * wm_adsp.h -- Wolfson ADSP support + * + * Copyright 2012 Wolfson Microelectronics plc + * + * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __WM_ADSP_H +#define __WM_ADSP_H + +#include <sound/soc.h> +#include <sound/soc-dapm.h> + +#include "wmfw.h" + +struct regulator; + +struct wm_adsp_region { + int type; + unsigned int base; +}; + +struct wm_adsp { + const char *part; + int num; + int type; + struct device *dev; + struct regmap *regmap; + + int base; + + const struct wm_adsp_region *mem; + int num_mems; + + struct regulator *dvfs; +}; + +#define WM_ADSP1(wname, num) \ + { .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, \ + .shift = num, .event = wm_adsp1_event, \ + .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD } + +#define WM_ADSP2(wname, num) \ +{ .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, \ + .shift = num, .event = wm_adsp2_event, \ + .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD } + +int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs); +int wm_adsp1_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event); +int wm_adsp2_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event); + +#endif diff --git a/sound/soc/codecs/wmfw.h b/sound/soc/codecs/wmfw.h new file mode 100644 index 00000000000..5632ded67fd --- /dev/null +++ b/sound/soc/codecs/wmfw.h @@ -0,0 +1,128 @@ +/* + * wmfw.h - Wolfson firmware format information + * + * Copyright 2012 Wolfson Microelectronics plc + * + * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __WMFW_H +#define __WMFW_H + +#include <linux/types.h> + +struct wmfw_header { + char magic[4]; + __le32 len; + __le16 rev; + u8 core; + u8 ver; +} __packed; + +struct wmfw_footer { + __le64 timestamp; + __le32 checksum; +} __packed; + +struct wmfw_adsp1_sizes { + __le32 dm; + __le32 pm; + __le32 zm; +} __packed; + +struct wmfw_adsp2_sizes { + __le32 xm; + __le32 ym; + __le32 pm; + __le32 zm; +} __packed; + +struct wmfw_region { + union { + __be32 type; + __le32 offset; + }; + __le32 len; + u8 data[]; +} __packed; + +struct wmfw_id_hdr { + __be32 core_id; + __be32 core_rev; + __be32 id; + __be32 ver; +} __packed; + +struct wmfw_adsp1_id_hdr { + struct wmfw_id_hdr fw; + __be32 zm; + __be32 dm; + __be32 algs; +} __packed; + +struct wmfw_adsp2_id_hdr { + struct wmfw_id_hdr fw; + __be32 zm; + __be32 xm; + __be32 ym; + __be32 algs; +} __packed; + +struct wmfw_alg_hdr { + __be32 id; + __be32 ver; +} __packed; + +struct wmfw_adsp1_alg_hdr { + struct wmfw_alg_hdr alg; + __be32 zm; + __be32 dm; +} __packed; + +struct wmfw_adsp2_alg_hdr { + struct wmfw_alg_hdr alg; + __be32 zm; + __be32 xm; + __be32 ym; +} __packed; + +struct wmfw_coeff_hdr { + u8 magic[4]; + __le32 len; + __le32 ver; + u8 data[]; +} __packed; + +struct wmfw_coeff_item { + union { + __be32 type; + __le32 offset; + }; + __le32 id; + __le32 ver; + __le32 sr; + __le32 len; + u8 data[]; +} __packed; + +#define WMFW_ADSP1 1 +#define WMFW_ADSP2 2 + +#define WMFW_ABSOLUTE 0xf0 +#define WMFW_NAME_TEXT 0xfe +#define WMFW_INFO_TEXT 0xff + +#define WMFW_ADSP1_PM 2 +#define WMFW_ADSP1_DM 3 +#define WMFW_ADSP1_ZM 4 + +#define WMFW_ADSP2_PM 2 +#define WMFW_ADSP2_ZM 4 +#define WMFW_ADSP2_XM 5 +#define WMFW_ADSP2_YM 6 + +#endif diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index 6fac5af1329..d55e6477bff 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, if (ret < 0) return ret; + /* set the CPU system clock */ + ret = snd_soc_dai_set_sysclk(cpu_dai, 0, sysclk, SND_SOC_CLOCK_OUT); + if (ret < 0) + return ret; + return 0; } diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 714e51e5be5..55e2bf652be 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -199,6 +199,7 @@ #define ACLKXE BIT(5) #define TX_ASYNC BIT(6) #define ACLKXPOL BIT(7) +#define ACLKXDIV_MASK 0x1f /* * DAVINCI_MCASP_ACLKRCTL_REG Receive Clock Control Register Bits @@ -207,6 +208,7 @@ #define ACLKRE BIT(5) #define RX_ASYNC BIT(6) #define ACLKRPOL BIT(7) +#define ACLKRDIV_MASK 0x1f /* * DAVINCI_MCASP_AHCLKXCTL_REG - High Frequency Transmit Clock Control @@ -215,6 +217,7 @@ #define AHCLKXDIV(val) (val) #define AHCLKXPOL BIT(14) #define AHCLKXE BIT(15) +#define AHCLKXDIV_MASK 0xfff /* * DAVINCI_MCASP_AHCLKRCTL_REG - High Frequency Receive Clock Control @@ -223,6 +226,7 @@ #define AHCLKRDIV(val) (val) #define AHCLKRPOL BIT(14) #define AHCLKRE BIT(15) +#define AHCLKRDIV_MASK 0xfff /* * 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, struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(cpu_dai); void __iomem *base = dev->base; + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_B: + case SND_SOC_DAIFMT_AC97: + mcasp_clr_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); + mcasp_clr_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); + break; + default: + /* configure a full-word SYNC pulse (LRCLK) */ + mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); + mcasp_set_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); + + /* make 1st data bit occur one ACLK cycle after the frame sync */ + mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, FSXDLY(1)); + mcasp_set_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, FSRDLY(1)); + break; + } + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: /* codec is clock and frame slave */ @@ -482,8 +503,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE); mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE); - mcasp_set_bits(base + DAVINCI_MCASP_PDIR_REG, - ACLKX | AHCLKX | AFSX); + mcasp_set_bits(base + DAVINCI_MCASP_PDIR_REG, ACLKX | AFSX); break; case SND_SOC_DAIFMT_CBM_CFS: /* codec is clock master and frame slave */ @@ -554,59 +574,75 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, return 0; } -static int davinci_config_channel_size(struct davinci_audio_dev *dev, - int channel_size) +static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) { - u32 fmt = 0; - u32 mask, rotate; - - switch (channel_size) { - case DAVINCI_AUDIO_WORD_8: - fmt = 0x03; - rotate = 6; - mask = 0x000000ff; - break; + struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(dai); - case DAVINCI_AUDIO_WORD_12: - fmt = 0x05; - rotate = 5; - mask = 0x00000fff; + switch (div_id) { + case 0: /* MCLK divider */ + mcasp_mod_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, + AHCLKXDIV(div - 1), AHCLKXDIV_MASK); + mcasp_mod_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG, + AHCLKRDIV(div - 1), AHCLKRDIV_MASK); break; - case DAVINCI_AUDIO_WORD_16: - fmt = 0x07; - rotate = 4; - mask = 0x0000ffff; + case 1: /* BCLK divider */ + mcasp_mod_bits(dev->base + DAVINCI_MCASP_ACLKXCTL_REG, + ACLKXDIV(div - 1), ACLKXDIV_MASK); + mcasp_mod_bits(dev->base + DAVINCI_MCASP_ACLKRCTL_REG, + ACLKRDIV(div - 1), ACLKRDIV_MASK); break; - case DAVINCI_AUDIO_WORD_20: - fmt = 0x09; - rotate = 3; - mask = 0x000fffff; + case 2: /* BCLK/LRCLK ratio */ + dev->bclk_lrclk_ratio = div; break; - case DAVINCI_AUDIO_WORD_24: - fmt = 0x0B; - rotate = 2; - mask = 0x00ffffff; - break; + default: + return -EINVAL; + } - case DAVINCI_AUDIO_WORD_28: - fmt = 0x0D; - rotate = 1; - mask = 0x0fffffff; - break; + return 0; +} - case DAVINCI_AUDIO_WORD_32: - fmt = 0x0F; - rotate = 0; - mask = 0xffffffff; - break; +static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id, + unsigned int freq, int dir) +{ + struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(dai); - default: - return -EINVAL; + if (dir == SND_SOC_CLOCK_OUT) { + mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE); + mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE); + mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG, AHCLKX); + } else { + mcasp_clr_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE); + mcasp_clr_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE); + mcasp_clr_bits(dev->base + DAVINCI_MCASP_PDIR_REG, AHCLKX); } + return 0; +} + +static int davinci_config_channel_size(struct davinci_audio_dev *dev, + int word_length) +{ + u32 fmt; + u32 rotate = (32 - word_length) / 4; + u32 mask = (1ULL << word_length) - 1; + + /* + * if s BCLK-to-LRCLK ratio has been configured via the set_clkdiv() + * callback, take it into account here. That allows us to for example + * send 32 bits per channel to the codec, while only 16 of them carry + * audio payload. + * The clock ratio is given for a full period of data (both left and + * right channels), so it has to be divided by 2. + */ + if (dev->bclk_lrclk_ratio) + word_length = dev->bclk_lrclk_ratio / 2; + + /* mapping of the XSSZ bit-field as described in the datasheet */ + fmt = (word_length >> 1) - 1; + mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, RXSSZ(fmt), RXSSZ(0x0F)); mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, @@ -709,8 +745,6 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) if (stream == SNDRV_PCM_STREAM_PLAYBACK) { /* bit stream is MSB first with no delay */ /* DSP_B mode */ - mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, - AHCLKXE); mcasp_set_reg(dev->base + DAVINCI_MCASP_TXTDM_REG, mask); mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXORD); @@ -720,14 +754,10 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) else printk(KERN_ERR "playback tdm slot %d not supported\n", dev->tdm_slots); - - mcasp_clr_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); } else { /* bit stream is MSB first with no delay */ /* DSP_B mode */ mcasp_set_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, RXORD); - mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG, - AHCLKRE); mcasp_set_reg(dev->base + DAVINCI_MCASP_RXTDM_REG, mask); if ((dev->tdm_slots >= 2) && (dev->tdm_slots <= 32)) @@ -736,8 +766,6 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) else printk(KERN_ERR "capture tdm slot %d not supported\n", dev->tdm_slots); - - mcasp_clr_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); } } @@ -800,19 +828,27 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, case SNDRV_PCM_FORMAT_U8: case SNDRV_PCM_FORMAT_S8: dma_params->data_type = 1; - word_length = DAVINCI_AUDIO_WORD_8; + word_length = 8; break; case SNDRV_PCM_FORMAT_U16_LE: case SNDRV_PCM_FORMAT_S16_LE: dma_params->data_type = 2; - word_length = DAVINCI_AUDIO_WORD_16; + word_length = 16; + break; + + case SNDRV_PCM_FORMAT_U24_3LE: + case SNDRV_PCM_FORMAT_S24_3LE: + dma_params->data_type = 3; + word_length = 24; break; + case SNDRV_PCM_FORMAT_U24_LE: + case SNDRV_PCM_FORMAT_S24_LE: case SNDRV_PCM_FORMAT_U32_LE: case SNDRV_PCM_FORMAT_S32_LE: dma_params->data_type = 4; - word_length = DAVINCI_AUDIO_WORD_32; + word_length = 32; break; default: @@ -880,13 +916,18 @@ static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = { .trigger = davinci_mcasp_trigger, .hw_params = davinci_mcasp_hw_params, .set_fmt = davinci_mcasp_set_dai_fmt, - + .set_clkdiv = davinci_mcasp_set_clkdiv, + .set_sysclk = davinci_mcasp_set_sysclk, }; #define DAVINCI_MCASP_PCM_FMTS (SNDRV_PCM_FMTBIT_S8 | \ SNDRV_PCM_FMTBIT_U8 | \ SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_U16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_U24_LE | \ + SNDRV_PCM_FMTBIT_S24_3LE | \ + SNDRV_PCM_FMTBIT_U24_3LE | \ SNDRV_PCM_FMTBIT_S32_LE | \ SNDRV_PCM_FMTBIT_U32_LE) @@ -1089,7 +1130,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev) dev->tdm_slots = pdata->tdm_slots; dev->num_serializer = pdata->num_serializer; dev->serial_dir = pdata->serial_dir; - dev->codec_fmt = pdata->codec_fmt; dev->version = pdata->version; dev->txnumevt = pdata->txnumevt; dev->rxnumevt = pdata->rxnumevt; @@ -1098,6 +1138,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev) dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; dma_data->asp_chan_q = pdata->asp_chan_q; dma_data->ram_chan_q = pdata->ram_chan_q; + dma_data->sram_pool = pdata->sram_pool; dma_data->sram_size = pdata->sram_size_playback; dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset + mem->start); @@ -1115,6 +1156,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev) dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]; dma_data->asp_chan_q = pdata->asp_chan_q; dma_data->ram_chan_q = pdata->ram_chan_q; + dma_data->sram_pool = pdata->sram_pool; dma_data->sram_size = pdata->sram_size_capture; dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset + mem->start); diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h index 0de9ed6ce03..0edd3b5a37f 100644 --- a/sound/soc/davinci/davinci-mcasp.h +++ b/sound/soc/davinci/davinci-mcasp.h @@ -23,26 +23,14 @@ #include "davinci-pcm.h" -#define DAVINCI_MCASP_RATES SNDRV_PCM_RATE_8000_96000 +#define DAVINCI_MCASP_RATES SNDRV_PCM_RATE_8000_192000 #define DAVINCI_MCASP_I2S_DAI 0 #define DAVINCI_MCASP_DIT_DAI 1 -enum { - DAVINCI_AUDIO_WORD_8 = 0, - DAVINCI_AUDIO_WORD_12, - DAVINCI_AUDIO_WORD_16, - DAVINCI_AUDIO_WORD_20, - DAVINCI_AUDIO_WORD_24, - DAVINCI_AUDIO_WORD_32, - DAVINCI_AUDIO_WORD_28, /* This is only valid for McASP */ -}; - struct davinci_audio_dev { struct davinci_pcm_dma_params dma_params[2]; void __iomem *base; - int sample_rate; struct device *dev; - unsigned int codec_fmt; /* McASP specific data */ int tdm_slots; @@ -50,6 +38,7 @@ struct davinci_audio_dev { u8 num_serializer; u8 *serial_dir; u8 version; + u8 bclk_lrclk_ratio; /* McASP FIFO related */ u8 txnumevt; diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c index 93ea3bf567e..afab81f844a 100644 --- a/sound/soc/davinci/davinci-pcm.c +++ b/sound/soc/davinci/davinci-pcm.c @@ -16,6 +16,7 @@ #include <linux/slab.h> #include <linux/dma-mapping.h> #include <linux/kernel.h> +#include <linux/genalloc.h> #include <sound/core.h> #include <sound/pcm.h> @@ -23,7 +24,6 @@ #include <sound/soc.h> #include <asm/dma.h> -#include <mach/sram.h> #include "davinci-pcm.h" @@ -67,13 +67,9 @@ static struct snd_pcm_hardware pcm_hardware_playback = { SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME| SNDRV_PCM_INFO_BATCH), .formats = DAVINCI_PCM_FMTBITS, - .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | - SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | - SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | - SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | - SNDRV_PCM_RATE_KNOT), + .rates = SNDRV_PCM_RATE_8000_192000 | SNDRV_PCM_RATE_KNOT, .rate_min = 8000, - .rate_max = 96000, + .rate_max = 192000, .channels_min = 2, .channels_max = 384, .buffer_bytes_max = 128 * 1024, @@ -90,13 +86,9 @@ static struct snd_pcm_hardware pcm_hardware_capture = { SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_BATCH), .formats = DAVINCI_PCM_FMTBITS, - .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | - SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | - SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | - SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | - SNDRV_PCM_RATE_KNOT), + .rates = SNDRV_PCM_RATE_8000_192000 | SNDRV_PCM_RATE_KNOT, .rate_min = 8000, - .rate_max = 96000, + .rate_max = 192000, .channels_min = 2, .channels_max = 384, .buffer_bytes_max = 128 * 1024, @@ -259,7 +251,9 @@ static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data) } } -static int allocate_sram(struct snd_pcm_substream *substream, unsigned size, +#ifdef CONFIG_GENERIC_ALLOCATOR +static int allocate_sram(struct snd_pcm_substream *substream, + struct gen_pool *sram_pool, unsigned size, struct snd_pcm_hardware *ppcm) { struct snd_dma_buffer *buf = &substream->dma_buffer; @@ -271,9 +265,10 @@ static int allocate_sram(struct snd_pcm_substream *substream, unsigned size, return 0; ppcm->period_bytes_max = size; - iram_virt = sram_alloc(size, &iram_phys); + iram_virt = (void *)gen_pool_alloc(sram_pool, size); if (!iram_virt) goto exit1; + iram_phys = gen_pool_virt_to_phys(sram_pool, (unsigned)iram_virt); iram_dma = kzalloc(sizeof(*iram_dma), GFP_KERNEL); if (!iram_dma) goto exit2; @@ -285,11 +280,33 @@ static int allocate_sram(struct snd_pcm_substream *substream, unsigned size, return 0; exit2: if (iram_virt) - sram_free(iram_virt, size); + gen_pool_free(sram_pool, (unsigned)iram_virt, size); exit1: return -ENOMEM; } +static void davinci_free_sram(struct snd_pcm_substream *substream, + struct snd_dma_buffer *iram_dma) +{ + struct davinci_runtime_data *prtd = substream->runtime->private_data; + struct gen_pool *sram_pool = prtd->params->sram_pool; + + gen_pool_free(sram_pool, (unsigned) iram_dma->area, iram_dma->bytes); +} +#else +static int allocate_sram(struct snd_pcm_substream *substream, + struct gen_pool *sram_pool, unsigned size, + struct snd_pcm_hardware *ppcm) +{ + return 0; +} + +static void davinci_free_sram(struct snd_pcm_substream *substream, + struct snd_dma_buffer *iram_dma) +{ +} +#endif + /* * Only used with ping/pong. * 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) ppcm = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? &pcm_hardware_playback : &pcm_hardware_capture; - allocate_sram(substream, params->sram_size, ppcm); + allocate_sram(substream, params->sram_pool, params->sram_size, ppcm); snd_soc_set_runtime_hwparams(substream, ppcm); /* ensure that buffer size is a multiple of period size */ ret = snd_pcm_hw_constraint_integer(runtime, @@ -819,7 +836,7 @@ static void davinci_pcm_free(struct snd_pcm *pcm) buf->area = NULL; iram_dma = buf->private_data; if (iram_dma) { - sram_free(iram_dma->area, iram_dma->bytes); + davinci_free_sram(substream, iram_dma); kfree(iram_dma); } } diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h index fc4d01cdd8c..b6ef7039dd0 100644 --- a/sound/soc/davinci/davinci-pcm.h +++ b/sound/soc/davinci/davinci-pcm.h @@ -12,6 +12,7 @@ #ifndef _DAVINCI_PCM_H #define _DAVINCI_PCM_H +#include <linux/genalloc.h> #include <linux/platform_data/davinci_asp.h> #include <mach/edma.h> @@ -20,6 +21,7 @@ struct davinci_pcm_dma_params { unsigned short acnt; dma_addr_t dma_addr; /* device physical address for DMA */ unsigned sram_size; + struct gen_pool *sram_pool; /* SRAM gen_pool for ping pong */ enum dma_event_q asp_chan_q; /* event queue number for ASP channel */ enum dma_event_q ram_chan_q; /* event queue number for RAM channel */ unsigned char data_type; /* xfer data type */ diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 4563b28bd62..3b98159d964 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -46,6 +46,20 @@ config SND_SOC_P1022_DS This will also include the Wolfson Microelectronics WM8776 codec driver. +config SND_SOC_P1022_RDK + tristate "ALSA SoC support for the Freescale / iVeia P1022 RDK board" + # I2C is necessary for the WM8960 driver + depends on P1022_RDK && I2C + select SND_SOC_FSL_SSI + select SND_SOC_FSL_UTILS + select SND_SOC_POWERPC_DMA + select SND_SOC_WM8960 + default y if P1022_RDK + help + Say Y if you want to enable audio on the Freescale / iVeia + P1022 RDK board. This will also include the Wolfson + Microelectronics WM8960 codec driver. + config SND_SOC_MPC5200_I2S tristate "Freescale MPC5200 PSC in I2S mode driver" depends on PPC_MPC52xx && PPC_BESTCOMM @@ -98,12 +112,12 @@ config SND_SOC_IMX_PCM tristate config SND_SOC_IMX_PCM_FIQ - tristate + bool select FIQ select SND_SOC_IMX_PCM config SND_SOC_IMX_PCM_DMA - tristate + bool select SND_SOC_DMAENGINE_PCM select SND_SOC_IMX_PCM @@ -112,7 +126,7 @@ config SND_SOC_IMX_AUDMUX config SND_MXC_SOC_WM1133_EV1 tristate "Audio on the i.MX31ADS with WM1133-EV1 fitted" - depends on MACH_MX31ADS_WM1133_EV1 && EXPERIMENTAL + depends on MACH_MX31ADS_WM1133_EV1 select SND_SOC_WM8350 select SND_SOC_IMX_PCM_FIQ select SND_SOC_IMX_AUDMUX diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile index 5f3cf3f52ea..afd34794db5 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 snd-soc-p1022-ds-objs := p1022_ds.o obj-$(CONFIG_SND_SOC_P1022_DS) += snd-soc-p1022-ds.o +# P1022 RDK Machine Support +snd-soc-p1022-rdk-objs := p1022_rdk.o +obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o + # Freescale PowerPC SSI/DMA Platform Support snd-soc-fsl-ssi-objs := fsl_ssi.o snd-soc-fsl-utils-objs := fsl_utils.o @@ -26,14 +30,18 @@ obj-$(CONFIG_SND_MPC52xx_SOC_EFIKA) += efika-audio-fabric.o # i.MX Platform Support snd-soc-imx-ssi-objs := imx-ssi.o snd-soc-imx-audmux-objs := imx-audmux.o +snd-soc-imx-pcm-objs := imx-pcm.o +ifneq ($(CONFIG_SND_SOC_IMX_PCM_FIQ),) + snd-soc-imx-pcm-objs += imx-pcm-fiq.o +endif +ifneq ($(CONFIG_SND_SOC_IMX_PCM_DMA),) + snd-soc-imx-pcm-objs += imx-pcm-dma.o +endif obj-$(CONFIG_SND_SOC_IMX_SSI) += snd-soc-imx-ssi.o obj-$(CONFIG_SND_SOC_IMX_AUDMUX) += snd-soc-imx-audmux.o obj-$(CONFIG_SND_SOC_IMX_PCM) += snd-soc-imx-pcm.o -snd-soc-imx-pcm-y := imx-pcm.o -snd-soc-imx-pcm-$(CONFIG_SND_SOC_IMX_PCM_FIQ) += imx-pcm-fiq.o -snd-soc-imx-pcm-$(CONFIG_SND_SOC_IMX_PCM_DMA) += imx-pcm-dma.o # i.MX Machine Support snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c index 267d5b4b63c..75ffdf0e2aa 100644 --- a/sound/soc/fsl/eukrea-tlv320.c +++ b/sound/soc/fsl/eukrea-tlv320.c @@ -93,7 +93,7 @@ static struct snd_soc_card eukrea_tlv320 = { .num_links = 1, }; -static int __devinit eukrea_tlv320_probe(struct platform_device *pdev) +static int eukrea_tlv320_probe(struct platform_device *pdev) { int ret; int int_port = 0, ext_port; @@ -142,7 +142,7 @@ static int __devinit eukrea_tlv320_probe(struct platform_device *pdev) return ret; } -static int __devexit eukrea_tlv320_remove(struct platform_device *pdev) +static int eukrea_tlv320_remove(struct platform_device *pdev) { snd_soc_unregister_card(&eukrea_tlv320); @@ -155,7 +155,7 @@ static struct platform_driver eukrea_tlv320_driver = { .owner = THIS_MODULE, }, .probe = eukrea_tlv320_probe, - .remove = __devexit_p(eukrea_tlv320_remove),}; + .remove = eukrea_tlv320_remove,}; module_platform_driver(eukrea_tlv320_driver); diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c index 6feb2650058..9cc5c1f82f0 100644 --- a/sound/soc/fsl/fsl_dma.c +++ b/sound/soc/fsl/fsl_dma.c @@ -894,7 +894,7 @@ static struct snd_pcm_ops fsl_dma_ops = { .pointer = fsl_dma_pointer, }; -static int __devinit fsl_soc_dma_probe(struct platform_device *pdev) +static int fsl_soc_dma_probe(struct platform_device *pdev) { struct dma_object *dma; struct device_node *np = pdev->dev.of_node; @@ -958,7 +958,7 @@ static int __devinit fsl_soc_dma_probe(struct platform_device *pdev) return 0; } -static int __devexit fsl_soc_dma_remove(struct platform_device *pdev) +static int fsl_soc_dma_remove(struct platform_device *pdev) { struct dma_object *dma = dev_get_drvdata(&pdev->dev); @@ -983,7 +983,7 @@ static struct platform_driver fsl_soc_dma_driver = { .of_match_table = fsl_soc_dma_ids, }, .probe = fsl_soc_dma_probe, - .remove = __devexit_p(fsl_soc_dma_remove), + .remove = fsl_soc_dma_remove, }; module_platform_driver(fsl_soc_dma_driver); diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 4ed2afd4778..7decbd9b234 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -639,7 +639,7 @@ static void make_lowercase(char *s) } } -static int __devinit fsl_ssi_probe(struct platform_device *pdev) +static int fsl_ssi_probe(struct platform_device *pdev) { struct fsl_ssi_private *ssi_private; int ret = 0; diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c index 524ce6210ce..251f4d981e0 100644 --- a/sound/soc/fsl/imx-audmux.c +++ b/sound/soc/fsl/imx-audmux.c @@ -162,7 +162,7 @@ static void __init audmux_debugfs_init(void) } } -static void __devexit audmux_debugfs_remove(void) +static void audmux_debugfs_remove(void) { debugfs_remove_recursive(audmux_debugfs_root); } @@ -244,7 +244,7 @@ int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr, } EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port); -static int __devinit imx_audmux_probe(struct platform_device *pdev) +static int imx_audmux_probe(struct platform_device *pdev) { struct resource *res; struct pinctrl *pinctrl; @@ -278,7 +278,7 @@ static int __devinit imx_audmux_probe(struct platform_device *pdev) return 0; } -static int __devexit imx_audmux_remove(struct platform_device *pdev) +static int imx_audmux_remove(struct platform_device *pdev) { if (audmux_type == IMX31_AUDMUX) audmux_debugfs_remove(); @@ -289,7 +289,7 @@ static int __devexit imx_audmux_remove(struct platform_device *pdev) static struct platform_driver imx_audmux_driver = { .probe = imx_audmux_probe, - .remove = __devexit_p(imx_audmux_remove), + .remove = imx_audmux_remove, .id_table = imx_audmux_ids, .driver = { .name = DRIVER_NAME, diff --git a/sound/soc/fsl/imx-mc13783.c b/sound/soc/fsl/imx-mc13783.c index 549b31fdc9d..4ae30f21fdb 100644 --- a/sound/soc/fsl/imx-mc13783.c +++ b/sound/soc/fsl/imx-mc13783.c @@ -98,7 +98,7 @@ static struct snd_soc_card imx_mc13783 = { .num_dapm_routes = ARRAY_SIZE(imx_mc13783_routes), }; -static int __devinit imx_mc13783_probe(struct platform_device *pdev) +static int imx_mc13783_probe(struct platform_device *pdev) { int ret; @@ -148,7 +148,7 @@ static int __devinit imx_mc13783_probe(struct platform_device *pdev) return ret; } -static int __devexit imx_mc13783_remove(struct platform_device *pdev) +static int imx_mc13783_remove(struct platform_device *pdev) { snd_soc_unregister_card(&imx_mc13783); @@ -161,7 +161,7 @@ static struct platform_driver imx_mc13783_audio_driver = { .owner = THIS_MODULE, }, .probe = imx_mc13783_probe, - .remove = __devexit_p(imx_mc13783_remove) + .remove = imx_mc13783_remove }; module_platform_driver(imx_mc13783_audio_driver); diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c index d85929b79c3..bf363d8d044 100644 --- a/sound/soc/fsl/imx-pcm-dma.c +++ b/sound/soc/fsl/imx-pcm-dma.c @@ -154,12 +154,12 @@ static struct snd_soc_platform_driver imx_soc_platform_mx2 = { .pcm_free = imx_pcm_free, }; -static int __devinit imx_soc_platform_probe(struct platform_device *pdev) +static int imx_soc_platform_probe(struct platform_device *pdev) { return snd_soc_register_platform(&pdev->dev, &imx_soc_platform_mx2); } -static int __devexit imx_soc_platform_remove(struct platform_device *pdev) +static int imx_soc_platform_remove(struct platform_device *pdev) { snd_soc_unregister_platform(&pdev->dev); return 0; @@ -171,7 +171,7 @@ static struct platform_driver imx_pcm_driver = { .owner = THIS_MODULE, }, .probe = imx_soc_platform_probe, - .remove = __devexit_p(imx_soc_platform_remove), + .remove = imx_soc_platform_remove, }; module_platform_driver(imx_pcm_driver); diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c index 22c6130957b..713bd79428a 100644 --- a/sound/soc/fsl/imx-pcm-fiq.c +++ b/sound/soc/fsl/imx-pcm-fiq.c @@ -282,7 +282,7 @@ static struct snd_soc_platform_driver imx_soc_platform_fiq = { .pcm_free = imx_pcm_fiq_free, }; -static int __devinit imx_soc_platform_probe(struct platform_device *pdev) +static int imx_soc_platform_probe(struct platform_device *pdev) { struct imx_ssi *ssi = platform_get_drvdata(pdev); int ret; @@ -316,7 +316,7 @@ failed_register: return ret; } -static int __devexit imx_soc_platform_remove(struct platform_device *pdev) +static int imx_soc_platform_remove(struct platform_device *pdev) { snd_soc_unregister_platform(&pdev->dev); return 0; @@ -329,7 +329,7 @@ static struct platform_driver imx_pcm_driver = { }, .probe = imx_soc_platform_probe, - .remove = __devexit_p(imx_soc_platform_remove), + .remove = imx_soc_platform_remove, }; module_platform_driver(imx_pcm_driver); diff --git a/sound/soc/fsl/imx-pcm.c b/sound/soc/fsl/imx-pcm.c index 93dc360b177..d5cd9eff3b4 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) } } EXPORT_SYMBOL_GPL(imx_pcm_free); + +MODULE_DESCRIPTION("Freescale i.MX PCM driver"); +MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c index 199408ec426..424347e9b2d 100644 --- a/sound/soc/fsl/imx-sgtl5000.c +++ b/sound/soc/fsl/imx-sgtl5000.c @@ -56,7 +56,7 @@ static const struct snd_soc_dapm_widget imx_sgtl5000_dapm_widgets[] = { SND_SOC_DAPM_SPK("Ext Spk", NULL), }; -static int __devinit imx_sgtl5000_probe(struct platform_device *pdev) +static int imx_sgtl5000_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct device_node *ssi_np, *codec_np; @@ -162,6 +162,7 @@ static int __devinit imx_sgtl5000_probe(struct platform_device *pdev) if (ret) goto clk_fail; data->card.num_links = 1; + data->card.owner = THIS_MODULE; data->card.dai_link = &data->dai; data->card.dapm_widgets = imx_sgtl5000_dapm_widgets; data->card.num_dapm_widgets = ARRAY_SIZE(imx_sgtl5000_dapm_widgets); @@ -184,7 +185,7 @@ fail: return ret; } -static int __devexit imx_sgtl5000_remove(struct platform_device *pdev) +static int imx_sgtl5000_remove(struct platform_device *pdev) { struct imx_sgtl5000_data *data = platform_get_drvdata(pdev); @@ -210,7 +211,7 @@ static struct platform_driver imx_sgtl5000_driver = { .of_match_table = imx_sgtl5000_dt_ids, }, .probe = imx_sgtl5000_probe, - .remove = __devexit_p(imx_sgtl5000_remove), + .remove = imx_sgtl5000_remove, }; module_platform_driver(imx_sgtl5000_driver); diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c index 006f7d465ed..2c8d89eecdc 100644 --- a/sound/soc/fsl/imx-ssi.c +++ b/sound/soc/fsl/imx-ssi.c @@ -639,7 +639,7 @@ failed_clk: return ret; } -static int __devexit imx_ssi_remove(struct platform_device *pdev) +static int imx_ssi_remove(struct platform_device *pdev) { struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); struct imx_ssi *ssi = platform_get_drvdata(pdev); @@ -660,7 +660,7 @@ static int __devexit imx_ssi_remove(struct platform_device *pdev) static struct platform_driver imx_ssi_driver = { .probe = imx_ssi_probe, - .remove = __devexit_p(imx_ssi_remove), + .remove = imx_ssi_remove, .driver = { .name = "imx-ssi", diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c index a313c0ae36d..a4aec0488dd 100644 --- a/sound/soc/fsl/mpc5200_psc_ac97.c +++ b/sound/soc/fsl/mpc5200_psc_ac97.c @@ -277,7 +277,7 @@ static struct snd_soc_dai_driver psc_ac97_dai[] = { * - Probe/remove operations * - OF device match table */ -static int __devinit psc_ac97_of_probe(struct platform_device *op) +static int psc_ac97_of_probe(struct platform_device *op) { int rc; struct snd_ac97 ac97; @@ -310,7 +310,7 @@ static int __devinit psc_ac97_of_probe(struct platform_device *op) return 0; } -static int __devexit psc_ac97_of_remove(struct platform_device *op) +static int psc_ac97_of_remove(struct platform_device *op) { mpc5200_audio_dma_destroy(op); snd_soc_unregister_dais(&op->dev, ARRAY_SIZE(psc_ac97_dai)); @@ -318,7 +318,7 @@ static int __devexit psc_ac97_of_remove(struct platform_device *op) } /* Match table for of_platform binding */ -static struct of_device_id psc_ac97_match[] __devinitdata = { +static struct of_device_id psc_ac97_match[] = { { .compatible = "fsl,mpc5200-psc-ac97", }, { .compatible = "fsl,mpc5200b-psc-ac97", }, {} @@ -327,7 +327,7 @@ MODULE_DEVICE_TABLE(of, psc_ac97_match); static struct platform_driver psc_ac97_driver = { .probe = psc_ac97_of_probe, - .remove = __devexit_p(psc_ac97_of_remove), + .remove = psc_ac97_of_remove, .driver = { .name = "mpc5200-psc-ac97", .owner = THIS_MODULE, diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c index ba1f0a66358..b95b966f25a 100644 --- a/sound/soc/fsl/mpc5200_psc_i2s.c +++ b/sound/soc/fsl/mpc5200_psc_i2s.c @@ -153,7 +153,7 @@ static struct snd_soc_dai_driver psc_i2s_dai[] = {{ * - Probe/remove operations * - OF device match table */ -static int __devinit psc_i2s_of_probe(struct platform_device *op) +static int psc_i2s_of_probe(struct platform_device *op) { int rc; struct psc_dma *psc_dma; @@ -205,7 +205,7 @@ static int __devinit psc_i2s_of_probe(struct platform_device *op) } -static int __devexit psc_i2s_of_remove(struct platform_device *op) +static int psc_i2s_of_remove(struct platform_device *op) { mpc5200_audio_dma_destroy(op); snd_soc_unregister_dais(&op->dev, ARRAY_SIZE(psc_i2s_dai)); @@ -213,7 +213,7 @@ static int __devexit psc_i2s_of_remove(struct platform_device *op) } /* Match table for of_platform binding */ -static struct of_device_id psc_i2s_match[] __devinitdata = { +static struct of_device_id psc_i2s_match[] = { { .compatible = "fsl,mpc5200-psc-i2s", }, { .compatible = "fsl,mpc5200b-psc-i2s", }, {} @@ -222,7 +222,7 @@ MODULE_DEVICE_TABLE(of, psc_i2s_match); static struct platform_driver psc_i2s_driver = { .probe = psc_i2s_of_probe, - .remove = __devexit_p(psc_i2s_of_remove), + .remove = psc_i2s_of_remove, .driver = { .name = "mpc5200-psc-i2s", .owner = THIS_MODULE, diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c index 9ff9318c52b..228c52e7144 100644 --- a/sound/soc/fsl/mpc8610_hpcd.c +++ b/sound/soc/fsl/mpc8610_hpcd.c @@ -368,7 +368,7 @@ error_alloc: * * This function is called when the platform device is removed. */ -static int __devexit mpc8610_hpcd_remove(struct platform_device *pdev) +static int mpc8610_hpcd_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); struct mpc8610_hpcd_data *machine_data = @@ -382,7 +382,7 @@ static int __devexit mpc8610_hpcd_remove(struct platform_device *pdev) static struct platform_driver mpc8610_hpcd_driver = { .probe = mpc8610_hpcd_probe, - .remove = __devexit_p(mpc8610_hpcd_remove), + .remove = mpc8610_hpcd_remove, .driver = { /* The name must match 'compatible' property in the device tree, * in lowercase letters. diff --git a/sound/soc/fsl/mx27vis-aic32x4.c b/sound/soc/fsl/mx27vis-aic32x4.c index 2b76877b178..3d107417905 100644 --- a/sound/soc/fsl/mx27vis-aic32x4.c +++ b/sound/soc/fsl/mx27vis-aic32x4.c @@ -180,7 +180,7 @@ static struct snd_soc_card mx27vis_aic32x4 = { .num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes), }; -static int __devinit mx27vis_aic32x4_probe(struct platform_device *pdev) +static int mx27vis_aic32x4_probe(struct platform_device *pdev) { struct snd_mx27vis_platform_data *pdata = pdev->dev.platform_data; int ret; @@ -219,7 +219,7 @@ static int __devinit mx27vis_aic32x4_probe(struct platform_device *pdev) return ret; } -static int __devexit mx27vis_aic32x4_remove(struct platform_device *pdev) +static int mx27vis_aic32x4_remove(struct platform_device *pdev) { snd_soc_unregister_card(&mx27vis_aic32x4); @@ -232,7 +232,7 @@ static struct platform_driver mx27vis_aic32x4_audio_driver = { .owner = THIS_MODULE, }, .probe = mx27vis_aic32x4_probe, - .remove = __devexit_p(mx27vis_aic32x4_remove), + .remove = mx27vis_aic32x4_remove, }; module_platform_driver(mx27vis_aic32x4_audio_driver); diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c index 144d4960363..ba59c23a137 100644 --- a/sound/soc/fsl/p1022_ds.c +++ b/sound/soc/fsl/p1022_ds.c @@ -376,7 +376,7 @@ error_put: * * This function is called when the platform device is removed. */ -static int __devexit p1022_ds_remove(struct platform_device *pdev) +static int p1022_ds_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); struct machine_data *mdata = @@ -390,7 +390,7 @@ static int __devexit p1022_ds_remove(struct platform_device *pdev) static struct platform_driver p1022_ds_driver = { .probe = p1022_ds_probe, - .remove = __devexit_p(p1022_ds_remove), + .remove = p1022_ds_remove, .driver = { /* * The name must match 'compatible' property in the device tree, diff --git a/sound/soc/fsl/p1022_rdk.c b/sound/soc/fsl/p1022_rdk.c new file mode 100644 index 00000000000..f2155191153 --- /dev/null +++ b/sound/soc/fsl/p1022_rdk.c @@ -0,0 +1,392 @@ +/** + * Freescale P1022RDK ALSA SoC Machine driver + * + * Author: Timur Tabi <timur@freescale.com> + * + * Copyright 2012 Freescale Semiconductor, Inc. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + * + * Note: in order for audio to work correctly, the output controls need + * to be enabled, because they control the clock. So for playback, for + * example: + * + * amixer sset 'Left Output Mixer PCM' on + * amixer sset 'Right Output Mixer PCM' on + */ + +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/of_device.h> +#include <linux/slab.h> +#include <sound/soc.h> +#include <asm/fsl_guts.h> + +#include "fsl_dma.h" +#include "fsl_ssi.h" +#include "fsl_utils.h" + +/* P1022-specific PMUXCR and DMUXCR bit definitions */ + +#define CCSR_GUTS_PMUXCR_UART0_I2C1_MASK 0x0001c000 +#define CCSR_GUTS_PMUXCR_UART0_I2C1_UART0_SSI 0x00010000 +#define CCSR_GUTS_PMUXCR_UART0_I2C1_SSI 0x00018000 + +#define CCSR_GUTS_PMUXCR_SSI_DMA_TDM_MASK 0x00000c00 +#define CCSR_GUTS_PMUXCR_SSI_DMA_TDM_SSI 0x00000000 + +#define CCSR_GUTS_DMUXCR_PAD 1 /* DMA controller/channel set to pad */ +#define CCSR_GUTS_DMUXCR_SSI 2 /* DMA controller/channel set to SSI */ + +/* + * Set the DMACR register in the GUTS + * + * The DMACR register determines the source of initiated transfers for each + * channel on each DMA controller. Rather than have a bunch of repetitive + * macros for the bit patterns, we just have a function that calculates + * them. + * + * guts: Pointer to GUTS structure + * co: The DMA controller (0 or 1) + * ch: The channel on the DMA controller (0, 1, 2, or 3) + * device: The device to set as the target (CCSR_GUTS_DMUXCR_xxx) + */ +static inline void guts_set_dmuxcr(struct ccsr_guts __iomem *guts, + unsigned int co, unsigned int ch, unsigned int device) +{ + unsigned int shift = 16 + (8 * (1 - co) + 2 * (3 - ch)); + + clrsetbits_be32(&guts->dmuxcr, 3 << shift, device << shift); +} + +/* There's only one global utilities register */ +static phys_addr_t guts_phys; + +/** + * machine_data: machine-specific ASoC device data + * + * This structure contains data for a single sound platform device on an + * P1022 RDK. Some of the data is taken from the device tree. + */ +struct machine_data { + struct snd_soc_dai_link dai[2]; + struct snd_soc_card card; + unsigned int dai_format; + unsigned int codec_clk_direction; + unsigned int cpu_clk_direction; + unsigned int clk_frequency; + unsigned int dma_id[2]; /* 0 = DMA1, 1 = DMA2, etc */ + unsigned int dma_channel_id[2]; /* 0 = ch 0, 1 = ch 1, etc*/ + char platform_name[2][DAI_NAME_SIZE]; /* One for each DMA channel */ +}; + +/** + * p1022_rdk_machine_probe: initialize the board + * + * This function is used to initialize the board-specific hardware. + * + * Here we program the DMACR and PMUXCR registers. + */ +static int p1022_rdk_machine_probe(struct snd_soc_card *card) +{ + struct machine_data *mdata = + container_of(card, struct machine_data, card); + struct ccsr_guts __iomem *guts; + + guts = ioremap(guts_phys, sizeof(struct ccsr_guts)); + if (!guts) { + dev_err(card->dev, "could not map global utilities\n"); + return -ENOMEM; + } + + /* Enable SSI Tx signal */ + clrsetbits_be32(&guts->pmuxcr, CCSR_GUTS_PMUXCR_UART0_I2C1_MASK, + CCSR_GUTS_PMUXCR_UART0_I2C1_UART0_SSI); + + /* Enable SSI Rx signal */ + clrsetbits_be32(&guts->pmuxcr, CCSR_GUTS_PMUXCR_SSI_DMA_TDM_MASK, + CCSR_GUTS_PMUXCR_SSI_DMA_TDM_SSI); + + /* Enable DMA Channel for SSI */ + guts_set_dmuxcr(guts, mdata->dma_id[0], mdata->dma_channel_id[0], + CCSR_GUTS_DMUXCR_SSI); + + guts_set_dmuxcr(guts, mdata->dma_id[1], mdata->dma_channel_id[1], + CCSR_GUTS_DMUXCR_SSI); + + iounmap(guts); + + return 0; +} + +/** + * p1022_rdk_startup: program the board with various hardware parameters + * + * This function takes board-specific information, like clock frequencies + * and serial data formats, and passes that information to the codec and + * transport drivers. + */ +static int p1022_rdk_startup(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct machine_data *mdata = + container_of(rtd->card, struct machine_data, card); + struct device *dev = rtd->card->dev; + int ret = 0; + + /* Tell the codec driver what the serial protocol is. */ + ret = snd_soc_dai_set_fmt(rtd->codec_dai, mdata->dai_format); + if (ret < 0) { + dev_err(dev, "could not set codec driver audio format (ret=%i)\n", + ret); + return ret; + } + + ret = snd_soc_dai_set_pll(rtd->codec_dai, 0, 0, mdata->clk_frequency, + mdata->clk_frequency); + if (ret < 0) { + dev_err(dev, "could not set codec PLL frequency (ret=%i)\n", + ret); + return ret; + } + + return 0; +} + +/** + * p1022_rdk_machine_remove: Remove the sound device + * + * This function is called to remove the sound device for one SSI. We + * de-program the DMACR and PMUXCR register. + */ +static int p1022_rdk_machine_remove(struct snd_soc_card *card) +{ + struct machine_data *mdata = + container_of(card, struct machine_data, card); + struct ccsr_guts __iomem *guts; + + guts = ioremap(guts_phys, sizeof(struct ccsr_guts)); + if (!guts) { + dev_err(card->dev, "could not map global utilities\n"); + return -ENOMEM; + } + + /* Restore the signal routing */ + clrbits32(&guts->pmuxcr, CCSR_GUTS_PMUXCR_UART0_I2C1_MASK); + clrbits32(&guts->pmuxcr, CCSR_GUTS_PMUXCR_SSI_DMA_TDM_MASK); + guts_set_dmuxcr(guts, mdata->dma_id[0], mdata->dma_channel_id[0], 0); + guts_set_dmuxcr(guts, mdata->dma_id[1], mdata->dma_channel_id[1], 0); + + iounmap(guts); + + return 0; +} + +/** + * p1022_rdk_ops: ASoC machine driver operations + */ +static struct snd_soc_ops p1022_rdk_ops = { + .startup = p1022_rdk_startup, +}; + +/** + * p1022_rdk_probe: platform probe function for the machine driver + * + * Although this is a machine driver, the SSI node is the "master" node with + * respect to audio hardware connections. Therefore, we create a new ASoC + * device for each new SSI node that has a codec attached. + */ +static int p1022_rdk_probe(struct platform_device *pdev) +{ + struct device *dev = pdev->dev.parent; + /* ssi_pdev is the platform device for the SSI node that probed us */ + struct platform_device *ssi_pdev = + container_of(dev, struct platform_device, dev); + struct device_node *np = ssi_pdev->dev.of_node; + struct device_node *codec_np = NULL; + struct machine_data *mdata; + const u32 *iprop; + int ret; + + /* Find the codec node for this SSI. */ + codec_np = of_parse_phandle(np, "codec-handle", 0); + if (!codec_np) { + dev_err(dev, "could not find codec node\n"); + return -EINVAL; + } + + mdata = kzalloc(sizeof(struct machine_data), GFP_KERNEL); + if (!mdata) { + ret = -ENOMEM; + goto error_put; + } + + mdata->dai[0].cpu_dai_name = dev_name(&ssi_pdev->dev); + mdata->dai[0].ops = &p1022_rdk_ops; + + /* ASoC core can match codec with device node */ + mdata->dai[0].codec_of_node = codec_np; + + /* + * We register two DAIs per SSI, one for playback and the other for + * capture. We support codecs that have separate DAIs for both playback + * and capture. + */ + memcpy(&mdata->dai[1], &mdata->dai[0], sizeof(struct snd_soc_dai_link)); + + /* The DAI names from the codec (snd_soc_dai_driver.name) */ + mdata->dai[0].codec_dai_name = "wm8960-hifi"; + mdata->dai[1].codec_dai_name = mdata->dai[0].codec_dai_name; + + /* + * Configure the SSI for I2S slave mode. Older device trees have + * an fsl,mode property, but we ignore that since there's really + * only one way to configure the SSI. + */ + mdata->dai_format = SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM; + mdata->codec_clk_direction = SND_SOC_CLOCK_OUT; + mdata->cpu_clk_direction = SND_SOC_CLOCK_IN; + + /* + * In i2s-slave mode, the codec has its own clock source, so we + * need to get the frequency from the device tree and pass it to + * the codec driver. + */ + iprop = of_get_property(codec_np, "clock-frequency", NULL); + if (!iprop || !*iprop) { + dev_err(&pdev->dev, "codec bus-frequency property is missing or invalid\n"); + ret = -EINVAL; + goto error; + } + mdata->clk_frequency = be32_to_cpup(iprop); + + if (!mdata->clk_frequency) { + dev_err(&pdev->dev, "unknown clock frequency\n"); + ret = -EINVAL; + goto error; + } + + /* Find the playback DMA channel to use. */ + mdata->dai[0].platform_name = mdata->platform_name[0]; + ret = fsl_asoc_get_dma_channel(np, "fsl,playback-dma", &mdata->dai[0], + &mdata->dma_channel_id[0], + &mdata->dma_id[0]); + if (ret) { + dev_err(&pdev->dev, "missing/invalid playback DMA phandle (ret=%i)\n", + ret); + goto error; + } + + /* Find the capture DMA channel to use. */ + mdata->dai[1].platform_name = mdata->platform_name[1]; + ret = fsl_asoc_get_dma_channel(np, "fsl,capture-dma", &mdata->dai[1], + &mdata->dma_channel_id[1], + &mdata->dma_id[1]); + if (ret) { + dev_err(&pdev->dev, "missing/invalid capture DMA phandle (ret=%i)\n", + ret); + goto error; + } + + /* Initialize our DAI data structure. */ + mdata->dai[0].stream_name = "playback"; + mdata->dai[1].stream_name = "capture"; + mdata->dai[0].name = mdata->dai[0].stream_name; + mdata->dai[1].name = mdata->dai[1].stream_name; + + mdata->card.probe = p1022_rdk_machine_probe; + mdata->card.remove = p1022_rdk_machine_remove; + mdata->card.name = pdev->name; /* The platform driver name */ + mdata->card.owner = THIS_MODULE; + mdata->card.dev = &pdev->dev; + mdata->card.num_links = 2; + mdata->card.dai_link = mdata->dai; + + /* Register with ASoC */ + ret = snd_soc_register_card(&mdata->card); + if (ret) { + dev_err(&pdev->dev, "could not register card (ret=%i)\n", ret); + goto error; + } + + return 0; + +error: + kfree(mdata); +error_put: + of_node_put(codec_np); + return ret; +} + +/** + * p1022_rdk_remove: remove the platform device + * + * This function is called when the platform device is removed. + */ +static int p1022_rdk_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct machine_data *mdata = + container_of(card, struct machine_data, card); + + snd_soc_unregister_card(card); + kfree(mdata); + + return 0; +} + +static struct platform_driver p1022_rdk_driver = { + .probe = p1022_rdk_probe, + .remove = p1022_rdk_remove, + .driver = { + /* + * The name must match 'compatible' property in the device tree, + * in lowercase letters. + */ + .name = "snd-soc-p1022rdk", + .owner = THIS_MODULE, + }, +}; + +/** + * p1022_rdk_init: machine driver initialization. + * + * This function is called when this module is loaded. + */ +static int __init p1022_rdk_init(void) +{ + struct device_node *guts_np; + struct resource res; + + /* Get the physical address of the global utilities registers */ + guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts"); + if (of_address_to_resource(guts_np, 0, &res)) { + pr_err("snd-soc-p1022rdk: missing/invalid global utils node\n"); + of_node_put(guts_np); + return -EINVAL; + } + guts_phys = res.start; + of_node_put(guts_np); + + return platform_driver_register(&p1022_rdk_driver); +} + +/** + * p1022_rdk_exit: machine driver exit + * + * This function is called when this driver is unloaded. + */ +static void __exit p1022_rdk_exit(void) +{ + platform_driver_unregister(&p1022_rdk_driver); +} + +late_initcall(p1022_rdk_init); +module_exit(p1022_rdk_exit); + +MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); +MODULE_DESCRIPTION("Freescale / iVeia P1022 RDK ALSA SoC machine driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/fsl/pcm030-audio-fabric.c b/sound/soc/fsl/pcm030-audio-fabric.c index 4b63ec8eb37..8e52c1485df 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 { static struct snd_soc_dai_link pcm030_fabric_dai[] = { { - .name = "AC97", + .name = "AC97.0", .stream_name = "AC97 Analog", .codec_dai_name = "wm9712-hifi", .cpu_dai_name = "mpc5200-psc-ac97.0", .codec_name = "wm9712-codec", }, { - .name = "AC97", + .name = "AC97.1", .stream_name = "AC97 IEC958", .codec_dai_name = "wm9712-aux", .cpu_dai_name = "mpc5200-psc-ac97.1", @@ -101,7 +101,7 @@ static int __init pcm030_fabric_probe(struct platform_device *op) return ret; } -static int __devexit pcm030_fabric_remove(struct platform_device *op) +static int pcm030_fabric_remove(struct platform_device *op) { struct pcm030_audio_data *pdata = platform_get_drvdata(op); int ret; @@ -120,7 +120,7 @@ MODULE_DEVICE_TABLE(of, pcm030_audio_match); static struct platform_driver pcm030_fabric_driver = { .probe = pcm030_fabric_probe, - .remove = __devexit_p(pcm030_fabric_remove), + .remove = pcm030_fabric_remove, .driver = { .name = DRV_NAME, .owner = THIS_MODULE, diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c index 41349670ada..6cef491f482 100644 --- a/sound/soc/jz4740/jz4740-i2s.c +++ b/sound/soc/jz4740/jz4740-i2s.c @@ -425,7 +425,7 @@ static struct snd_soc_dai_driver jz4740_i2s_dai = { .resume = jz4740_i2s_resume, }; -static int __devinit jz4740_i2s_dev_probe(struct platform_device *pdev) +static int jz4740_i2s_dev_probe(struct platform_device *pdev) { struct jz4740_i2s *i2s; int ret; @@ -492,7 +492,7 @@ err_free: return ret; } -static int __devexit jz4740_i2s_dev_remove(struct platform_device *pdev) +static int jz4740_i2s_dev_remove(struct platform_device *pdev) { struct jz4740_i2s *i2s = platform_get_drvdata(pdev); @@ -512,7 +512,7 @@ static int __devexit jz4740_i2s_dev_remove(struct platform_device *pdev) static struct platform_driver jz4740_i2s_driver = { .probe = jz4740_i2s_dev_probe, - .remove = __devexit_p(jz4740_i2s_dev_remove), + .remove = jz4740_i2s_dev_remove, .driver = { .name = "jz4740-i2s", .owner = THIS_MODULE, diff --git a/sound/soc/jz4740/jz4740-pcm.c b/sound/soc/jz4740/jz4740-pcm.c index 9b8cf256847..71005929231 100644 --- a/sound/soc/jz4740/jz4740-pcm.c +++ b/sound/soc/jz4740/jz4740-pcm.c @@ -335,12 +335,12 @@ static struct snd_soc_platform_driver jz4740_soc_platform = { .pcm_free = jz4740_pcm_free, }; -static int __devinit jz4740_pcm_probe(struct platform_device *pdev) +static int jz4740_pcm_probe(struct platform_device *pdev) { return snd_soc_register_platform(&pdev->dev, &jz4740_soc_platform); } -static int __devexit jz4740_pcm_remove(struct platform_device *pdev) +static int jz4740_pcm_remove(struct platform_device *pdev) { snd_soc_unregister_platform(&pdev->dev); return 0; @@ -348,7 +348,7 @@ static int __devexit jz4740_pcm_remove(struct platform_device *pdev) static struct platform_driver jz4740_pcm_driver = { .probe = jz4740_pcm_probe, - .remove = __devexit_p(jz4740_pcm_remove), + .remove = jz4740_pcm_remove, .driver = { .name = "jz4740-pcm-audio", .owner = THIS_MODULE, diff --git a/sound/soc/jz4740/qi_lb60.c b/sound/soc/jz4740/qi_lb60.c index e8aaff18d7c..55fd6b5df55 100644 --- a/sound/soc/jz4740/qi_lb60.c +++ b/sound/soc/jz4740/qi_lb60.c @@ -96,7 +96,7 @@ static const struct gpio qi_lb60_gpios[] = { { QI_LB60_AMP_GPIO, GPIOF_OUT_INIT_LOW, "AMP" }, }; -static int __devinit qi_lb60_probe(struct platform_device *pdev) +static int qi_lb60_probe(struct platform_device *pdev) { struct snd_soc_card *card = &qi_lb60; int ret; @@ -116,7 +116,7 @@ static int __devinit qi_lb60_probe(struct platform_device *pdev) return ret; } -static int __devexit qi_lb60_remove(struct platform_device *pdev) +static int qi_lb60_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -131,7 +131,7 @@ static struct platform_driver qi_lb60_driver = { .owner = THIS_MODULE, }, .probe = qi_lb60_probe, - .remove = __devexit_p(qi_lb60_remove), + .remove = qi_lb60_remove, }; module_platform_driver(qi_lb60_driver); diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c index 2ba08148655..d3d4bdca1cc 100644 --- a/sound/soc/kirkwood/kirkwood-dma.c +++ b/sound/soc/kirkwood/kirkwood-dma.c @@ -22,12 +22,16 @@ #include "kirkwood.h" #define KIRKWOOD_RATES \ - (SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000) + (SNDRV_PCM_RATE_8000_192000 | \ + SNDRV_PCM_RATE_CONTINUOUS | \ + SNDRV_PCM_RATE_KNOT) + #define KIRKWOOD_FORMATS \ (SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S24_LE | \ - SNDRV_PCM_FMTBIT_S32_LE) + SNDRV_PCM_FMTBIT_S32_LE | \ + SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE | \ + SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE) struct kirkwood_dma_priv { struct snd_pcm_substream *play_stream; @@ -43,10 +47,10 @@ static struct snd_pcm_hardware kirkwood_dma_snd_hw = { SNDRV_PCM_INFO_PAUSE), .formats = KIRKWOOD_FORMATS, .rates = KIRKWOOD_RATES, - .rate_min = 44100, - .rate_max = 96000, + .rate_min = 8000, + .rate_max = 384000, .channels_min = 1, - .channels_max = 2, + .channels_max = 8, .buffer_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES * KIRKWOOD_SND_MAX_PERIODS, .period_bytes_min = KIRKWOOD_SND_MIN_PERIOD_BYTES, .period_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES, @@ -368,12 +372,12 @@ static struct snd_soc_platform_driver kirkwood_soc_platform = { .pcm_free = kirkwood_dma_free_dma_buffers, }; -static int __devinit kirkwood_soc_platform_probe(struct platform_device *pdev) +static int kirkwood_soc_platform_probe(struct platform_device *pdev) { return snd_soc_register_platform(&pdev->dev, &kirkwood_soc_platform); } -static int __devexit kirkwood_soc_platform_remove(struct platform_device *pdev) +static int kirkwood_soc_platform_remove(struct platform_device *pdev) { snd_soc_unregister_platform(&pdev->dev); return 0; @@ -386,7 +390,7 @@ static struct platform_driver kirkwood_pcm_driver = { }, .probe = kirkwood_soc_platform_probe, - .remove = __devexit_p(kirkwood_soc_platform_remove), + .remove = kirkwood_soc_platform_remove, }; module_platform_driver(kirkwood_pcm_driver); diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c index 1d5db484d2d..282d8b1163b 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) } while (value == 0); } +static void kirkwood_set_rate(struct snd_soc_dai *dai, + struct kirkwood_dma_data *priv, unsigned long rate) +{ + uint32_t clks_ctrl; + + if (rate == 44100 || rate == 48000 || rate == 96000) { + /* use internal dco for supported rates */ + dev_dbg(dai->dev, "%s: dco set rate = %lu\n", + __func__, rate); + kirkwood_set_dco(priv->io, rate); + + clks_ctrl = KIRKWOOD_MCLK_SOURCE_DCO; + } else if (!IS_ERR(priv->extclk)) { + /* use optional external clk for other rates */ + dev_dbg(dai->dev, "%s: extclk set rate = %lu -> %lu\n", + __func__, rate, 256 * rate); + clk_set_rate(priv->extclk, 256 * rate); + + clks_ctrl = KIRKWOOD_MCLK_SOURCE_EXTCLK; + } + writel(clks_ctrl, priv->io + KIRKWOOD_CLOCKS_CTRL); +} + static int kirkwood_i2s_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { @@ -113,26 +136,21 @@ static int kirkwood_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); - unsigned int i2s_reg, reg; - unsigned long i2s_value, value; + uint32_t ctl_play, ctl_rec; + unsigned int i2s_reg; + unsigned long i2s_value; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { i2s_reg = KIRKWOOD_I2S_PLAYCTL; - reg = KIRKWOOD_PLAYCTL; } else { i2s_reg = KIRKWOOD_I2S_RECCTL; - reg = KIRKWOOD_RECCTL; } - /* set dco conf */ - kirkwood_set_dco(priv->io, params_rate(params)); + kirkwood_set_rate(dai, priv, params_rate(params)); i2s_value = readl(priv->io+i2s_reg); i2s_value &= ~KIRKWOOD_I2S_CTL_SIZE_MASK; - value = readl(priv->io+reg); - value &= ~KIRKWOOD_PLAYCTL_SIZE_MASK; - /* * Size settings in play/rec i2s control regs and play/rec control * regs must be the same. @@ -140,38 +158,57 @@ static int kirkwood_i2s_hw_params(struct snd_pcm_substream *substream, switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: i2s_value |= KIRKWOOD_I2S_CTL_SIZE_16; - value |= KIRKWOOD_PLAYCTL_SIZE_16_C; + ctl_play = KIRKWOOD_PLAYCTL_SIZE_16_C | + KIRKWOOD_PLAYCTL_I2S_EN; + ctl_rec = KIRKWOOD_RECCTL_SIZE_16_C | + KIRKWOOD_RECCTL_I2S_EN; break; /* * doesn't work... S20_3LE != kirkwood 20bit format ? * case SNDRV_PCM_FORMAT_S20_3LE: i2s_value |= KIRKWOOD_I2S_CTL_SIZE_20; - value |= KIRKWOOD_PLAYCTL_SIZE_20; + ctl_play = KIRKWOOD_PLAYCTL_SIZE_20 | + KIRKWOOD_PLAYCTL_I2S_EN; + ctl_rec = KIRKWOOD_RECCTL_SIZE_20 | + KIRKWOOD_RECCTL_I2S_EN; break; */ case SNDRV_PCM_FORMAT_S24_LE: i2s_value |= KIRKWOOD_I2S_CTL_SIZE_24; - value |= KIRKWOOD_PLAYCTL_SIZE_24; + ctl_play = KIRKWOOD_PLAYCTL_SIZE_24 | + KIRKWOOD_PLAYCTL_I2S_EN; + ctl_rec = KIRKWOOD_RECCTL_SIZE_24 | + KIRKWOOD_RECCTL_I2S_EN; break; case SNDRV_PCM_FORMAT_S32_LE: i2s_value |= KIRKWOOD_I2S_CTL_SIZE_32; - value |= KIRKWOOD_PLAYCTL_SIZE_32; + ctl_play = KIRKWOOD_PLAYCTL_SIZE_32 | + KIRKWOOD_PLAYCTL_I2S_EN; + ctl_rec = KIRKWOOD_RECCTL_SIZE_32 | + KIRKWOOD_RECCTL_I2S_EN; break; default: return -EINVAL; } if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - value &= ~KIRKWOOD_PLAYCTL_MONO_MASK; if (params_channels(params) == 1) - value |= KIRKWOOD_PLAYCTL_MONO_BOTH; + ctl_play |= KIRKWOOD_PLAYCTL_MONO_BOTH; else - value |= KIRKWOOD_PLAYCTL_MONO_OFF; + ctl_play |= KIRKWOOD_PLAYCTL_MONO_OFF; + + priv->ctl_play &= ~(KIRKWOOD_PLAYCTL_MONO_MASK | + KIRKWOOD_PLAYCTL_I2S_EN | + KIRKWOOD_PLAYCTL_SPDIF_EN | + KIRKWOOD_PLAYCTL_SIZE_MASK); + priv->ctl_play |= ctl_play; + } else { + priv->ctl_rec &= ~KIRKWOOD_RECCTL_SIZE_MASK; + priv->ctl_rec |= ctl_rec; } writel(i2s_value, priv->io+i2s_reg); - writel(value, priv->io+reg); return 0; } @@ -205,20 +242,18 @@ static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream, switch (cmd) { case SNDRV_PCM_TRIGGER_START: + /* configure */ + ctl = priv->ctl_play; + value = ctl & ~(KIRKWOOD_PLAYCTL_I2S_EN | + KIRKWOOD_PLAYCTL_SPDIF_EN); + writel(value, priv->io + KIRKWOOD_PLAYCTL); + + /* enable interrupts */ value = readl(priv->io + KIRKWOOD_INT_MASK); value |= KIRKWOOD_INT_CAUSE_PLAY_BYTES; writel(value, priv->io + KIRKWOOD_INT_MASK); - /* configure audio & enable i2s playback */ - ctl &= ~KIRKWOOD_PLAYCTL_BURST_MASK; - ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE - | KIRKWOOD_PLAYCTL_SPDIF_EN); - - if (priv->burst == 32) - ctl |= KIRKWOOD_PLAYCTL_BURST_32; - else - ctl |= KIRKWOOD_PLAYCTL_BURST_128; - ctl |= KIRKWOOD_PLAYCTL_I2S_EN; + /* enable playback */ writel(ctl, priv->io + KIRKWOOD_PLAYCTL); break; @@ -259,30 +294,24 @@ static int kirkwood_i2s_rec_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); - unsigned long value; + uint32_t ctl, value; value = readl(priv->io + KIRKWOOD_RECCTL); switch (cmd) { case SNDRV_PCM_TRIGGER_START: + /* configure */ + ctl = priv->ctl_rec; + value = ctl & ~KIRKWOOD_RECCTL_I2S_EN; + writel(value, priv->io + KIRKWOOD_RECCTL); + + /* enable interrupts */ value = readl(priv->io + KIRKWOOD_INT_MASK); value |= KIRKWOOD_INT_CAUSE_REC_BYTES; writel(value, priv->io + KIRKWOOD_INT_MASK); - /* configure audio & enable i2s record */ - value = readl(priv->io + KIRKWOOD_RECCTL); - value &= ~KIRKWOOD_RECCTL_BURST_MASK; - value &= ~KIRKWOOD_RECCTL_MONO; - value &= ~(KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE - | KIRKWOOD_RECCTL_SPDIF_EN); - - if (priv->burst == 32) - value |= KIRKWOOD_RECCTL_BURST_32; - else - value |= KIRKWOOD_RECCTL_BURST_128; - value |= KIRKWOOD_RECCTL_I2S_EN; - - writel(value, priv->io + KIRKWOOD_RECCTL); + /* enable record */ + writel(ctl, priv->io + KIRKWOOD_RECCTL); break; case SNDRV_PCM_TRIGGER_STOP: @@ -389,112 +418,146 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai = { .channels_min = 1, .channels_max = 2, .rates = KIRKWOOD_I2S_RATES, - .formats = KIRKWOOD_I2S_FORMATS,}, + .formats = KIRKWOOD_I2S_FORMATS, + }, .capture = { .channels_min = 1, .channels_max = 2, .rates = KIRKWOOD_I2S_RATES, - .formats = KIRKWOOD_I2S_FORMATS,}, + .formats = KIRKWOOD_I2S_FORMATS, + }, .ops = &kirkwood_i2s_dai_ops, }; -static __devinit int kirkwood_i2s_dev_probe(struct platform_device *pdev) +static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk = { + .probe = kirkwood_i2s_probe, + .remove = kirkwood_i2s_remove, + .playback = { + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000 | + SNDRV_PCM_RATE_CONTINUOUS | + SNDRV_PCM_RATE_KNOT, + .formats = KIRKWOOD_I2S_FORMATS, + }, + .capture = { + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000 | + SNDRV_PCM_RATE_CONTINUOUS | + SNDRV_PCM_RATE_KNOT, + .formats = KIRKWOOD_I2S_FORMATS, + }, + .ops = &kirkwood_i2s_dai_ops, +}; + +static int kirkwood_i2s_dev_probe(struct platform_device *pdev) { - struct resource *mem; - struct kirkwood_asoc_platform_data *data = - pdev->dev.platform_data; + struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data; + struct snd_soc_dai_driver *soc_dai = &kirkwood_i2s_dai; struct kirkwood_dma_data *priv; + struct resource *mem; int err; - priv = kzalloc(sizeof(struct kirkwood_dma_data), GFP_KERNEL); + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) { dev_err(&pdev->dev, "allocation failed\n"); - err = -ENOMEM; - goto error; + return -ENOMEM; } dev_set_drvdata(&pdev->dev, priv); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { dev_err(&pdev->dev, "platform_get_resource failed\n"); - err = -ENXIO; - goto err_alloc; - } - - priv->mem = request_mem_region(mem->start, SZ_16K, DRV_NAME); - if (!priv->mem) { - dev_err(&pdev->dev, "request_mem_region failed\n"); - err = -EBUSY; - goto err_alloc; + return -ENXIO; } - priv->io = ioremap(priv->mem->start, SZ_16K); + priv->io = devm_request_and_ioremap(&pdev->dev, mem); if (!priv->io) { - dev_err(&pdev->dev, "ioremap failed\n"); - err = -ENOMEM; - goto err_iomem; + dev_err(&pdev->dev, "devm_request_and_ioremap failed\n"); + return -ENOMEM; } priv->irq = platform_get_irq(pdev, 0); if (priv->irq <= 0) { dev_err(&pdev->dev, "platform_get_irq failed\n"); - err = -ENXIO; - goto err_ioremap; + return -ENXIO; } if (!data) { dev_err(&pdev->dev, "no platform data ?!\n"); - err = -EINVAL; - goto err_ioremap; + return -EINVAL; } priv->burst = data->burst; - priv->clk = clk_get(&pdev->dev, NULL); + priv->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(priv->clk)) { dev_err(&pdev->dev, "no clock\n"); - err = PTR_ERR(priv->clk); - goto err_ioremap; + return PTR_ERR(priv->clk); + } + + err = clk_prepare_enable(priv->clk); + if (err < 0) + return err; + + priv->extclk = clk_get(&pdev->dev, "extclk"); + if (!IS_ERR(priv->extclk)) { + if (priv->extclk == priv->clk) { + clk_put(priv->extclk); + priv->extclk = ERR_PTR(-EINVAL); + } else { + dev_info(&pdev->dev, "found external clock\n"); + clk_prepare_enable(priv->extclk); + soc_dai = &kirkwood_i2s_dai_extclk; + } + } + + /* Some sensible defaults - this reflects the powerup values */ + priv->ctl_play = KIRKWOOD_PLAYCTL_SIZE_24; + priv->ctl_rec = KIRKWOOD_RECCTL_SIZE_24; + + /* Select the burst size */ + if (data->burst == 32) { + priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_32; + priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_32; + } else { + priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_128; + priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_128; } - clk_prepare_enable(priv->clk); - err = snd_soc_register_dai(&pdev->dev, &kirkwood_i2s_dai); + err = snd_soc_register_dai(&pdev->dev, soc_dai); if (!err) return 0; dev_err(&pdev->dev, "snd_soc_register_dai failed\n"); + if (!IS_ERR(priv->extclk)) { + clk_disable_unprepare(priv->extclk); + clk_put(priv->extclk); + } clk_disable_unprepare(priv->clk); - clk_put(priv->clk); - -err_ioremap: - iounmap(priv->io); -err_iomem: - release_mem_region(priv->mem->start, SZ_16K); -err_alloc: - kfree(priv); -error: + return err; } -static __devexit int kirkwood_i2s_dev_remove(struct platform_device *pdev) +static int kirkwood_i2s_dev_remove(struct platform_device *pdev) { struct kirkwood_dma_data *priv = dev_get_drvdata(&pdev->dev); snd_soc_unregister_dai(&pdev->dev); + if (!IS_ERR(priv->extclk)) { + clk_disable_unprepare(priv->extclk); + clk_put(priv->extclk); + } clk_disable_unprepare(priv->clk); - clk_put(priv->clk); - - iounmap(priv->io); - release_mem_region(priv->mem->start, SZ_16K); - kfree(priv); return 0; } static struct platform_driver kirkwood_i2s_driver = { .probe = kirkwood_i2s_dev_probe, - .remove = __devexit_p(kirkwood_i2s_dev_remove), + .remove = kirkwood_i2s_dev_remove, .driver = { .name = DRV_NAME, .owner = THIS_MODULE, diff --git a/sound/soc/kirkwood/kirkwood-openrd.c b/sound/soc/kirkwood/kirkwood-openrd.c index c28540aeea2..b979c715471 100644 --- a/sound/soc/kirkwood/kirkwood-openrd.c +++ b/sound/soc/kirkwood/kirkwood-openrd.c @@ -71,7 +71,7 @@ static struct snd_soc_card openrd_client = { .num_links = ARRAY_SIZE(openrd_client_dai), }; -static int __devinit openrd_probe(struct platform_device *pdev) +static int openrd_probe(struct platform_device *pdev) { struct snd_soc_card *card = &openrd_client; int ret; @@ -85,7 +85,7 @@ static int __devinit openrd_probe(struct platform_device *pdev) return ret; } -static int __devexit openrd_remove(struct platform_device *pdev) +static int openrd_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -99,7 +99,7 @@ static struct platform_driver openrd_driver = { .owner = THIS_MODULE, }, .probe = openrd_probe, - .remove = __devexit_p(openrd_remove), + .remove = openrd_remove, }; module_platform_driver(openrd_driver); diff --git a/sound/soc/kirkwood/kirkwood-t5325.c b/sound/soc/kirkwood/kirkwood-t5325.c index c67bbc57498..1d0ed6f8add 100644 --- a/sound/soc/kirkwood/kirkwood-t5325.c +++ b/sound/soc/kirkwood/kirkwood-t5325.c @@ -92,7 +92,7 @@ static struct snd_soc_card t5325 = { .num_dapm_routes = ARRAY_SIZE(t5325_route), }; -static int __devinit t5325_probe(struct platform_device *pdev) +static int t5325_probe(struct platform_device *pdev) { struct snd_soc_card *card = &t5325; int ret; @@ -106,7 +106,7 @@ static int __devinit t5325_probe(struct platform_device *pdev) return ret; } -static int __devexit t5325_remove(struct platform_device *pdev) +static int t5325_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -120,7 +120,7 @@ static struct platform_driver t5325_driver = { .owner = THIS_MODULE, }, .probe = t5325_probe, - .remove = __devexit_p(t5325_remove), + .remove = t5325_remove, }; module_platform_driver(t5325_driver); diff --git a/sound/soc/kirkwood/kirkwood.h b/sound/soc/kirkwood/kirkwood.h index f9084d83e6b..4d92637ddb3 100644 --- a/sound/soc/kirkwood/kirkwood.h +++ b/sound/soc/kirkwood/kirkwood.h @@ -77,6 +77,11 @@ #define KIRKWOOD_DCO_SPCR_STATUS 0x120c #define KIRKWOOD_DCO_SPCR_STATUS_DCO_LOCK (1<<16) +#define KIRKWOOD_CLOCKS_CTRL 0x1230 +#define KIRKWOOD_MCLK_SOURCE_MASK (3<<0) +#define KIRKWOOD_MCLK_SOURCE_DCO (0<<0) +#define KIRKWOOD_MCLK_SOURCE_EXTCLK (3<<0) + #define KIRKWOOD_ERR_CAUSE 0x1300 #define KIRKWOOD_ERR_MASK 0x1304 @@ -119,11 +124,13 @@ #define KIRKWOOD_SND_MAX_PERIOD_BYTES 0x4000 struct kirkwood_dma_data { - struct resource *mem; void __iomem *io; + struct clk *clk; + struct clk *extclk; + uint32_t ctl_play; + uint32_t ctl_rec; int irq; int burst; - struct clk *clk; }; #endif diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c index 2cc7782714b..4139116c33b 100644 --- a/sound/soc/mid-x86/mfld_machine.c +++ b/sound/soc/mid-x86/mfld_machine.c @@ -358,7 +358,7 @@ static irqreturn_t snd_mfld_jack_detection(int irq, void *data) return IRQ_HANDLED; } -static int __devinit snd_mfld_mc_probe(struct platform_device *pdev) +static int snd_mfld_mc_probe(struct platform_device *pdev) { int ret_val = 0, irq; struct mfld_mc_private *mc_drv_ctx; @@ -417,7 +417,7 @@ unalloc: return ret_val; } -static int __devexit snd_mfld_mc_remove(struct platform_device *pdev) +static int snd_mfld_mc_remove(struct platform_device *pdev) { struct mfld_mc_private *mc_drv_ctx = platform_get_drvdata(pdev); @@ -435,7 +435,7 @@ static struct platform_driver snd_mfld_mc_driver = { .name = "msic_audio", }, .probe = snd_mfld_mc_probe, - .remove = __devexit_p(snd_mfld_mc_remove), + .remove = snd_mfld_mc_remove, }; module_platform_driver(snd_mfld_mc_driver); diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c index f82d766cbf9..564b5b60319 100644 --- a/sound/soc/mxs/mxs-pcm.c +++ b/sound/soc/mxs/mxs-pcm.c @@ -220,13 +220,13 @@ static struct snd_soc_platform_driver mxs_soc_platform = { .pcm_free = mxs_pcm_free, }; -int __devinit mxs_pcm_platform_register(struct device *dev) +int mxs_pcm_platform_register(struct device *dev) { return snd_soc_register_platform(dev, &mxs_soc_platform); } EXPORT_SYMBOL_GPL(mxs_pcm_platform_register); -void __devexit mxs_pcm_platform_unregister(struct device *dev) +void mxs_pcm_platform_unregister(struct device *dev) { snd_soc_unregister_platform(dev); } diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index c294fbb523f..365d9d27a32 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) saif->mclk_in_use = 0; return 0; } +EXPORT_SYMBOL_GPL(mxs_saif_put_mclk); /* * 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, return 0; } +EXPORT_SYMBOL_GPL(mxs_saif_get_mclk); /* * SAIF DAI format configuration. @@ -655,7 +657,7 @@ static irqreturn_t mxs_saif_irq(int irq, void *dev_id) return IRQ_HANDLED; } -static int __devinit mxs_saif_probe(struct platform_device *pdev) +static int mxs_saif_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct resource *iores, *dmares; @@ -790,7 +792,7 @@ failed_pdev_alloc: return ret; } -static int __devexit mxs_saif_remove(struct platform_device *pdev) +static int mxs_saif_remove(struct platform_device *pdev) { mxs_pcm_platform_unregister(&pdev->dev); snd_soc_unregister_dai(&pdev->dev); @@ -806,7 +808,7 @@ MODULE_DEVICE_TABLE(of, mxs_saif_dt_ids); static struct platform_driver mxs_saif_driver = { .probe = mxs_saif_probe, - .remove = __devexit_p(mxs_saif_remove), + .remove = mxs_saif_remove, .driver = { .name = "mxs-saif", diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c index 215113b05f7..b1d9b5ebeee 100644 --- a/sound/soc/mxs/mxs-sgtl5000.c +++ b/sound/soc/mxs/mxs-sgtl5000.c @@ -112,7 +112,7 @@ static struct snd_soc_card mxs_sgtl5000 = { .num_links = ARRAY_SIZE(mxs_sgtl5000_dai), }; -static int __devinit mxs_sgtl5000_probe_dt(struct platform_device *pdev) +static int mxs_sgtl5000_probe_dt(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct device_node *saif_np[2], *codec_np; @@ -145,7 +145,7 @@ static int __devinit mxs_sgtl5000_probe_dt(struct platform_device *pdev) return ret; } -static int __devinit mxs_sgtl5000_probe(struct platform_device *pdev) +static int mxs_sgtl5000_probe(struct platform_device *pdev) { struct snd_soc_card *card = &mxs_sgtl5000; int ret; @@ -176,7 +176,7 @@ static int __devinit mxs_sgtl5000_probe(struct platform_device *pdev) return 0; } -static int __devexit mxs_sgtl5000_remove(struct platform_device *pdev) +static int mxs_sgtl5000_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -200,7 +200,7 @@ static struct platform_driver mxs_sgtl5000_audio_driver = { .of_match_table = mxs_sgtl5000_dt_ids, }, .probe = mxs_sgtl5000_probe, - .remove = __devexit_p(mxs_sgtl5000_remove), + .remove = mxs_sgtl5000_remove, }; module_platform_driver(mxs_sgtl5000_audio_driver); diff --git a/sound/soc/nuc900/nuc900-ac97.c b/sound/soc/nuc900/nuc900-ac97.c index 946020a647d..0418467a484 100644 --- a/sound/soc/nuc900/nuc900-ac97.c +++ b/sound/soc/nuc900/nuc900-ac97.c @@ -314,7 +314,7 @@ static struct snd_soc_dai_driver nuc900_ac97_dai = { .ops = &nuc900_ac97_dai_ops, }; -static int __devinit nuc900_ac97_drvprobe(struct platform_device *pdev) +static int nuc900_ac97_drvprobe(struct platform_device *pdev) { struct nuc900_audio *nuc900_audio; int ret; @@ -382,7 +382,7 @@ out0: return ret; } -static int __devexit nuc900_ac97_drvremove(struct platform_device *pdev) +static int nuc900_ac97_drvremove(struct platform_device *pdev) { snd_soc_unregister_dai(&pdev->dev); @@ -403,7 +403,7 @@ static struct platform_driver nuc900_ac97_driver = { .owner = THIS_MODULE, }, .probe = nuc900_ac97_drvprobe, - .remove = __devexit_p(nuc900_ac97_drvremove), + .remove = nuc900_ac97_drvremove, }; module_platform_driver(nuc900_ac97_driver); diff --git a/sound/soc/nuc900/nuc900-pcm.c b/sound/soc/nuc900/nuc900-pcm.c index 37585b47f4e..c894ff0f258 100644 --- a/sound/soc/nuc900/nuc900-pcm.c +++ b/sound/soc/nuc900/nuc900-pcm.c @@ -337,12 +337,12 @@ static struct snd_soc_platform_driver nuc900_soc_platform = { .pcm_free = nuc900_dma_free_dma_buffers, }; -static int __devinit nuc900_soc_platform_probe(struct platform_device *pdev) +static int nuc900_soc_platform_probe(struct platform_device *pdev) { return snd_soc_register_platform(&pdev->dev, &nuc900_soc_platform); } -static int __devexit nuc900_soc_platform_remove(struct platform_device *pdev) +static int nuc900_soc_platform_remove(struct platform_device *pdev) { snd_soc_unregister_platform(&pdev->dev); return 0; @@ -355,7 +355,7 @@ static struct platform_driver nuc900_pcm_driver = { }, .probe = nuc900_soc_platform_probe, - .remove = __devexit_p(nuc900_soc_platform_remove), + .remove = nuc900_soc_platform_remove, }; module_platform_driver(nuc900_pcm_driver); diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c index d8e96b2cd03..2600447fa74 100644 --- a/sound/soc/omap/ams-delta.c +++ b/sound/soc/omap/ams-delta.c @@ -575,7 +575,7 @@ static struct snd_soc_card ams_delta_audio_card = { }; /* Module init/exit */ -static __devinit int ams_delta_probe(struct platform_device *pdev) +static int ams_delta_probe(struct platform_device *pdev) { struct snd_soc_card *card = &ams_delta_audio_card; int ret; @@ -591,7 +591,7 @@ static __devinit int ams_delta_probe(struct platform_device *pdev) return 0; } -static int __devexit ams_delta_remove(struct platform_device *pdev) +static int ams_delta_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -616,7 +616,7 @@ static struct platform_driver ams_delta_driver = { .owner = THIS_MODULE, }, .probe = ams_delta_probe, - .remove = __devexit_p(ams_delta_remove), + .remove = ams_delta_remove, }; module_platform_driver(ams_delta_driver); diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c index afb8d4f1bed..285c8368cb4 100644 --- a/sound/soc/omap/mcbsp.c +++ b/sound/soc/omap/mcbsp.c @@ -28,8 +28,6 @@ #include <linux/platform_data/asoc-ti-mcbsp.h> -#include <plat/cpu.h> - #include "mcbsp.h" 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) * system will refuse to enter idle if the CLKS pin source is not reset * back to internal source. */ - if (!cpu_class_is_omap1()) + if (!mcbsp_omap1()) omap2_mcbsp_set_clks_src(mcbsp, MCBSP_CLKS_PRCM_SRC); spin_lock(&mcbsp->lock); @@ -932,8 +930,7 @@ static const struct attribute_group sidetone_attr_group = { .attrs = (struct attribute **)sidetone_attrs, }; -static int __devinit omap_st_add(struct omap_mcbsp *mcbsp, - struct resource *res) +static int omap_st_add(struct omap_mcbsp *mcbsp, struct resource *res) { struct omap_mcbsp_st_data *st_data; int err; @@ -959,7 +956,7 @@ static int __devinit omap_st_add(struct omap_mcbsp *mcbsp, * McBSP1 and McBSP3 are directly mapped on 1610 and 1510. * 730 has only 2 McBSP, and both of them are MPU peripherals. */ -int __devinit omap_mcbsp_init(struct platform_device *pdev) +int omap_mcbsp_init(struct platform_device *pdev) { struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev); struct resource *res; @@ -1087,7 +1084,7 @@ err_thres: return ret; } -void __devexit omap_mcbsp_sysfs_remove(struct omap_mcbsp *mcbsp) +void omap_mcbsp_sysfs_remove(struct omap_mcbsp *mcbsp) { if (mcbsp->pdata->buffer_size) sysfs_remove_group(&mcbsp->dev->kobj, &additional_attr_group); diff --git a/sound/soc/omap/mcbsp.h b/sound/soc/omap/mcbsp.h index 49a67259ce5..f93e0b0af30 100644 --- a/sound/soc/omap/mcbsp.h +++ b/sound/soc/omap/mcbsp.h @@ -26,6 +26,12 @@ #include "omap-pcm.h" +#ifdef CONFIG_ARCH_OMAP1 +#define mcbsp_omap1() 1 +#else +#define mcbsp_omap1() 0 +#endif + /* McBSP register numbers. Register address offset = num * reg_step */ enum { /* Common registers */ @@ -341,7 +347,7 @@ int omap_st_enable(struct omap_mcbsp *mcbsp); int omap_st_disable(struct omap_mcbsp *mcbsp); int omap_st_is_enabled(struct omap_mcbsp *mcbsp); -int __devinit omap_mcbsp_init(struct platform_device *pdev); -void __devexit omap_mcbsp_sysfs_remove(struct omap_mcbsp *mcbsp); +int omap_mcbsp_init(struct platform_device *pdev); +void omap_mcbsp_sysfs_remove(struct omap_mcbsp *mcbsp); #endif /* __ASOC_MCBSP_H */ diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c index a57a4e68dcc..e7d93fa412a 100644 --- a/sound/soc/omap/omap-abe-twl6040.c +++ b/sound/soc/omap/omap-abe-twl6040.c @@ -273,7 +273,7 @@ static struct snd_soc_card omap_abe_card = { .num_dapm_routes = ARRAY_SIZE(audio_map), }; -static __devinit int omap_abe_probe(struct platform_device *pdev) +static int omap_abe_probe(struct platform_device *pdev) { struct omap_abe_twl6040_data *pdata = dev_get_platdata(&pdev->dev); struct device_node *node = pdev->dev.of_node; @@ -331,8 +331,8 @@ static __devinit int omap_abe_probe(struct platform_device *pdev) num_links = 1; } - of_property_read_u32(node, "ti,jack-detection", - &priv->jack_detection); + priv->jack_detection = of_property_read_bool(node, + "ti,jack-detection"); of_property_read_u32(node, "ti,mclk-freq", &priv->mclk_freq); if (!priv->mclk_freq) { @@ -390,7 +390,7 @@ err_unregister: return ret; } -static int __devexit omap_abe_remove(struct platform_device *pdev) +static int omap_abe_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); struct abe_twl6040 *priv = snd_soc_card_get_drvdata(card); @@ -417,7 +417,7 @@ static struct platform_driver omap_abe_driver = { .of_match_table = omap_abe_of_match, }, .probe = omap_abe_probe, - .remove = __devexit_p(omap_abe_remove), + .remove = omap_abe_remove, }; module_platform_driver(omap_abe_driver); diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c index 5a6aeaf552a..ba49ccd9eed 100644 --- a/sound/soc/omap/omap-dmic.c +++ b/sound/soc/omap/omap-dmic.c @@ -448,7 +448,7 @@ static struct snd_soc_dai_driver omap_dmic_dai = { .ops = &omap_dmic_dai_ops, }; -static __devinit int asoc_dmic_probe(struct platform_device *pdev) +static int asoc_dmic_probe(struct platform_device *pdev) { struct omap_dmic *dmic; struct resource *res; @@ -518,7 +518,7 @@ err_put_clk: return ret; } -static int __devexit asoc_dmic_remove(struct platform_device *pdev) +static int asoc_dmic_remove(struct platform_device *pdev) { struct omap_dmic *dmic = platform_get_drvdata(pdev); @@ -541,7 +541,7 @@ static struct platform_driver asoc_dmic_driver = { .of_match_table = omap_dmic_of_match, }, .probe = asoc_dmic_probe, - .remove = __devexit_p(asoc_dmic_remove), + .remove = asoc_dmic_remove, }; module_platform_driver(asoc_dmic_driver); diff --git a/sound/soc/omap/omap-hdmi-card.c b/sound/soc/omap/omap-hdmi-card.c index eaa2ea0e3f8..d4eaa92e518 100644 --- a/sound/soc/omap/omap-hdmi-card.c +++ b/sound/soc/omap/omap-hdmi-card.c @@ -45,7 +45,7 @@ static struct snd_soc_card snd_soc_omap_hdmi = { .num_links = 1, }; -static __devinit int omap_hdmi_probe(struct platform_device *pdev) +static int omap_hdmi_probe(struct platform_device *pdev) { struct snd_soc_card *card = &snd_soc_omap_hdmi; int ret; @@ -61,7 +61,7 @@ static __devinit int omap_hdmi_probe(struct platform_device *pdev) return 0; } -static int __devexit omap_hdmi_remove(struct platform_device *pdev) +static int omap_hdmi_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -76,7 +76,7 @@ static struct platform_driver omap_hdmi_driver = { .owner = THIS_MODULE, }, .probe = omap_hdmi_probe, - .remove = __devexit_p(omap_hdmi_remove), + .remove = omap_hdmi_remove, }; module_platform_driver(omap_hdmi_driver); diff --git a/sound/soc/omap/omap-hdmi.c b/sound/soc/omap/omap-hdmi.c index f59c69fb400..7ea24819d57 100644 --- a/sound/soc/omap/omap-hdmi.c +++ b/sound/soc/omap/omap-hdmi.c @@ -262,7 +262,7 @@ static struct snd_soc_dai_driver omap_hdmi_dai = { .ops = &omap_hdmi_dai_ops, }; -static __devinit int omap_hdmi_probe(struct platform_device *pdev) +static int omap_hdmi_probe(struct platform_device *pdev) { int ret; struct resource *hdmi_rsrc; @@ -324,7 +324,7 @@ static __devinit int omap_hdmi_probe(struct platform_device *pdev) return ret; } -static int __devexit omap_hdmi_remove(struct platform_device *pdev) +static int omap_hdmi_remove(struct platform_device *pdev) { struct hdmi_priv *hdmi_data = dev_get_drvdata(&pdev->dev); @@ -345,7 +345,7 @@ static struct platform_driver hdmi_dai_driver = { .owner = THIS_MODULE, }, .probe = omap_hdmi_probe, - .remove = __devexit_p(omap_hdmi_remove), + .remove = omap_hdmi_remove, }; module_platform_driver(hdmi_dai_driver); diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index a6ee1574785..8d2defd6fdb 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -34,7 +34,6 @@ #include <sound/initval.h> #include <sound/soc.h> -#include <plat/cpu.h> #include <linux/platform_data/asoc-ti-mcbsp.h> #include "mcbsp.h" #include "omap-mcbsp.h" @@ -512,7 +511,7 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, regs->srgr2 |= CLKSM; break; case OMAP_MCBSP_SYSCLK_CLKS_FCLK: - if (cpu_class_is_omap1()) { + if (mcbsp_omap1()) { err = -EINVAL; break; } @@ -520,7 +519,7 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, MCBSP_CLKS_PRCM_SRC); break; case OMAP_MCBSP_SYSCLK_CLKS_EXT: - if (cpu_class_is_omap1()) { + if (mcbsp_omap1()) { err = 0; break; } @@ -758,7 +757,7 @@ static const struct of_device_id omap_mcbsp_of_match[] = { }; MODULE_DEVICE_TABLE(of, omap_mcbsp_of_match); -static __devinit int asoc_mcbsp_probe(struct platform_device *pdev) +static int asoc_mcbsp_probe(struct platform_device *pdev) { struct omap_mcbsp_platform_data *pdata = dev_get_platdata(&pdev->dev); struct omap_mcbsp *mcbsp; @@ -799,7 +798,7 @@ static __devinit int asoc_mcbsp_probe(struct platform_device *pdev) return ret; } -static int __devexit asoc_mcbsp_remove(struct platform_device *pdev) +static int asoc_mcbsp_remove(struct platform_device *pdev) { struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev); @@ -825,7 +824,7 @@ static struct platform_driver asoc_mcbsp_driver = { }, .probe = asoc_mcbsp_probe, - .remove = __devexit_p(asoc_mcbsp_remove), + .remove = asoc_mcbsp_remove, }; module_platform_driver(asoc_mcbsp_driver); diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index 56965bb3275..2fe8be20945 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -429,7 +429,7 @@ void omap_mcpdm_configure_dn_offsets(struct snd_soc_pcm_runtime *rtd, } EXPORT_SYMBOL_GPL(omap_mcpdm_configure_dn_offsets); -static __devinit int asoc_mcpdm_probe(struct platform_device *pdev) +static int asoc_mcpdm_probe(struct platform_device *pdev) { struct omap_mcpdm *mcpdm; struct resource *res; @@ -487,7 +487,7 @@ static __devinit int asoc_mcpdm_probe(struct platform_device *pdev) return snd_soc_register_dai(&pdev->dev, &omap_mcpdm_dai); } -static int __devexit asoc_mcpdm_remove(struct platform_device *pdev) +static int asoc_mcpdm_remove(struct platform_device *pdev) { snd_soc_unregister_dai(&pdev->dev); return 0; @@ -507,7 +507,7 @@ static struct platform_driver asoc_mcpdm_driver = { }, .probe = asoc_mcpdm_probe, - .remove = __devexit_p(asoc_mcpdm_remove), + .remove = asoc_mcpdm_remove, }; module_platform_driver(asoc_mcpdm_driver); diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index 340874ebf9a..5f7e5b9c87a 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -297,13 +297,13 @@ static struct snd_soc_platform_driver omap_soc_platform = { .pcm_free = omap_pcm_free_dma_buffers, }; -static __devinit int omap_pcm_probe(struct platform_device *pdev) +static int omap_pcm_probe(struct platform_device *pdev) { return snd_soc_register_platform(&pdev->dev, &omap_soc_platform); } -static int __devexit omap_pcm_remove(struct platform_device *pdev) +static int omap_pcm_remove(struct platform_device *pdev) { snd_soc_unregister_platform(&pdev->dev); return 0; @@ -316,7 +316,7 @@ static struct platform_driver omap_pcm_driver = { }, .probe = omap_pcm_probe, - .remove = __devexit_p(omap_pcm_remove), + .remove = omap_pcm_remove, }; module_platform_driver(omap_pcm_driver); diff --git a/sound/soc/omap/omap-twl4030.c b/sound/soc/omap/omap-twl4030.c index 3b97b87971f..4541d28b531 100644 --- a/sound/soc/omap/omap-twl4030.c +++ b/sound/soc/omap/omap-twl4030.c @@ -107,7 +107,7 @@ static struct snd_soc_card omap_twl4030_card = { .num_links = ARRAY_SIZE(omap_twl4030_dai_links), }; -static __devinit int omap_twl4030_probe(struct platform_device *pdev) +static int omap_twl4030_probe(struct platform_device *pdev) { struct omap_tw4030_pdata *pdata = dev_get_platdata(&pdev->dev); struct device_node *node = pdev->dev.of_node; @@ -154,7 +154,7 @@ static __devinit int omap_twl4030_probe(struct platform_device *pdev) return 0; } -static int __devexit omap_twl4030_remove(struct platform_device *pdev) +static int omap_twl4030_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -177,7 +177,7 @@ static struct platform_driver omap_twl4030_driver = { .of_match_table = omap_twl4030_of_match, }, .probe = omap_twl4030_probe, - .remove = __devexit_p(omap_twl4030_remove), + .remove = omap_twl4030_remove, }; module_platform_driver(omap_twl4030_driver); diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c index 1ff6bb9ade5..771bff27ac3 100644 --- a/sound/soc/omap/zoom2.c +++ b/sound/soc/omap/zoom2.c @@ -37,8 +37,6 @@ #include "omap-mcbsp.h" #include "omap-pcm.h" -#define ZOOM2_HEADSET_MUX_GPIO (OMAP_MAX_GPIO_LINES + 15) - static int zoom2_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -187,9 +185,6 @@ static int __init zoom2_soc_init(void) if (ret) goto err1; - BUG_ON(gpio_request(ZOOM2_HEADSET_MUX_GPIO, "hs_mux") < 0); - gpio_direction_output(ZOOM2_HEADSET_MUX_GPIO, 0); - return 0; err1: @@ -202,8 +197,6 @@ module_init(zoom2_soc_init); static void __exit zoom2_soc_exit(void) { - gpio_free(ZOOM2_HEADSET_MUX_GPIO); - platform_device_unregister(zoom2_snd_device); } module_exit(zoom2_soc_exit); diff --git a/sound/soc/pxa/brownstone.c b/sound/soc/pxa/brownstone.c index 5e666e03d33..4ad76099dd4 100644 --- a/sound/soc/pxa/brownstone.c +++ b/sound/soc/pxa/brownstone.c @@ -140,7 +140,7 @@ static struct snd_soc_card brownstone = { .num_dapm_routes = ARRAY_SIZE(brownstone_audio_map), }; -static int __devinit brownstone_probe(struct platform_device *pdev) +static int brownstone_probe(struct platform_device *pdev) { int ret; @@ -152,7 +152,7 @@ static int __devinit brownstone_probe(struct platform_device *pdev) return ret; } -static int __devexit brownstone_remove(struct platform_device *pdev) +static int brownstone_remove(struct platform_device *pdev) { snd_soc_unregister_card(&brownstone); return 0; @@ -164,7 +164,7 @@ static struct platform_driver mmp_driver = { .owner = THIS_MODULE, }, .probe = brownstone_probe, - .remove = __devexit_p(brownstone_remove), + .remove = brownstone_remove, }; module_platform_driver(mmp_driver); diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index 863367ad89c..f4cce1e8011 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c @@ -303,7 +303,7 @@ static struct snd_soc_card corgi = { .num_dapm_routes = ARRAY_SIZE(corgi_audio_map), }; -static int __devinit corgi_probe(struct platform_device *pdev) +static int corgi_probe(struct platform_device *pdev) { struct snd_soc_card *card = &corgi; int ret; @@ -317,7 +317,7 @@ static int __devinit corgi_probe(struct platform_device *pdev) return ret; } -static int __devexit corgi_remove(struct platform_device *pdev) +static int corgi_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -331,7 +331,7 @@ static struct platform_driver corgi_driver = { .owner = THIS_MODULE, }, .probe = corgi_probe, - .remove = __devexit_p(corgi_remove), + .remove = corgi_remove, }; module_platform_driver(corgi_driver); diff --git a/sound/soc/pxa/e740_wm9705.c b/sound/soc/pxa/e740_wm9705.c index 7b1bc239003..70d799b13f0 100644 --- a/sound/soc/pxa/e740_wm9705.c +++ b/sound/soc/pxa/e740_wm9705.c @@ -144,7 +144,7 @@ static struct gpio e740_audio_gpios[] = { { GPIO_E740_WM9705_nAVDD2, GPIOF_OUT_INIT_HIGH, "Audio power" }, }; -static int __devinit e740_probe(struct platform_device *pdev) +static int e740_probe(struct platform_device *pdev) { struct snd_soc_card *card = &e740; int ret; @@ -165,7 +165,7 @@ static int __devinit e740_probe(struct platform_device *pdev) return ret; } -static int __devexit e740_remove(struct platform_device *pdev) +static int e740_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -180,7 +180,7 @@ static struct platform_driver e740_driver = { .owner = THIS_MODULE, }, .probe = e740_probe, - .remove = __devexit_p(e740_remove), + .remove = e740_remove, }; module_platform_driver(e740_driver); diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c index 47b89d71e28..f94d2ab5135 100644 --- a/sound/soc/pxa/e750_wm9705.c +++ b/sound/soc/pxa/e750_wm9705.c @@ -126,7 +126,7 @@ static struct gpio e750_audio_gpios[] = { { GPIO_E750_SPK_AMP_OFF, GPIOF_OUT_INIT_HIGH, "Speaker amp" }, }; -static int __devinit e750_probe(struct platform_device *pdev) +static int e750_probe(struct platform_device *pdev) { struct snd_soc_card *card = &e750; int ret; @@ -147,7 +147,7 @@ static int __devinit e750_probe(struct platform_device *pdev) return ret; } -static int __devexit e750_remove(struct platform_device *pdev) +static int e750_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -162,7 +162,7 @@ static struct platform_driver e750_driver = { .owner = THIS_MODULE, }, .probe = e750_probe, - .remove = __devexit_p(e750_remove), + .remove = e750_remove, }; module_platform_driver(e750_driver); diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c index ea9707ec6f2..8768a640dd7 100644 --- a/sound/soc/pxa/e800_wm9712.c +++ b/sound/soc/pxa/e800_wm9712.c @@ -116,7 +116,7 @@ static struct gpio e800_audio_gpios[] = { { GPIO_E800_HP_AMP_OFF, GPIOF_OUT_INIT_HIGH, "Speaker amp" }, }; -static int __devinit e800_probe(struct platform_device *pdev) +static int e800_probe(struct platform_device *pdev) { struct snd_soc_card *card = &e800; int ret; @@ -137,7 +137,7 @@ static int __devinit e800_probe(struct platform_device *pdev) return ret; } -static int __devexit e800_remove(struct platform_device *pdev) +static int e800_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -152,7 +152,7 @@ static struct platform_driver e800_driver = { .owner = THIS_MODULE, }, .probe = e800_probe, - .remove = __devexit_p(e800_remove), + .remove = e800_remove, }; module_platform_driver(e800_driver); diff --git a/sound/soc/pxa/hx4700.c b/sound/soc/pxa/hx4700.c index 2a342c92d82..dcc9b04bd92 100644 --- a/sound/soc/pxa/hx4700.c +++ b/sound/soc/pxa/hx4700.c @@ -183,7 +183,7 @@ static struct gpio hx4700_audio_gpios[] = { { GPIO92_HX4700_HP_DRIVER, GPIOF_OUT_INIT_LOW, "EP_POWER" }, }; -static int __devinit hx4700_audio_probe(struct platform_device *pdev) +static int hx4700_audio_probe(struct platform_device *pdev) { int ret; @@ -204,7 +204,7 @@ static int __devinit hx4700_audio_probe(struct platform_device *pdev) return ret; } -static int __devexit hx4700_audio_remove(struct platform_device *pdev) +static int hx4700_audio_remove(struct platform_device *pdev) { snd_soc_jack_free_gpios(&hs_jack, 1, &hs_jack_gpio); snd_soc_unregister_card(&snd_soc_card_hx4700); @@ -223,7 +223,7 @@ static struct platform_driver hx4700_audio_driver = { .pm = &snd_soc_pm_ops, }, .probe = hx4700_audio_probe, - .remove = __devexit_p(hx4700_audio_remove), + .remove = hx4700_audio_remove, }; module_platform_driver(hx4700_audio_driver); diff --git a/sound/soc/pxa/imote2.c b/sound/soc/pxa/imote2.c index b93dafd32b8..eef1f7b7b38 100644 --- a/sound/soc/pxa/imote2.c +++ b/sound/soc/pxa/imote2.c @@ -65,7 +65,7 @@ static struct snd_soc_card imote2 = { .num_links = 1, }; -static int __devinit imote2_probe(struct platform_device *pdev) +static int imote2_probe(struct platform_device *pdev) { struct snd_soc_card *card = &imote2; int ret; @@ -79,7 +79,7 @@ static int __devinit imote2_probe(struct platform_device *pdev) return ret; } -static int __devexit imote2_remove(struct platform_device *pdev) +static int imote2_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -93,7 +93,7 @@ static struct platform_driver imote2_driver = { .owner = THIS_MODULE, }, .probe = imote2_probe, - .remove = __devexit_p(imote2_remove), + .remove = imote2_remove, }; module_platform_driver(imote2_driver); diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c index 8687c1c65d2..97b711e1282 100644 --- a/sound/soc/pxa/mioa701_wm9713.c +++ b/sound/soc/pxa/mioa701_wm9713.c @@ -186,7 +186,7 @@ static struct snd_soc_card mioa701 = { .num_links = ARRAY_SIZE(mioa701_dai), }; -static int __devinit mioa701_wm9713_probe(struct platform_device *pdev) +static int mioa701_wm9713_probe(struct platform_device *pdev) { int rc; @@ -202,7 +202,7 @@ static int __devinit mioa701_wm9713_probe(struct platform_device *pdev) return rc; } -static int __devexit mioa701_wm9713_remove(struct platform_device *pdev) +static int mioa701_wm9713_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -212,7 +212,7 @@ static int __devexit mioa701_wm9713_remove(struct platform_device *pdev) static struct platform_driver mioa701_wm9713_driver = { .probe = mioa701_wm9713_probe, - .remove = __devexit_p(mioa701_wm9713_remove), + .remove = mioa701_wm9713_remove, .driver = { .name = "mioa701-wm9713", .owner = THIS_MODULE, diff --git a/sound/soc/pxa/mmp-pcm.c b/sound/soc/pxa/mmp-pcm.c index e834faf859f..190eb0bccf5 100644 --- a/sound/soc/pxa/mmp-pcm.c +++ b/sound/soc/pxa/mmp-pcm.c @@ -257,7 +257,7 @@ struct snd_soc_platform_driver mmp_soc_platform = { .pcm_free = mmp_pcm_free_dma_buffers, }; -static __devinit int mmp_pcm_probe(struct platform_device *pdev) +static int mmp_pcm_probe(struct platform_device *pdev) { struct mmp_audio_platdata *pdata = pdev->dev.platform_data; @@ -274,7 +274,7 @@ static __devinit int mmp_pcm_probe(struct platform_device *pdev) return snd_soc_register_platform(&pdev->dev, &mmp_soc_platform); } -static int __devexit mmp_pcm_remove(struct platform_device *pdev) +static int mmp_pcm_remove(struct platform_device *pdev) { snd_soc_unregister_platform(&pdev->dev); return 0; @@ -287,7 +287,7 @@ static struct platform_driver mmp_pcm_driver = { }, .probe = mmp_pcm_probe, - .remove = __devexit_p(mmp_pcm_remove), + .remove = mmp_pcm_remove, }; module_platform_driver(mmp_pcm_driver); diff --git a/sound/soc/pxa/mmp-sspa.c b/sound/soc/pxa/mmp-sspa.c index 4d6cb8a30fc..41c3a09b53e 100644 --- a/sound/soc/pxa/mmp-sspa.c +++ b/sound/soc/pxa/mmp-sspa.c @@ -405,7 +405,7 @@ struct snd_soc_dai_driver mmp_sspa_dai = { .ops = &mmp_sspa_dai_ops, }; -static __devinit int asoc_mmp_sspa_probe(struct platform_device *pdev) +static int asoc_mmp_sspa_probe(struct platform_device *pdev) { struct sspa_priv *priv; struct resource *res; @@ -453,7 +453,7 @@ static __devinit int asoc_mmp_sspa_probe(struct platform_device *pdev) return snd_soc_register_dai(&pdev->dev, &mmp_sspa_dai); } -static int __devexit asoc_mmp_sspa_remove(struct platform_device *pdev) +static int asoc_mmp_sspa_remove(struct platform_device *pdev) { struct sspa_priv *priv = platform_get_drvdata(pdev); @@ -470,7 +470,7 @@ static struct platform_driver asoc_mmp_sspa_driver = { .owner = THIS_MODULE, }, .probe = asoc_mmp_sspa_probe, - .remove = __devexit_p(asoc_mmp_sspa_remove), + .remove = asoc_mmp_sspa_remove, }; module_platform_driver(asoc_mmp_sspa_driver); diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c index aa3da91907c..2074e2daf9c 100644 --- a/sound/soc/pxa/palm27x.c +++ b/sound/soc/pxa/palm27x.c @@ -187,7 +187,7 @@ put_device: return ret; } -static int __devexit palm27x_asoc_remove(struct platform_device *pdev) +static int palm27x_asoc_remove(struct platform_device *pdev) { platform_device_unregister(palm27x_snd_device); return 0; @@ -195,7 +195,7 @@ static int __devexit palm27x_asoc_remove(struct platform_device *pdev) static struct platform_driver palm27x_wm9712_driver = { .probe = palm27x_asoc_probe, - .remove = __devexit_p(palm27x_asoc_remove), + .remove = palm27x_asoc_remove, .driver = { .name = "palm27x-asoc", .owner = THIS_MODULE, diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c index d2cc8173503..fafe46355c3 100644 --- a/sound/soc/pxa/poodle.c +++ b/sound/soc/pxa/poodle.c @@ -269,7 +269,7 @@ static struct snd_soc_card poodle = { .num_dapm_routes = ARRAY_SIZE(poodle_audio_map), }; -static int __devinit poodle_probe(struct platform_device *pdev) +static int poodle_probe(struct platform_device *pdev) { struct snd_soc_card *card = &poodle; int ret; @@ -291,7 +291,7 @@ static int __devinit poodle_probe(struct platform_device *pdev) return ret; } -static int __devexit poodle_remove(struct platform_device *pdev) +static int poodle_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -305,7 +305,7 @@ static struct platform_driver poodle_driver = { .owner = THIS_MODULE, }, .probe = poodle_probe, - .remove = __devexit_p(poodle_remove), + .remove = poodle_remove, }; module_platform_driver(poodle_driver); diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index 4da5fc55c7e..d3eb0c2eec7 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c @@ -794,12 +794,12 @@ static struct snd_soc_dai_driver pxa_ssp_dai = { .ops = &pxa_ssp_dai_ops, }; -static __devinit int asoc_ssp_probe(struct platform_device *pdev) +static int asoc_ssp_probe(struct platform_device *pdev) { return snd_soc_register_dai(&pdev->dev, &pxa_ssp_dai); } -static int __devexit asoc_ssp_remove(struct platform_device *pdev) +static int asoc_ssp_remove(struct platform_device *pdev) { snd_soc_unregister_dai(&pdev->dev); return 0; @@ -812,7 +812,7 @@ static struct platform_driver asoc_ssp_driver = { }, .probe = asoc_ssp_probe, - .remove = __devexit_p(asoc_ssp_remove), + .remove = asoc_ssp_remove, }; module_platform_driver(asoc_ssp_driver); diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index 06ea2744cc8..4b0a009bd68 100644 --- a/sound/soc/pxa/pxa2xx-ac97.c +++ b/sound/soc/pxa/pxa2xx-ac97.c @@ -104,7 +104,7 @@ static int pxa2xx_ac97_resume(struct snd_soc_dai *dai) #define pxa2xx_ac97_resume NULL #endif -static int __devinit pxa2xx_ac97_probe(struct snd_soc_dai *dai) +static int pxa2xx_ac97_probe(struct snd_soc_dai *dai) { return pxa2xx_ac97_hw_probe(to_platform_device(dai->dev)); } @@ -234,7 +234,7 @@ static struct snd_soc_dai_driver pxa_ac97_dai_driver[] = { EXPORT_SYMBOL_GPL(soc_ac97_ops); -static __devinit int pxa2xx_ac97_dev_probe(struct platform_device *pdev) +static int pxa2xx_ac97_dev_probe(struct platform_device *pdev) { if (pdev->id != -1) { dev_err(&pdev->dev, "PXA2xx has only one AC97 port.\n"); @@ -249,7 +249,7 @@ static __devinit int pxa2xx_ac97_dev_probe(struct platform_device *pdev) ARRAY_SIZE(pxa_ac97_dai_driver)); } -static int __devexit pxa2xx_ac97_dev_remove(struct platform_device *pdev) +static int pxa2xx_ac97_dev_remove(struct platform_device *pdev) { snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(pxa_ac97_dai_driver)); return 0; @@ -257,7 +257,7 @@ static int __devexit pxa2xx_ac97_dev_remove(struct platform_device *pdev) static struct platform_driver pxa2xx_ac97_driver = { .probe = pxa2xx_ac97_dev_probe, - .remove = __devexit_p(pxa2xx_ac97_dev_remove), + .remove = pxa2xx_ac97_dev_remove, .driver = { .name = "pxa2xx-ac97", .owner = THIS_MODULE, diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c index 3075a426124..6b1a06f6756 100644 --- a/sound/soc/pxa/pxa2xx-i2s.c +++ b/sound/soc/pxa/pxa2xx-i2s.c @@ -365,7 +365,7 @@ static int pxa2xx_i2s_drv_probe(struct platform_device *pdev) return snd_soc_register_dai(&pdev->dev, &pxa_i2s_dai); } -static int __devexit pxa2xx_i2s_drv_remove(struct platform_device *pdev) +static int pxa2xx_i2s_drv_remove(struct platform_device *pdev) { snd_soc_unregister_dai(&pdev->dev); return 0; @@ -373,7 +373,7 @@ static int __devexit pxa2xx_i2s_drv_remove(struct platform_device *pdev) static struct platform_driver pxa2xx_i2s_driver = { .probe = pxa2xx_i2s_drv_probe, - .remove = __devexit_p(pxa2xx_i2s_drv_remove), + .remove = pxa2xx_i2s_drv_remove, .driver = { .name = "pxa2xx-i2s", diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c index fdd6bedef9b..ecff116cb7b 100644 --- a/sound/soc/pxa/pxa2xx-pcm.c +++ b/sound/soc/pxa/pxa2xx-pcm.c @@ -120,12 +120,12 @@ static struct snd_soc_platform_driver pxa2xx_soc_platform = { .pcm_free = pxa2xx_pcm_free_dma_buffers, }; -static int __devinit pxa2xx_soc_platform_probe(struct platform_device *pdev) +static int pxa2xx_soc_platform_probe(struct platform_device *pdev) { return snd_soc_register_platform(&pdev->dev, &pxa2xx_soc_platform); } -static int __devexit pxa2xx_soc_platform_remove(struct platform_device *pdev) +static int pxa2xx_soc_platform_remove(struct platform_device *pdev) { snd_soc_unregister_platform(&pdev->dev); return 0; @@ -138,7 +138,7 @@ static struct platform_driver pxa_pcm_driver = { }, .probe = pxa2xx_soc_platform_probe, - .remove = __devexit_p(pxa2xx_soc_platform_remove), + .remove = pxa2xx_soc_platform_remove, }; module_platform_driver(pxa_pcm_driver); diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c index 2aec63f3706..a3fe19123f0 100644 --- a/sound/soc/pxa/tosa.c +++ b/sound/soc/pxa/tosa.c @@ -241,7 +241,7 @@ static struct snd_soc_card tosa = { .num_links = ARRAY_SIZE(tosa_dai), }; -static int __devinit tosa_probe(struct platform_device *pdev) +static int tosa_probe(struct platform_device *pdev) { struct snd_soc_card *card = ⤩ int ret; @@ -262,7 +262,7 @@ static int __devinit tosa_probe(struct platform_device *pdev) return ret; } -static int __devexit tosa_remove(struct platform_device *pdev) +static int tosa_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -277,7 +277,7 @@ static struct platform_driver tosa_driver = { .owner = THIS_MODULE, }, .probe = tosa_probe, - .remove = __devexit_p(tosa_remove), + .remove = tosa_remove, }; module_platform_driver(tosa_driver); diff --git a/sound/soc/pxa/ttc-dkb.c b/sound/soc/pxa/ttc-dkb.c index 935491a8a77..f4ea4f6663a 100644 --- a/sound/soc/pxa/ttc-dkb.c +++ b/sound/soc/pxa/ttc-dkb.c @@ -131,7 +131,7 @@ static struct snd_soc_card ttc_dkb_card = { .num_dapm_routes = ARRAY_SIZE(ttc_audio_map), }; -static int __devinit ttc_dkb_probe(struct platform_device *pdev) +static int ttc_dkb_probe(struct platform_device *pdev) { struct snd_soc_card *card = &ttc_dkb_card; int ret; @@ -146,7 +146,7 @@ static int __devinit ttc_dkb_probe(struct platform_device *pdev) return ret; } -static int __devexit ttc_dkb_remove(struct platform_device *pdev) +static int ttc_dkb_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -161,7 +161,7 @@ static struct platform_driver ttc_dkb_driver = { .owner = THIS_MODULE, }, .probe = ttc_dkb_probe, - .remove = __devexit_p(ttc_dkb_remove), + .remove = ttc_dkb_remove, }; module_platform_driver(ttc_dkb_driver); diff --git a/sound/soc/s6000/s6000-i2s.c b/sound/soc/s6000/s6000-i2s.c index aaabdbaec19..fee4d477a49 100644 --- a/sound/soc/s6000/s6000-i2s.c +++ b/sound/soc/s6000/s6000-i2s.c @@ -436,7 +436,7 @@ static struct snd_soc_dai_driver s6000_i2s_dai = { .ops = &s6000_i2s_dai_ops, }; -static int __devinit s6000_i2s_probe(struct platform_device *pdev) +static int s6000_i2s_probe(struct platform_device *pdev) { struct s6000_i2s_dev *dev; struct resource *scbmem, *sifmem, *region, *dma1, *dma2; @@ -566,7 +566,7 @@ err_release_none: return ret; } -static void __devexit s6000_i2s_remove(struct platform_device *pdev) +static void s6000_i2s_remove(struct platform_device *pdev) { struct s6000_i2s_dev *dev = dev_get_drvdata(&pdev->dev); struct resource *region; @@ -597,7 +597,7 @@ static void __devexit s6000_i2s_remove(struct platform_device *pdev) static struct platform_driver s6000_i2s_driver = { .probe = s6000_i2s_probe, - .remove = __devexit_p(s6000_i2s_remove), + .remove = s6000_i2s_remove, .driver = { .name = "s6000-i2s", .owner = THIS_MODULE, diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c index 716da861c62..1358c7de252 100644 --- a/sound/soc/s6000/s6000-pcm.c +++ b/sound/soc/s6000/s6000-pcm.c @@ -500,12 +500,12 @@ static struct snd_soc_platform_driver s6000_soc_platform = { .pcm_free = s6000_pcm_free, }; -static int __devinit s6000_soc_platform_probe(struct platform_device *pdev) +static int s6000_soc_platform_probe(struct platform_device *pdev) { return snd_soc_register_platform(&pdev->dev, &s6000_soc_platform); } -static int __devexit s6000_soc_platform_remove(struct platform_device *pdev) +static int s6000_soc_platform_remove(struct platform_device *pdev) { snd_soc_unregister_platform(&pdev->dev); return 0; @@ -518,7 +518,7 @@ static struct platform_driver s6000_pcm_driver = { }, .probe = s6000_soc_platform_probe, - .remove = __devexit_p(s6000_soc_platform_remove), + .remove = s6000_soc_platform_remove, }; module_platform_driver(s6000_pcm_driver); diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c index 14fbcd30cae..0df3c5644cf 100644 --- a/sound/soc/samsung/ac97.c +++ b/sound/soc/samsung/ac97.c @@ -370,7 +370,7 @@ static struct snd_soc_dai_driver s3c_ac97_dai[] = { }, }; -static __devinit int s3c_ac97_probe(struct platform_device *pdev) +static int s3c_ac97_probe(struct platform_device *pdev) { struct resource *mem_res, *dmatx_res, *dmarx_res, *dmamic_res, *irq_res; struct s3c_audio_pdata *ac97_pdata; @@ -442,7 +442,7 @@ static __devinit int s3c_ac97_probe(struct platform_device *pdev) ret = -ENODEV; goto err2; } - clk_enable(s3c_ac97.ac97_clk); + clk_prepare_enable(s3c_ac97.ac97_clk); if (ac97_pdata->cfg_gpio(pdev)) { dev_err(&pdev->dev, "Unable to configure gpio\n"); @@ -462,13 +462,20 @@ static __devinit int s3c_ac97_probe(struct platform_device *pdev) if (ret) goto err5; - return 0; + ret = asoc_dma_platform_register(&pdev->dev); + if (ret) { + dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret); + goto err6; + } + return 0; +err6: + snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c_ac97_dai)); err5: free_irq(irq_res->start, NULL); err4: err3: - clk_disable(s3c_ac97.ac97_clk); + clk_disable_unprepare(s3c_ac97.ac97_clk); clk_put(s3c_ac97.ac97_clk); err2: iounmap(s3c_ac97.regs); @@ -478,17 +485,18 @@ err1: return ret; } -static __devexit int s3c_ac97_remove(struct platform_device *pdev) +static int s3c_ac97_remove(struct platform_device *pdev) { struct resource *mem_res, *irq_res; + asoc_dma_platform_unregister(&pdev->dev); snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c_ac97_dai)); irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (irq_res) free_irq(irq_res->start, NULL); - clk_disable(s3c_ac97.ac97_clk); + clk_disable_unprepare(s3c_ac97.ac97_clk); clk_put(s3c_ac97.ac97_clk); iounmap(s3c_ac97.regs); @@ -502,7 +510,7 @@ static __devexit int s3c_ac97_remove(struct platform_device *pdev) static struct platform_driver s3c_ac97_driver = { .probe = s3c_ac97_probe, - .remove = __devexit_p(s3c_ac97_remove), + .remove = s3c_ac97_remove, .driver = { .name = "samsung-ac97", .owner = THIS_MODULE, diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c index a2ca1567b9e..ceed466af9f 100644 --- a/sound/soc/samsung/bells.c +++ b/sound/soc/samsung/bells.c @@ -18,15 +18,6 @@ #include "../codecs/wm5102.h" #include "../codecs/wm9081.h" -/* - * 44.1kHz based clocks for the SYSCLK domain, use a very high clock - * to allow all the DSP functionality to be enabled if desired. - */ -#define SYSCLK_RATE (44100 * 1024) - -/* 48kHz based clocks for the ASYNC domain */ -#define ASYNCCLK_RATE (48000 * 512) - /* BCLK2 is fixed at this currently */ #define BCLK2_RATE (64 * 8000) @@ -36,15 +27,40 @@ */ #define MCLK_RATE 24576000 -#define WM9081_AUDIO_RATE 44100 -#define WM9081_MCLK_RATE (WM9081_AUDIO_RATE * 256) +#define SYS_AUDIO_RATE 44100 +#define SYS_MCLK_RATE (SYS_AUDIO_RATE * 512) + +#define DAI_AP_DSP 0 +#define DAI_DSP_CODEC 1 +#define DAI_CODEC_CP 2 +#define DAI_CODEC_SUB 3 + +struct bells_drvdata { + int sysclk_rate; + int asyncclk_rate; +}; + +static struct bells_drvdata wm2200_drvdata = { + .sysclk_rate = 22579200, +}; + +static struct bells_drvdata wm5102_drvdata = { + .sysclk_rate = 45158400, + .asyncclk_rate = 49152000, +}; + +static struct bells_drvdata wm5110_drvdata = { + .sysclk_rate = 135475200, + .asyncclk_rate = 147456000, +}; static int bells_set_bias_level(struct snd_soc_card *card, struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level) { - struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; + struct snd_soc_dai *codec_dai = card->rtd[DAI_DSP_CODEC].codec_dai; struct snd_soc_codec *codec = codec_dai->codec; + struct bells_drvdata *bells = card->drvdata; int ret; if (dapm->dev != codec_dai->dev) @@ -52,18 +68,21 @@ static int bells_set_bias_level(struct snd_soc_card *card, switch (level) { case SND_SOC_BIAS_PREPARE: - if (dapm->bias_level == SND_SOC_BIAS_STANDBY) { - ret = snd_soc_codec_set_pll(codec, WM5102_FLL1, - ARIZONA_FLL_SRC_MCLK1, - MCLK_RATE, - SYSCLK_RATE); - if (ret < 0) - pr_err("Failed to start FLL: %d\n", ret); + if (dapm->bias_level != SND_SOC_BIAS_STANDBY) + break; + ret = snd_soc_codec_set_pll(codec, WM5102_FLL1, + ARIZONA_FLL_SRC_MCLK1, + MCLK_RATE, + bells->sysclk_rate); + if (ret < 0) + pr_err("Failed to start FLL: %d\n", ret); + + if (bells->asyncclk_rate) { ret = snd_soc_codec_set_pll(codec, WM5102_FLL2, ARIZONA_FLL_SRC_AIF2BCLK, BCLK2_RATE, - ASYNCCLK_RATE); + bells->asyncclk_rate); if (ret < 0) pr_err("Failed to start FLL: %d\n", ret); } @@ -80,8 +99,9 @@ static int bells_set_bias_level_post(struct snd_soc_card *card, struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level) { - struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; + struct snd_soc_dai *codec_dai = card->rtd[DAI_DSP_CODEC].codec_dai; struct snd_soc_codec *codec = codec_dai->codec; + struct bells_drvdata *bells = card->drvdata; int ret; if (dapm->dev != codec_dai->dev) @@ -95,10 +115,13 @@ static int bells_set_bias_level_post(struct snd_soc_card *card, return ret; } - ret = snd_soc_codec_set_pll(codec, WM5102_FLL2, 0, 0, 0); - if (ret < 0) { - pr_err("Failed to stop FLL: %d\n", ret); - return ret; + if (bells->asyncclk_rate) { + ret = snd_soc_codec_set_pll(codec, WM5102_FLL2, + 0, 0, 0); + if (ret < 0) { + pr_err("Failed to stop FLL: %d\n", ret); + return ret; + } } break; @@ -113,56 +136,73 @@ static int bells_set_bias_level_post(struct snd_soc_card *card, static int bells_late_probe(struct snd_soc_card *card) { - struct snd_soc_codec *codec = card->rtd[0].codec; - struct snd_soc_dai *aif1_dai = card->rtd[0].codec_dai; - struct snd_soc_dai *aif2_dai = card->rtd[1].cpu_dai; - struct snd_soc_dai *aif3_dai = card->rtd[2].cpu_dai; - struct snd_soc_dai *wm9081_dai = card->rtd[2].codec_dai; + struct bells_drvdata *bells = card->drvdata; + struct snd_soc_codec *wm0010 = card->rtd[DAI_AP_DSP].codec; + struct snd_soc_codec *codec = card->rtd[DAI_DSP_CODEC].codec; + struct snd_soc_dai *aif1_dai = card->rtd[DAI_DSP_CODEC].codec_dai; + struct snd_soc_dai *aif2_dai; + struct snd_soc_dai *aif3_dai; + struct snd_soc_dai *wm9081_dai; int ret; - ret = snd_soc_dai_set_sysclk(aif1_dai, ARIZONA_CLK_SYSCLK, 0, 0); + ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK, + ARIZONA_CLK_SRC_FLL1, + bells->sysclk_rate, + SND_SOC_CLOCK_IN); if (ret != 0) { - dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret); + dev_err(codec->dev, "Failed to set SYSCLK: %d\n", ret); return ret; } - ret = snd_soc_dai_set_sysclk(aif2_dai, ARIZONA_CLK_ASYNCCLK, 0, 0); + ret = snd_soc_codec_set_sysclk(wm0010, 0, 0, SYS_MCLK_RATE, 0); if (ret != 0) { - dev_err(aif2_dai->dev, "Failed to set AIF2 clock: %d\n", ret); + dev_err(wm0010->dev, "Failed to set WM0010 clock: %d\n", ret); return ret; } - ret = snd_soc_dai_set_sysclk(aif3_dai, ARIZONA_CLK_SYSCLK, 0, 0); - if (ret != 0) { + ret = snd_soc_dai_set_sysclk(aif1_dai, ARIZONA_CLK_SYSCLK, 0, 0); + if (ret != 0) dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret); - return ret; - } - ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK, - ARIZONA_CLK_SRC_FLL1, SYSCLK_RATE, + ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_OPCLK, 0, + SYS_MCLK_RATE, SND_SOC_CLOCK_OUT); + if (ret != 0) + dev_err(codec->dev, "Failed to set OPCLK: %d\n", ret); + + if (card->num_rtd == DAI_CODEC_CP) + return 0; + + ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_ASYNCCLK, + ARIZONA_CLK_SRC_FLL2, + bells->asyncclk_rate, SND_SOC_CLOCK_IN); if (ret != 0) { - dev_err(codec->dev, "Failed to set SYSCLK: %d\n", ret); + dev_err(codec->dev, "Failed to set ASYNCCLK: %d\n", ret); return ret; } - ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_OPCLK, 0, - WM9081_MCLK_RATE, SND_SOC_CLOCK_OUT); + aif2_dai = card->rtd[DAI_CODEC_CP].cpu_dai; + + ret = snd_soc_dai_set_sysclk(aif2_dai, ARIZONA_CLK_ASYNCCLK, 0, 0); if (ret != 0) { - dev_err(codec->dev, "Failed to set OPCLK: %d\n", ret); + dev_err(aif2_dai->dev, "Failed to set AIF2 clock: %d\n", ret); return ret; } - ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_ASYNCCLK, - ARIZONA_CLK_SRC_FLL2, ASYNCCLK_RATE, - SND_SOC_CLOCK_IN); + if (card->num_rtd == DAI_CODEC_SUB) + return 0; + + aif3_dai = card->rtd[DAI_CODEC_SUB].cpu_dai; + wm9081_dai = card->rtd[DAI_CODEC_SUB].codec_dai; + + ret = snd_soc_dai_set_sysclk(aif3_dai, ARIZONA_CLK_SYSCLK, 0, 0); if (ret != 0) { - dev_err(codec->dev, "Failed to set SYSCLK: %d\n", ret); + dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret); return ret; } ret = snd_soc_codec_set_sysclk(wm9081_dai->codec, WM9081_SYSCLK_MCLK, - 0, WM9081_MCLK_RATE, 0); + 0, SYS_MCLK_RATE, 0); if (ret != 0) { dev_err(wm9081_dai->dev, "Failed to set MCLK: %d\n", ret); return ret; @@ -181,22 +221,57 @@ static const struct snd_soc_pcm_stream baseband_params = { static const struct snd_soc_pcm_stream sub_params = { .formats = SNDRV_PCM_FMTBIT_S32_LE, - .rate_min = WM9081_AUDIO_RATE, - .rate_max = WM9081_AUDIO_RATE, + .rate_min = SYS_AUDIO_RATE, + .rate_max = SYS_AUDIO_RATE, .channels_min = 2, .channels_max = 2, }; +static struct snd_soc_dai_link bells_dai_wm2200[] = { + { + .name = "CPU-DSP", + .stream_name = "CPU-DSP", + .cpu_dai_name = "samsung-i2s.0", + .codec_dai_name = "wm0010-sdi1", + .platform_name = "samsung-i2s.0", + .codec_name = "spi0.0", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF + | SND_SOC_DAIFMT_CBM_CFM, + }, + { + .name = "DSP-CODEC", + .stream_name = "DSP-CODEC", + .cpu_dai_name = "wm0010-sdi2", + .codec_dai_name = "wm2200", + .codec_name = "wm2200.1-003a", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF + | SND_SOC_DAIFMT_CBM_CFM, + .params = &sub_params, + .ignore_suspend = 1, + }, +}; + static struct snd_soc_dai_link bells_dai_wm5102[] = { { - .name = "CPU", - .stream_name = "CPU", + .name = "CPU-DSP", + .stream_name = "CPU-DSP", .cpu_dai_name = "samsung-i2s.0", + .codec_dai_name = "wm0010-sdi1", + .platform_name = "samsung-i2s.0", + .codec_name = "spi0.0", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF + | SND_SOC_DAIFMT_CBM_CFM, + }, + { + .name = "DSP-CODEC", + .stream_name = "DSP-CODEC", + .cpu_dai_name = "wm0010-sdi2", .codec_dai_name = "wm5102-aif1", - .platform_name = "samsung-audio", .codec_name = "wm5102-codec", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM, + .params = &sub_params, + .ignore_suspend = 1, }, { .name = "Baseband", @@ -224,14 +299,25 @@ static struct snd_soc_dai_link bells_dai_wm5102[] = { static struct snd_soc_dai_link bells_dai_wm5110[] = { { - .name = "CPU", - .stream_name = "CPU", + .name = "CPU-DSP", + .stream_name = "CPU-DSP", .cpu_dai_name = "samsung-i2s.0", + .codec_dai_name = "wm0010-sdi1", + .platform_name = "samsung-i2s.0", + .codec_name = "spi0.0", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF + | SND_SOC_DAIFMT_CBM_CFM, + }, + { + .name = "DSP-CODEC", + .stream_name = "DSP-CODEC", + .cpu_dai_name = "wm0010-sdi2", .codec_dai_name = "wm5110-aif1", - .platform_name = "samsung-audio", .codec_name = "wm5110-codec", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM, + .params = &sub_params, + .ignore_suspend = 1, }, { .name = "Baseband", @@ -270,6 +356,24 @@ static struct snd_soc_dapm_route bells_routes[] = { static struct snd_soc_card bells_cards[] = { { + .name = "Bells WM2200", + .owner = THIS_MODULE, + .dai_link = bells_dai_wm2200, + .num_links = ARRAY_SIZE(bells_dai_wm2200), + .codec_conf = bells_codec_conf, + .num_configs = ARRAY_SIZE(bells_codec_conf), + + .late_probe = bells_late_probe, + + .dapm_routes = bells_routes, + .num_dapm_routes = ARRAY_SIZE(bells_routes), + + .set_bias_level = bells_set_bias_level, + .set_bias_level_post = bells_set_bias_level_post, + + .drvdata = &wm2200_drvdata, + }, + { .name = "Bells WM5102", .owner = THIS_MODULE, .dai_link = bells_dai_wm5102, @@ -284,6 +388,8 @@ static struct snd_soc_card bells_cards[] = { .set_bias_level = bells_set_bias_level, .set_bias_level_post = bells_set_bias_level_post, + + .drvdata = &wm5102_drvdata, }, { .name = "Bells WM5110", @@ -300,11 +406,13 @@ static struct snd_soc_card bells_cards[] = { .set_bias_level = bells_set_bias_level, .set_bias_level_post = bells_set_bias_level_post, + + .drvdata = &wm5110_drvdata, }, }; -static __devinit int bells_probe(struct platform_device *pdev) +static int bells_probe(struct platform_device *pdev) { int ret; @@ -321,7 +429,7 @@ static __devinit int bells_probe(struct platform_device *pdev) return 0; } -static int __devexit bells_remove(struct platform_device *pdev) +static int bells_remove(struct platform_device *pdev) { snd_soc_unregister_card(&bells_cards[pdev->id]); @@ -335,7 +443,7 @@ static struct platform_driver bells_driver = { .pm = &snd_soc_pm_ops, }, .probe = bells_probe, - .remove = __devexit_p(bells_remove), + .remove = bells_remove, }; module_platform_driver(bells_driver); diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c index b70964ea448..db87628d763 100644 --- a/sound/soc/samsung/dma.c +++ b/sound/soc/samsung/dma.c @@ -432,30 +432,18 @@ static struct snd_soc_platform_driver samsung_asoc_platform = { .pcm_free = dma_free_dma_buffers, }; -static int __devinit samsung_asoc_platform_probe(struct platform_device *pdev) +int asoc_dma_platform_register(struct device *dev) { - return snd_soc_register_platform(&pdev->dev, &samsung_asoc_platform); + return snd_soc_register_platform(dev, &samsung_asoc_platform); } +EXPORT_SYMBOL_GPL(asoc_dma_platform_register); -static int __devexit samsung_asoc_platform_remove(struct platform_device *pdev) +void asoc_dma_platform_unregister(struct device *dev) { - snd_soc_unregister_platform(&pdev->dev); - return 0; + snd_soc_unregister_platform(dev); } - -static struct platform_driver asoc_dma_driver = { - .driver = { - .name = "samsung-audio", - .owner = THIS_MODULE, - }, - - .probe = samsung_asoc_platform_probe, - .remove = __devexit_p(samsung_asoc_platform_remove), -}; - -module_platform_driver(asoc_dma_driver); +EXPORT_SYMBOL_GPL(asoc_dma_platform_unregister); MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); MODULE_DESCRIPTION("Samsung ASoC DMA Driver"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:samsung-audio"); diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h index 7d1ead77ef2..73d8c7c8a1e 100644 --- a/sound/soc/samsung/dma.h +++ b/sound/soc/samsung/dma.h @@ -21,4 +21,7 @@ struct s3c_dma_params { struct samsung_dma_ops *ops; }; +int asoc_dma_platform_register(struct device *dev); +void asoc_dma_platform_unregister(struct device *dev); + #endif diff --git a/sound/soc/samsung/goni_wm8994.c b/sound/soc/samsung/goni_wm8994.c index c23c2ae91f5..d37ede58e0a 100644 --- a/sound/soc/samsung/goni_wm8994.c +++ b/sound/soc/samsung/goni_wm8994.c @@ -228,7 +228,7 @@ static struct snd_soc_dai_link goni_dai[] = { .stream_name = "WM8994 HiFi", .cpu_dai_name = "samsung-i2s.0", .codec_dai_name = "wm8994-aif1", - .platform_name = "samsung-audio", + .platform_name = "samsung-i2s.0", .codec_name = "wm8994-codec.0-001a", .init = goni_wm8994_init, .ops = &goni_hifi_ops, diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c index 6e3257717c5..3870e9678b5 100644 --- a/sound/soc/samsung/h1940_uda1380.c +++ b/sound/soc/samsung/h1940_uda1380.c @@ -207,7 +207,7 @@ static struct snd_soc_dai_link h1940_uda1380_dai[] = { .cpu_dai_name = "s3c24xx-iis", .codec_dai_name = "uda1380-hifi", .init = h1940_uda1380_init, - .platform_name = "samsung-audio", + .platform_name = "s3c24xx-iis", .codec_name = "uda1380-codec.0-001a", .ops = &h1940_ops, }, diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 40b00a13dcd..d2d124f1dd1 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -49,8 +49,6 @@ struct i2s_dai { struct clk *clk; /* Clock for generating I2S signals */ struct clk *op_clk; - /* Array of clock names for op_clk */ - const char **src_clk; /* Pointer to the Primary_Fifo if this is Sec_Fifo, NULL otherwise */ struct i2s_dai *pri_dai; /* 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, if (i2s->op_clk) { if ((clk_id && !(mod & MOD_IMS_SYSMUX)) || (!clk_id && (mod & MOD_IMS_SYSMUX))) { - clk_disable(i2s->op_clk); + clk_disable_unprepare(i2s->op_clk); clk_put(i2s->op_clk); } else { i2s->rclk_srcrate = @@ -432,9 +430,13 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, } } - i2s->op_clk = clk_get(&i2s->pdev->dev, - i2s->src_clk[clk_id]); - clk_enable(i2s->op_clk); + if (clk_id) + i2s->op_clk = clk_get(&i2s->pdev->dev, + "i2s_opclk1"); + else + i2s->op_clk = clk_get(&i2s->pdev->dev, + "i2s_opclk0"); + clk_prepare_enable(i2s->op_clk); i2s->rclk_srcrate = clk_get_rate(i2s->op_clk); /* Over-ride the other's */ @@ -880,7 +882,7 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) iounmap(i2s->addr); return -ENOENT; } - clk_enable(i2s->clk); + clk_prepare_enable(i2s->clk); if (other) { other->addr = i2s->addr; @@ -922,7 +924,7 @@ static int samsung_i2s_dai_remove(struct snd_soc_dai *dai) if (i2s->quirks & QUIRK_NEED_RSTCLR) writel(0, i2s->addr + I2SCON); - clk_disable(i2s->clk); + clk_disable_unprepare(i2s->clk); clk_put(i2s->clk); iounmap(i2s->addr); @@ -950,8 +952,7 @@ static const struct snd_soc_dai_ops samsung_i2s_dai_ops = { SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S24_LE) -static __devinit -struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec) +static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec) { struct i2s_dai *i2s; @@ -992,7 +993,7 @@ struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec) return i2s; } -static __devinit int samsung_i2s_probe(struct platform_device *pdev) +static int samsung_i2s_probe(struct platform_device *pdev) { u32 dma_pl_chan, dma_cp_chan, dma_pl_sec_chan; struct i2s_dai *pri_dai, *sec_dai = NULL; @@ -1007,6 +1008,7 @@ static __devinit int samsung_i2s_probe(struct platform_device *pdev) sec_dai = dev_get_drvdata(&pdev->dev); snd_soc_register_dai(&sec_dai->pdev->dev, &sec_dai->i2s_dai_drv); + asoc_dma_platform_register(&pdev->dev); return 0; } @@ -1067,7 +1069,6 @@ static __devinit int samsung_i2s_probe(struct platform_device *pdev) (struct s3c2410_dma_client *)&pri_dai->dma_capture; pri_dai->dma_playback.channel = dma_pl_chan; pri_dai->dma_capture.channel = dma_cp_chan; - pri_dai->src_clk = i2s_cfg->src_clk; pri_dai->dma_playback.dma_size = 4; pri_dai->dma_capture.dma_size = 4; pri_dai->base = regs_base; @@ -1088,7 +1089,6 @@ static __devinit int samsung_i2s_probe(struct platform_device *pdev) (struct s3c2410_dma_client *)&sec_dai->dma_playback; /* Use iDMA always if SysDMA not provided */ sec_dai->dma_playback.channel = dma_pl_sec_chan ? : -1; - sec_dai->src_clk = i2s_cfg->src_clk; sec_dai->dma_playback.dma_size = 4; sec_dai->base = regs_base; sec_dai->quirks = quirks; @@ -1107,6 +1107,8 @@ static __devinit int samsung_i2s_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); + asoc_dma_platform_register(&pdev->dev); + return 0; err: release_mem_region(regs_base, resource_size(res)); @@ -1114,7 +1116,7 @@ err: return ret; } -static __devexit int samsung_i2s_remove(struct platform_device *pdev) +static int samsung_i2s_remove(struct platform_device *pdev) { struct i2s_dai *i2s, *other; struct resource *res; @@ -1135,6 +1137,7 @@ static __devexit int samsung_i2s_remove(struct platform_device *pdev) i2s->pri_dai = NULL; i2s->sec_dai = NULL; + asoc_dma_platform_unregister(&pdev->dev); snd_soc_unregister_dai(&pdev->dev); return 0; @@ -1142,7 +1145,7 @@ static __devexit int samsung_i2s_remove(struct platform_device *pdev) static struct platform_driver samsung_i2s_driver = { .probe = samsung_i2s_probe, - .remove = __devexit_p(samsung_i2s_remove), + .remove = samsung_i2s_remove, .driver = { .name = "samsung-i2s", .owner = THIS_MODULE, diff --git a/sound/soc/samsung/idma.c b/sound/soc/samsung/idma.c index c227c3163ca..a07950b0c8c 100644 --- a/sound/soc/samsung/idma.c +++ b/sound/soc/samsung/idma.c @@ -416,12 +416,12 @@ static struct snd_soc_platform_driver asoc_idma_platform = { .pcm_free = idma_free, }; -static int __devinit asoc_idma_platform_probe(struct platform_device *pdev) +static int asoc_idma_platform_probe(struct platform_device *pdev) { return snd_soc_register_platform(&pdev->dev, &asoc_idma_platform); } -static int __devexit asoc_idma_platform_remove(struct platform_device *pdev) +static int asoc_idma_platform_remove(struct platform_device *pdev) { snd_soc_unregister_platform(&pdev->dev); return 0; @@ -434,7 +434,7 @@ static struct platform_driver asoc_idma_driver = { }, .probe = asoc_idma_platform_probe, - .remove = __devexit_p(asoc_idma_platform_remove), + .remove = asoc_idma_platform_remove, }; module_platform_driver(asoc_idma_driver); diff --git a/sound/soc/samsung/jive_wm8750.c b/sound/soc/samsung/jive_wm8750.c index 1578663a1fa..b5f6abd9d22 100644 --- a/sound/soc/samsung/jive_wm8750.c +++ b/sound/soc/samsung/jive_wm8750.c @@ -118,7 +118,7 @@ static struct snd_soc_dai_link jive_dai = { .stream_name = "WM8750", .cpu_dai_name = "s3c2412-i2s", .codec_dai_name = "wm8750-hifi", - .platform_name = "samsung-audio", + .platform_name = "s3c2412-i2s", .codec_name = "wm8750.0-001a", .init = jive_wm8750_init, .ops = &jive_ops, diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c index ee52c8a0077..bfb91f34a22 100644 --- a/sound/soc/samsung/littlemill.c +++ b/sound/soc/samsung/littlemill.c @@ -145,7 +145,7 @@ static struct snd_soc_dai_link littlemill_dai[] = { .stream_name = "CPU", .cpu_dai_name = "samsung-i2s.0", .codec_dai_name = "wm8994-aif1", - .platform_name = "samsung-audio", + .platform_name = "samsung-i2s.0", .codec_name = "wm8994-codec", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM, @@ -270,7 +270,7 @@ static int littlemill_late_probe(struct snd_soc_card *card) return ret; /* This will check device compatibility itself */ - wm8958_mic_detect(codec, &littlemill_headset, NULL, NULL); + wm8958_mic_detect(codec, &littlemill_headset, NULL, NULL, NULL, NULL); /* As will this */ wm8994_mic_detect(codec, &littlemill_headset, 1); @@ -297,7 +297,7 @@ static struct snd_soc_card littlemill = { .late_probe = littlemill_late_probe, }; -static __devinit int littlemill_probe(struct platform_device *pdev) +static int littlemill_probe(struct platform_device *pdev) { struct snd_soc_card *card = &littlemill; int ret; @@ -314,7 +314,7 @@ static __devinit int littlemill_probe(struct platform_device *pdev) return 0; } -static int __devexit littlemill_remove(struct platform_device *pdev) +static int littlemill_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -330,7 +330,7 @@ static struct platform_driver littlemill_driver = { .pm = &snd_soc_pm_ops, }, .probe = littlemill_probe, - .remove = __devexit_p(littlemill_remove), + .remove = littlemill_remove, }; module_platform_driver(littlemill_driver); diff --git a/sound/soc/samsung/ln2440sbc_alc650.c b/sound/soc/samsung/ln2440sbc_alc650.c index 69c4a5934a4..9342fc270c2 100644 --- a/sound/soc/samsung/ln2440sbc_alc650.c +++ b/sound/soc/samsung/ln2440sbc_alc650.c @@ -28,7 +28,7 @@ static struct snd_soc_dai_link ln2440sbc_dai[] = { .cpu_dai_name = "samsung-ac97", .codec_dai_name = "ac97-hifi", .codec_name = "ac97-codec", - .platform_name = "samsung-audio", + .platform_name = "samsung-ac97", }, }; diff --git a/sound/soc/samsung/lowland.c b/sound/soc/samsung/lowland.c index 6abf341c4a2..570cf522950 100644 --- a/sound/soc/samsung/lowland.c +++ b/sound/soc/samsung/lowland.c @@ -99,7 +99,7 @@ static struct snd_soc_dai_link lowland_dai[] = { .stream_name = "CPU", .cpu_dai_name = "samsung-i2s.0", .codec_dai_name = "wm5100-aif1", - .platform_name = "samsung-audio", + .platform_name = "samsung-i2s.0", .codec_name = "wm5100.1-001a", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM, @@ -180,7 +180,7 @@ static struct snd_soc_card lowland = { .num_dapm_routes = ARRAY_SIZE(audio_paths), }; -static __devinit int lowland_probe(struct platform_device *pdev) +static int lowland_probe(struct platform_device *pdev) { struct snd_soc_card *card = &lowland; int ret; @@ -197,7 +197,7 @@ static __devinit int lowland_probe(struct platform_device *pdev) return 0; } -static int __devexit lowland_remove(struct platform_device *pdev) +static int lowland_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -213,7 +213,7 @@ static struct platform_driver lowland_driver = { .pm = &snd_soc_pm_ops, }, .probe = lowland_probe, - .remove = __devexit_p(lowland_remove), + .remove = lowland_remove, }; module_platform_driver(lowland_driver); diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c index 321d51134e4..c7e965f80d2 100644 --- a/sound/soc/samsung/neo1973_wm8753.c +++ b/sound/soc/samsung/neo1973_wm8753.c @@ -364,7 +364,7 @@ static struct snd_soc_dai_link neo1973_dai[] = { { /* Hifi Playback - for similatious use with voice below */ .name = "WM8753", .stream_name = "WM8753 HiFi", - .platform_name = "samsung-audio", + .platform_name = "s3c24xx-iis", .cpu_dai_name = "s3c24xx-iis", .codec_dai_name = "wm8753-hifi", .codec_name = "wm8753.0-001a", diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index c86081992df..13bab79ad93 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c @@ -490,7 +490,7 @@ static struct snd_soc_dai_driver s3c_pcm_dai[] = { }, }; -static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev) +static int s3c_pcm_dev_probe(struct platform_device *pdev) { struct s3c_pcm_info *pcm; struct resource *mem_res, *dmatx_res, *dmarx_res; @@ -543,7 +543,7 @@ static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev) ret = PTR_ERR(pcm->cclk); goto err1; } - clk_enable(pcm->cclk); + clk_prepare_enable(pcm->cclk); /* record our pcm structure for later use in the callbacks */ dev_set_drvdata(&pdev->dev, pcm); @@ -568,7 +568,7 @@ static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev) ret = -ENOENT; goto err4; } - clk_enable(pcm->pclk); + clk_prepare_enable(pcm->pclk); s3c_pcm_stereo_in[pdev->id].dma_addr = mem_res->start + S3C_PCM_RXFIFO; @@ -589,27 +589,36 @@ static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev) goto err5; } + ret = asoc_dma_platform_register(&pdev->dev); + if (ret) { + dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret); + goto err6; + } + return 0; +err6: + snd_soc_unregister_dai(&pdev->dev); err5: - clk_disable(pcm->pclk); + clk_disable_unprepare(pcm->pclk); clk_put(pcm->pclk); err4: iounmap(pcm->regs); err3: release_mem_region(mem_res->start, resource_size(mem_res)); err2: - clk_disable(pcm->cclk); + clk_disable_unprepare(pcm->cclk); clk_put(pcm->cclk); err1: return ret; } -static __devexit int s3c_pcm_dev_remove(struct platform_device *pdev) +static int s3c_pcm_dev_remove(struct platform_device *pdev) { struct s3c_pcm_info *pcm = &s3c_pcm[pdev->id]; struct resource *mem_res; + asoc_dma_platform_unregister(&pdev->dev); snd_soc_unregister_dai(&pdev->dev); pm_runtime_disable(&pdev->dev); @@ -619,8 +628,8 @@ static __devexit int s3c_pcm_dev_remove(struct platform_device *pdev) mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(mem_res->start, resource_size(mem_res)); - clk_disable(pcm->cclk); - clk_disable(pcm->pclk); + clk_disable_unprepare(pcm->cclk); + clk_disable_unprepare(pcm->pclk); clk_put(pcm->pclk); clk_put(pcm->cclk); @@ -629,7 +638,7 @@ static __devexit int s3c_pcm_dev_remove(struct platform_device *pdev) static struct platform_driver s3c_pcm_driver = { .probe = s3c_pcm_dev_probe, - .remove = __devexit_p(s3c_pcm_dev_remove), + .remove = s3c_pcm_dev_remove, .driver = { .name = "samsung-pcm", .owner = THIS_MODULE, diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c index 21e12361a9c..a5826ea9cad 100644 --- a/sound/soc/samsung/rx1950_uda1380.c +++ b/sound/soc/samsung/rx1950_uda1380.c @@ -85,7 +85,7 @@ static struct snd_soc_dai_link rx1950_uda1380_dai[] = { .cpu_dai_name = "s3c24xx-iis", .codec_dai_name = "uda1380-hifi", .init = rx1950_uda1380_init, - .platform_name = "samsung-audio", + .platform_name = "s3c24xx-iis", .codec_name = "uda1380-codec.0-001a", .ops = &rx1950_ops, }, diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c index ac7701b3c5d..22133771639 100644 --- a/sound/soc/samsung/s3c2412-i2s.c +++ b/sound/soc/samsung/s3c2412-i2s.c @@ -160,20 +160,38 @@ static struct snd_soc_dai_driver s3c2412_i2s_dai = { .ops = &s3c2412_i2s_dai_ops, }; -static __devinit int s3c2412_iis_dev_probe(struct platform_device *pdev) +static int s3c2412_iis_dev_probe(struct platform_device *pdev) { - return s3c_i2sv2_register_dai(&pdev->dev, -1, &s3c2412_i2s_dai); + int ret = 0; + + ret = s3c_i2sv2_register_dai(&pdev->dev, -1, &s3c2412_i2s_dai); + if (ret) { + pr_err("failed to register the dai\n"); + return ret; + } + + ret = asoc_dma_platform_register(&pdev->dev); + if (ret) { + pr_err("failed to register the DMA: %d\n", ret); + goto err; + } + + return 0; +err: + snd_soc_unregister_dai(&pdev->dev); + return ret; } -static __devexit int s3c2412_iis_dev_remove(struct platform_device *pdev) +static int s3c2412_iis_dev_remove(struct platform_device *pdev) { + asoc_dma_platform_unregister(&pdev->dev); snd_soc_unregister_dai(&pdev->dev); return 0; } static struct platform_driver s3c2412_iis_driver = { .probe = s3c2412_iis_dev_probe, - .remove = __devexit_p(s3c2412_iis_dev_remove), + .remove = s3c2412_iis_dev_remove, .driver = { .name = "s3c2412-iis", .owner = THIS_MODULE, diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c index 0aae3a3883d..ee10e8704e9 100644 --- a/sound/soc/samsung/s3c24xx-i2s.c +++ b/sound/soc/samsung/s3c24xx-i2s.c @@ -465,20 +465,38 @@ static struct snd_soc_dai_driver s3c24xx_i2s_dai = { .ops = &s3c24xx_i2s_dai_ops, }; -static __devinit int s3c24xx_iis_dev_probe(struct platform_device *pdev) +static int s3c24xx_iis_dev_probe(struct platform_device *pdev) { - return snd_soc_register_dai(&pdev->dev, &s3c24xx_i2s_dai); + int ret = 0; + + ret = s3c_i2sv2_register_dai(&pdev->dev, -1, &s3c2412_i2s_dai); + if (ret) { + pr_err("failed to register the dai\n"); + return ret; + } + + ret = asoc_dma_platform_register(&pdev->dev); + if (ret) { + pr_err("failed to register the dma: %d\n", ret); + goto err; + } + + return 0; +err: + snd_soc_unregister_dai(&pdev->dev); + return ret; } -static __devexit int s3c24xx_iis_dev_remove(struct platform_device *pdev) +static int s3c24xx_iis_dev_remove(struct platform_device *pdev) { + asoc_dma_platform_unregister(&pdev->dev); snd_soc_unregister_dai(&pdev->dev); return 0; } static struct platform_driver s3c24xx_iis_driver = { .probe = s3c24xx_iis_dev_probe, - .remove = __devexit_p(s3c24xx_iis_dev_remove), + .remove = s3c24xx_iis_dev_remove, .driver = { .name = "s3c24xx-iis", .owner = THIS_MODULE, diff --git a/sound/soc/samsung/s3c24xx_simtec.c b/sound/soc/samsung/s3c24xx_simtec.c index 335a7d8a4a8..2c015f62ead 100644 --- a/sound/soc/samsung/s3c24xx_simtec.c +++ b/sound/soc/samsung/s3c24xx_simtec.c @@ -313,8 +313,8 @@ const struct dev_pm_ops simtec_audio_pmops = { EXPORT_SYMBOL_GPL(simtec_audio_pmops); #endif -int __devinit simtec_audio_core_probe(struct platform_device *pdev, - struct snd_soc_card *card) +int simtec_audio_core_probe(struct platform_device *pdev, + struct snd_soc_card *card) { struct platform_device *snd_dev; int ret; @@ -371,7 +371,7 @@ err_clk: } EXPORT_SYMBOL_GPL(simtec_audio_core_probe); -int __devexit simtec_audio_remove(struct platform_device *pdev) +int simtec_audio_remove(struct platform_device *pdev) { struct platform_device *snd_dev = platform_get_drvdata(pdev); diff --git a/sound/soc/samsung/s3c24xx_simtec_hermes.c b/sound/soc/samsung/s3c24xx_simtec_hermes.c index 7ace6a87f41..d8a0543cae5 100644 --- a/sound/soc/samsung/s3c24xx_simtec_hermes.c +++ b/sound/soc/samsung/s3c24xx_simtec_hermes.c @@ -82,7 +82,7 @@ static struct snd_soc_dai_link simtec_dai_aic33 = { .codec_name = "tlv320aic3x-codec.0-001a", .cpu_dai_name = "s3c24xx-iis", .codec_dai_name = "tlv320aic3x-hifi", - .platform_name = "samsung-audio", + .platform_name = "s3c24xx-iis", .init = simtec_hermes_init, }; @@ -99,7 +99,7 @@ static struct snd_soc_card snd_soc_machine_simtec_aic33 = { .num_dapm_routes = ARRAY_SIZE(base_map), }; -static int __devinit simtec_audio_hermes_probe(struct platform_device *pd) +static int simtec_audio_hermes_probe(struct platform_device *pd) { dev_info(&pd->dev, "probing....\n"); return simtec_audio_core_probe(pd, &snd_soc_machine_simtec_aic33); @@ -112,7 +112,7 @@ static struct platform_driver simtec_audio_hermes_platdrv = { .pm = simtec_audio_pm, }, .probe = simtec_audio_hermes_probe, - .remove = __devexit_p(simtec_audio_remove), + .remove = simtec_audio_remove, }; module_platform_driver(simtec_audio_hermes_platdrv); diff --git a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c index c42d5f00b0e..1ac0d7a63a3 100644 --- a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c +++ b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c @@ -71,7 +71,7 @@ static struct snd_soc_dai_link simtec_dai_aic23 = { .codec_name = "tlv320aic3x-codec.0-001a", .cpu_dai_name = "s3c24xx-iis", .codec_dai_name = "tlv320aic3x-hifi", - .platform_name = "samsung-audio", + .platform_name = "s3c24xx-iis", .init = simtec_tlv320aic23_init, }; @@ -88,7 +88,7 @@ static struct snd_soc_card snd_soc_machine_simtec_aic23 = { .num_dapm_routes = ARRAY_SIZE(base_map), }; -static int __devinit simtec_audio_tlv320aic23_probe(struct platform_device *pd) +static int simtec_audio_tlv320aic23_probe(struct platform_device *pd) { return simtec_audio_core_probe(pd, &snd_soc_machine_simtec_aic23); } @@ -100,7 +100,7 @@ static struct platform_driver simtec_audio_tlv320aic23_driver = { .pm = simtec_audio_pm, }, .probe = simtec_audio_tlv320aic23_probe, - .remove = __devexit_p(simtec_audio_remove), + .remove = simtec_audio_remove, }; module_platform_driver(simtec_audio_tlv320aic23_driver); diff --git a/sound/soc/samsung/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c index d731042e51b..333e1b7f06c 100644 --- a/sound/soc/samsung/s3c24xx_uda134x.c +++ b/sound/soc/samsung/s3c24xx_uda134x.c @@ -224,7 +224,7 @@ static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = { .codec_dai_name = "uda134x-hifi", .cpu_dai_name = "s3c24xx-iis", .ops = &s3c24xx_uda134x_ops, - .platform_name = "samsung-audio", + .platform_name = "s3c24xx-iis", }; static struct snd_soc_card snd_soc_s3c24xx_uda134x = { diff --git a/sound/soc/samsung/smartq_wm8987.c b/sound/soc/samsung/smartq_wm8987.c index f2dcb424ea2..58ae3237ef6 100644 --- a/sound/soc/samsung/smartq_wm8987.c +++ b/sound/soc/samsung/smartq_wm8987.c @@ -189,7 +189,7 @@ static struct snd_soc_dai_link smartq_dai[] = { .stream_name = "SmartQ Hi-Fi", .cpu_dai_name = "samsung-i2s.0", .codec_dai_name = "wm8750-hifi", - .platform_name = "samsung-audio", + .platform_name = "samsung-i2s.0", .codec_name = "wm8750.0-0x1a", .init = smartq_wm8987_init, .ops = &smartq_hifi_ops, diff --git a/sound/soc/samsung/smdk2443_wm9710.c b/sound/soc/samsung/smdk2443_wm9710.c index 720ba29bb7e..c390aad68cf 100644 --- a/sound/soc/samsung/smdk2443_wm9710.c +++ b/sound/soc/samsung/smdk2443_wm9710.c @@ -24,7 +24,7 @@ static struct snd_soc_dai_link smdk2443_dai[] = { .cpu_dai_name = "samsung-ac97", .codec_dai_name = "ac97-hifi", .codec_name = "ac97-codec", - .platform_name = "samsung-audio", + .platform_name = "samsung-ac97", }, }; diff --git a/sound/soc/samsung/smdk_spdif.c b/sound/soc/samsung/smdk_spdif.c index beaa9c15d69..a2f2363fe1c 100644 --- a/sound/soc/samsung/smdk_spdif.c +++ b/sound/soc/samsung/smdk_spdif.c @@ -151,7 +151,7 @@ static struct snd_soc_ops smdk_spdif_ops = { static struct snd_soc_dai_link smdk_dai = { .name = "S/PDIF", .stream_name = "S/PDIF PCM Playback", - .platform_name = "samsung-audio", + .platform_name = "samsung-spdif", .cpu_dai_name = "samsung-spdif", .codec_dai_name = "dit-hifi", .codec_name = "spdif-dit", diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c index ade2809cf39..7e2b710763b 100644 --- a/sound/soc/samsung/smdk_wm8580.c +++ b/sound/soc/samsung/smdk_wm8580.c @@ -176,7 +176,7 @@ static struct snd_soc_dai_link smdk_dai[] = { .stream_name = "Playback", .cpu_dai_name = "samsung-i2s.0", .codec_dai_name = "wm8580-hifi-playback", - .platform_name = "samsung-audio", + .platform_name = "samsung-i2s.0", .codec_name = "wm8580.0-001b", .ops = &smdk_ops, }, @@ -185,7 +185,7 @@ static struct snd_soc_dai_link smdk_dai[] = { .stream_name = "Capture", .cpu_dai_name = "samsung-i2s.0", .codec_dai_name = "wm8580-hifi-capture", - .platform_name = "samsung-audio", + .platform_name = "samsung-i2s.0", .codec_name = "wm8580.0-001b", .init = smdk_wm8580_init_paiftx, .ops = &smdk_ops, @@ -195,7 +195,7 @@ static struct snd_soc_dai_link smdk_dai[] = { .stream_name = "Playback", .cpu_dai_name = "samsung-i2s.x", .codec_dai_name = "wm8580-hifi-playback", - .platform_name = "samsung-audio", + .platform_name = "samsung-i2s.x", .codec_name = "wm8580.0-001b", .ops = &smdk_ops, }, diff --git a/sound/soc/samsung/smdk_wm8580pcm.c b/sound/soc/samsung/smdk_wm8580pcm.c index fab5322e9f0..e43bd4294f9 100644 --- a/sound/soc/samsung/smdk_wm8580pcm.c +++ b/sound/soc/samsung/smdk_wm8580pcm.c @@ -135,7 +135,7 @@ static struct snd_soc_dai_link smdk_dai[] = { .stream_name = "Capture", .cpu_dai_name = "samsung-pcm.0", .codec_dai_name = "wm8580-hifi-capture", - .platform_name = "samsung-audio", + .platform_name = "samsung-pcm.0", .codec_name = "wm8580.0-001b", .ops = &smdk_wm8580_pcm_ops, }, @@ -153,7 +153,7 @@ static struct snd_soc_card smdk_pcm = { * is absent (or not connected), so we connect EXT_VOICE_CLK(OSC4), * 2.0484Mhz, directly with MCLK both Codec and SoC. */ -static int __devinit snd_smdk_probe(struct platform_device *pdev) +static int snd_smdk_probe(struct platform_device *pdev) { int ret = 0; @@ -173,7 +173,7 @@ static int __devinit snd_smdk_probe(struct platform_device *pdev) return 0; } -static int __devexit snd_smdk_remove(struct platform_device *pdev) +static int snd_smdk_remove(struct platform_device *pdev) { snd_soc_unregister_card(&smdk_pcm); platform_set_drvdata(pdev, NULL); @@ -186,7 +186,7 @@ static struct platform_driver snd_smdk_driver = { .name = "samsung-smdk-pcm", }, .probe = snd_smdk_probe, - .remove = __devexit_p(snd_smdk_remove), + .remove = snd_smdk_remove, }; module_platform_driver(snd_smdk_driver); diff --git a/sound/soc/samsung/smdk_wm8994.c b/sound/soc/samsung/smdk_wm8994.c index 48dd4dd9ee0..b0d0ab8bff5 100644 --- a/sound/soc/samsung/smdk_wm8994.c +++ b/sound/soc/samsung/smdk_wm8994.c @@ -127,7 +127,7 @@ static struct snd_soc_dai_link smdk_dai[] = { .stream_name = "Pri_Dai", .cpu_dai_name = "samsung-i2s.0", .codec_dai_name = "wm8994-aif1", - .platform_name = "samsung-audio", + .platform_name = "samsung-i2s.0", .codec_name = "wm8994-codec", .init = smdk_wm8994_init_paiftx, .ops = &smdk_ops, @@ -136,7 +136,7 @@ static struct snd_soc_dai_link smdk_dai[] = { .stream_name = "Sec_Dai", .cpu_dai_name = "samsung-i2s.4", .codec_dai_name = "wm8994-aif1", - .platform_name = "samsung-audio", + .platform_name = "samsung-i2s.4", .codec_name = "wm8994-codec", .ops = &smdk_ops, }, @@ -150,7 +150,7 @@ static struct snd_soc_card smdk = { }; -static int __devinit smdk_audio_probe(struct platform_device *pdev) +static int smdk_audio_probe(struct platform_device *pdev) { int ret; struct snd_soc_card *card = &smdk; @@ -164,7 +164,7 @@ static int __devinit smdk_audio_probe(struct platform_device *pdev) return ret; } -static int __devexit smdk_audio_remove(struct platform_device *pdev) +static int smdk_audio_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -179,7 +179,7 @@ static struct platform_driver smdk_audio_driver = { .owner = THIS_MODULE, }, .probe = smdk_audio_probe, - .remove = __devexit_p(smdk_audio_remove), + .remove = smdk_audio_remove, }; module_platform_driver(smdk_audio_driver); diff --git a/sound/soc/samsung/smdk_wm8994pcm.c b/sound/soc/samsung/smdk_wm8994pcm.c index 77ecba93511..3688a32000a 100644 --- a/sound/soc/samsung/smdk_wm8994pcm.c +++ b/sound/soc/samsung/smdk_wm8994pcm.c @@ -116,7 +116,7 @@ static struct snd_soc_dai_link smdk_dai[] = { .stream_name = "Primary PCM", .cpu_dai_name = "samsung-pcm.0", .codec_dai_name = "wm8994-aif1", - .platform_name = "samsung-audio", + .platform_name = "samsung-pcm.0", .codec_name = "wm8994-codec", .ops = &smdk_wm8994_pcm_ops, }, @@ -129,7 +129,7 @@ static struct snd_soc_card smdk_pcm = { .num_links = 1, }; -static int __devinit snd_smdk_probe(struct platform_device *pdev) +static int snd_smdk_probe(struct platform_device *pdev) { int ret = 0; @@ -143,7 +143,7 @@ static int __devinit snd_smdk_probe(struct platform_device *pdev) return 0; } -static int __devexit snd_smdk_remove(struct platform_device *pdev) +static int snd_smdk_remove(struct platform_device *pdev) { snd_soc_unregister_card(&smdk_pcm); platform_set_drvdata(pdev, NULL); @@ -156,7 +156,7 @@ static struct platform_driver snd_smdk_driver = { .name = "samsung-smdk-pcm", }, .probe = snd_smdk_probe, - .remove = __devexit_p(snd_smdk_remove), + .remove = snd_smdk_remove, }; module_platform_driver(snd_smdk_driver); diff --git a/sound/soc/samsung/smdk_wm9713.c b/sound/soc/samsung/smdk_wm9713.c index 55b2ca7f329..0d20e4ed27a 100644 --- a/sound/soc/samsung/smdk_wm9713.c +++ b/sound/soc/samsung/smdk_wm9713.c @@ -42,7 +42,7 @@ static struct snd_soc_card smdk; static struct snd_soc_dai_link smdk_dai = { .name = "AC97", .stream_name = "AC97 PCM", - .platform_name = "samsung-audio", + .platform_name = "samsung-ac97", .cpu_dai_name = "samsung-ac97", .codec_dai_name = "wm9713-hifi", .codec_name = "wm9713-codec", diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c index bc24c7af02b..5008e5bd6ed 100644 --- a/sound/soc/samsung/spdif.c +++ b/sound/soc/samsung/spdif.c @@ -357,7 +357,7 @@ static struct snd_soc_dai_driver samsung_spdif_dai = { .resume = spdif_resume, }; -static __devinit int spdif_probe(struct platform_device *pdev) +static int spdif_probe(struct platform_device *pdev) { struct s3c_audio_pdata *spdif_pdata; struct resource *mem_res, *dma_res; @@ -397,7 +397,7 @@ static __devinit int spdif_probe(struct platform_device *pdev) ret = -ENOENT; goto err0; } - clk_enable(spdif->pclk); + clk_prepare_enable(spdif->pclk); spdif->sclk = clk_get(&pdev->dev, "sclk_spdif"); if (IS_ERR(spdif->sclk)) { @@ -405,7 +405,7 @@ static __devinit int spdif_probe(struct platform_device *pdev) ret = -ENOENT; goto err1; } - clk_enable(spdif->sclk); + clk_prepare_enable(spdif->sclk); /* Request S/PDIF Register's memory region */ if (!request_mem_region(mem_res->start, @@ -437,27 +437,35 @@ static __devinit int spdif_probe(struct platform_device *pdev) spdif->dma_playback = &spdif_stereo_out; - return 0; + ret = asoc_dma_platform_register(&pdev->dev); + if (ret) { + dev_err(&pdev->dev, "failed to register DMA: %d\n", ret); + goto err5; + } + return 0; +err5: + snd_soc_unregister_dai(&pdev->dev); err4: iounmap(spdif->regs); err3: release_mem_region(mem_res->start, resource_size(mem_res)); err2: - clk_disable(spdif->sclk); + clk_disable_unprepare(spdif->sclk); clk_put(spdif->sclk); err1: - clk_disable(spdif->pclk); + clk_disable_unprepare(spdif->pclk); clk_put(spdif->pclk); err0: return ret; } -static __devexit int spdif_remove(struct platform_device *pdev) +static int spdif_remove(struct platform_device *pdev) { struct samsung_spdif_info *spdif = &spdif_info; struct resource *mem_res; + asoc_dma_platform_unregister(&pdev->dev); snd_soc_unregister_dai(&pdev->dev); iounmap(spdif->regs); @@ -466,9 +474,9 @@ static __devexit int spdif_remove(struct platform_device *pdev) if (mem_res) release_mem_region(mem_res->start, resource_size(mem_res)); - clk_disable(spdif->sclk); + clk_disable_unprepare(spdif->sclk); clk_put(spdif->sclk); - clk_disable(spdif->pclk); + clk_disable_unprepare(spdif->pclk); clk_put(spdif->pclk); return 0; @@ -476,7 +484,7 @@ static __devexit int spdif_remove(struct platform_device *pdev) static struct platform_driver samsung_spdif_driver = { .probe = spdif_probe, - .remove = __devexit_p(spdif_remove), + .remove = spdif_remove, .driver = { .name = "samsung-spdif", .owner = THIS_MODULE, diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c index c7e1c28528a..57df90d6b7c 100644 --- a/sound/soc/samsung/speyside.c +++ b/sound/soc/samsung/speyside.c @@ -198,7 +198,7 @@ static struct snd_soc_dai_link speyside_dai[] = { .stream_name = "CPU-DSP", .cpu_dai_name = "samsung-i2s.0", .codec_dai_name = "wm0010-sdi1", - .platform_name = "samsung-audio", + .platform_name = "samsung-i2s.0", .codec_name = "spi0.0", .init = speyside_wm0010_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF @@ -320,7 +320,7 @@ static struct snd_soc_card speyside = { .late_probe = speyside_late_probe, }; -static __devinit int speyside_probe(struct platform_device *pdev) +static int speyside_probe(struct platform_device *pdev) { struct snd_soc_card *card = &speyside; int ret; @@ -337,7 +337,7 @@ static __devinit int speyside_probe(struct platform_device *pdev) return 0; } -static int __devexit speyside_remove(struct platform_device *pdev) +static int speyside_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -353,7 +353,7 @@ static struct platform_driver speyside_driver = { .pm = &snd_soc_pm_ops, }, .probe = speyside_probe, - .remove = __devexit_p(speyside_remove), + .remove = speyside_remove, }; module_platform_driver(speyside_driver); diff --git a/sound/soc/samsung/tobermory.c b/sound/soc/samsung/tobermory.c index 9199649bf78..f21ff608a81 100644 --- a/sound/soc/samsung/tobermory.c +++ b/sound/soc/samsung/tobermory.c @@ -110,7 +110,7 @@ static struct snd_soc_dai_link tobermory_dai[] = { .stream_name = "CPU", .cpu_dai_name = "samsung-i2s.0", .codec_dai_name = "wm8962", - .platform_name = "samsung-audio", + .platform_name = "samsung-i2s.0", .codec_name = "wm8962.1-001a", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM, @@ -214,7 +214,7 @@ static struct snd_soc_card tobermory = { .late_probe = tobermory_late_probe, }; -static __devinit int tobermory_probe(struct platform_device *pdev) +static int tobermory_probe(struct platform_device *pdev) { struct snd_soc_card *card = &tobermory; int ret; @@ -231,7 +231,7 @@ static __devinit int tobermory_probe(struct platform_device *pdev) return 0; } -static int __devexit tobermory_remove(struct platform_device *pdev) +static int tobermory_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -247,7 +247,7 @@ static struct platform_driver tobermory_driver = { .pm = &snd_soc_pm_ops, }, .probe = tobermory_probe, - .remove = __devexit_p(tobermory_remove), + .remove = tobermory_remove, }; module_platform_driver(tobermory_driver); diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c index 7da20186b19..19eff8fc4fd 100644 --- a/sound/soc/sh/dma-sh7760.c +++ b/sound/soc/sh/dma-sh7760.c @@ -348,12 +348,12 @@ static struct snd_soc_platform sh7760_soc_platform = { .pcm_free = camelot_pcm_free, }; -static int __devinit sh7760_soc_platform_probe(struct platform_device *pdev) +static int sh7760_soc_platform_probe(struct platform_device *pdev) { return snd_soc_register_platform(&pdev->dev, &sh7760_soc_platform); } -static int __devexit sh7760_soc_platform_remove(struct platform_device *pdev) +static int sh7760_soc_platform_remove(struct platform_device *pdev) { snd_soc_unregister_platform(&pdev->dev); return 0; @@ -366,7 +366,7 @@ static struct platform_driver sh7760_pcm_driver = { }, .probe = sh7760_soc_platform_probe, - .remove = __devexit_p(sh7760_soc_platform_remove), + .remove = sh7760_soc_platform_remove, }; module_platform_driver(sh7760_pcm_driver); diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 9d7f30774a4..a606d0f93d1 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -22,6 +22,7 @@ #include <linux/module.h> #include <linux/workqueue.h> #include <sound/soc.h> +#include <sound/pcm_params.h> #include <sound/sh_fsi.h> /* PortA/PortB register */ @@ -189,6 +190,14 @@ typedef int (*set_rate_func)(struct device *dev, int rate, int enable); */ /* + * FSI clock + * + * FSIxCLK [CPG] (ick) -------> | + * |-> FSI_DIV (div)-> FSI2 + * FSIxCK [external] (xck) ---> | + */ + +/* * struct */ @@ -228,6 +237,20 @@ struct fsi_stream { dma_addr_t dma; }; +struct fsi_clk { + /* see [FSI clock] */ + struct clk *own; + struct clk *xck; + struct clk *ick; + struct clk *div; + int (*set_rate)(struct device *dev, + struct fsi_priv *fsi, + unsigned long rate); + + unsigned long rate; + unsigned int count; +}; + struct fsi_priv { void __iomem *base; struct fsi_master *master; @@ -236,11 +259,17 @@ struct fsi_priv { struct fsi_stream playback; struct fsi_stream capture; + struct fsi_clk clock; + u32 fmt; int chan_num:16; int clk_master:1; + int clk_cpg:1; int spdif:1; + int enable_stream:1; + int bit_clk_inv:1; + int lr_clk_inv:1; long rate; }; @@ -370,6 +399,11 @@ static int fsi_is_spdif(struct fsi_priv *fsi) return fsi->spdif; } +static int fsi_is_enable_stream(struct fsi_priv *fsi) +{ + return fsi->enable_stream; +} + static int fsi_is_play(struct snd_pcm_substream *substream) { return substream->stream == SNDRV_PCM_STREAM_PLAYBACK; @@ -717,14 +751,335 @@ static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable) /* * clock function */ +static int fsi_clk_init(struct device *dev, + struct fsi_priv *fsi, + int xck, + int ick, + int div, + int (*set_rate)(struct device *dev, + struct fsi_priv *fsi, + unsigned long rate)) +{ + struct fsi_clk *clock = &fsi->clock; + int is_porta = fsi_is_port_a(fsi); + + clock->xck = NULL; + clock->ick = NULL; + clock->div = NULL; + clock->rate = 0; + clock->count = 0; + clock->set_rate = set_rate; + + clock->own = devm_clk_get(dev, NULL); + if (IS_ERR(clock->own)) + return -EINVAL; + + /* external clock */ + if (xck) { + clock->xck = devm_clk_get(dev, is_porta ? "xcka" : "xckb"); + if (IS_ERR(clock->xck)) { + dev_err(dev, "can't get xck clock\n"); + return -EINVAL; + } + if (clock->xck == clock->own) { + dev_err(dev, "cpu doesn't support xck clock\n"); + return -EINVAL; + } + } + + /* FSIACLK/FSIBCLK */ + if (ick) { + clock->ick = devm_clk_get(dev, is_porta ? "icka" : "ickb"); + if (IS_ERR(clock->ick)) { + dev_err(dev, "can't get ick clock\n"); + return -EINVAL; + } + if (clock->ick == clock->own) { + dev_err(dev, "cpu doesn't support ick clock\n"); + return -EINVAL; + } + } + + /* FSI-DIV */ + if (div) { + clock->div = devm_clk_get(dev, is_porta ? "diva" : "divb"); + if (IS_ERR(clock->div)) { + dev_err(dev, "can't get div clock\n"); + return -EINVAL; + } + if (clock->div == clock->own) { + dev_err(dev, "cpu doens't support div clock\n"); + return -EINVAL; + } + } + + return 0; +} + +#define fsi_clk_invalid(fsi) fsi_clk_valid(fsi, 0) +static void fsi_clk_valid(struct fsi_priv *fsi, unsigned long rate) +{ + fsi->clock.rate = rate; +} + +static int fsi_clk_is_valid(struct fsi_priv *fsi) +{ + return fsi->clock.set_rate && + fsi->clock.rate; +} + +static int fsi_clk_enable(struct device *dev, + struct fsi_priv *fsi, + unsigned long rate) +{ + struct fsi_clk *clock = &fsi->clock; + int ret = -EINVAL; + + if (!fsi_clk_is_valid(fsi)) + return ret; + + if (0 == clock->count) { + ret = clock->set_rate(dev, fsi, rate); + if (ret < 0) { + fsi_clk_invalid(fsi); + return ret; + } + + if (clock->xck) + clk_enable(clock->xck); + if (clock->ick) + clk_enable(clock->ick); + if (clock->div) + clk_enable(clock->div); + + clock->count++; + } + + return ret; +} + +static int fsi_clk_disable(struct device *dev, + struct fsi_priv *fsi) +{ + struct fsi_clk *clock = &fsi->clock; + + if (!fsi_clk_is_valid(fsi)) + return -EINVAL; + + if (1 == clock->count--) { + if (clock->xck) + clk_disable(clock->xck); + if (clock->ick) + clk_disable(clock->ick); + if (clock->div) + clk_disable(clock->div); + } + + return 0; +} + +static int fsi_clk_set_ackbpf(struct device *dev, + struct fsi_priv *fsi, + int ackmd, int bpfmd) +{ + u32 data = 0; + + /* check ackmd/bpfmd relationship */ + if (bpfmd > ackmd) { + dev_err(dev, "unsupported rate (%d/%d)\n", ackmd, bpfmd); + return -EINVAL; + } + + /* ACKMD */ + switch (ackmd) { + case 512: + data |= (0x0 << 12); + break; + case 256: + data |= (0x1 << 12); + break; + case 128: + data |= (0x2 << 12); + break; + case 64: + data |= (0x3 << 12); + break; + case 32: + data |= (0x4 << 12); + break; + default: + dev_err(dev, "unsupported ackmd (%d)\n", ackmd); + return -EINVAL; + } + + /* BPFMD */ + switch (bpfmd) { + case 32: + data |= (0x0 << 8); + break; + case 64: + data |= (0x1 << 8); + break; + case 128: + data |= (0x2 << 8); + break; + case 256: + data |= (0x3 << 8); + break; + case 512: + data |= (0x4 << 8); + break; + case 16: + data |= (0x7 << 8); + break; + default: + dev_err(dev, "unsupported bpfmd (%d)\n", bpfmd); + return -EINVAL; + } + + dev_dbg(dev, "ACKMD/BPFMD = %d/%d\n", ackmd, bpfmd); + + fsi_reg_mask_set(fsi, CKG1, (ACKMD_MASK | BPFMD_MASK) , data); + udelay(10); + + return 0; +} + +static int fsi_clk_set_rate_external(struct device *dev, + struct fsi_priv *fsi, + unsigned long rate) +{ + struct clk *xck = fsi->clock.xck; + struct clk *ick = fsi->clock.ick; + unsigned long xrate; + int ackmd, bpfmd; + int ret = 0; + + /* check clock rate */ + xrate = clk_get_rate(xck); + if (xrate % rate) { + dev_err(dev, "unsupported clock rate\n"); + return -EINVAL; + } + + clk_set_parent(ick, xck); + clk_set_rate(ick, xrate); + + bpfmd = fsi->chan_num * 32; + ackmd = xrate / rate; + + dev_dbg(dev, "external/rate = %ld/%ld\n", xrate, rate); + + ret = fsi_clk_set_ackbpf(dev, fsi, ackmd, bpfmd); + if (ret < 0) + dev_err(dev, "%s failed", __func__); + + return ret; +} + +static int fsi_clk_set_rate_cpg(struct device *dev, + struct fsi_priv *fsi, + unsigned long rate) +{ + struct clk *ick = fsi->clock.ick; + struct clk *div = fsi->clock.div; + unsigned long target = 0; /* 12288000 or 11289600 */ + unsigned long actual, cout; + unsigned long diff, min; + unsigned long best_cout, best_act; + int adj; + int ackmd, bpfmd; + int ret = -EINVAL; + + if (!(12288000 % rate)) + target = 12288000; + if (!(11289600 % rate)) + target = 11289600; + if (!target) { + dev_err(dev, "unsupported rate\n"); + return ret; + } + + bpfmd = fsi->chan_num * 32; + ackmd = target / rate; + ret = fsi_clk_set_ackbpf(dev, fsi, ackmd, bpfmd); + if (ret < 0) { + dev_err(dev, "%s failed", __func__); + return ret; + } + + /* + * The clock flow is + * + * [CPG] = cout => [FSI_DIV] = audio => [FSI] => [codec] + * + * But, it needs to find best match of CPG and FSI_DIV + * combination, since it is difficult to generate correct + * frequency of audio clock from ick clock only. + * Because ick is created from its parent clock. + * + * target = rate x [512/256/128/64]fs + * cout = round(target x adjustment) + * actual = cout / adjustment (by FSI-DIV) ~= target + * audio = actual + */ + min = ~0; + best_cout = 0; + best_act = 0; + for (adj = 1; adj < 0xffff; adj++) { + + cout = target * adj; + if (cout > 100000000) /* max clock = 100MHz */ + break; + + /* cout/actual audio clock */ + cout = clk_round_rate(ick, cout); + actual = cout / adj; + + /* find best frequency */ + diff = abs(actual - target); + if (diff < min) { + min = diff; + best_cout = cout; + best_act = actual; + } + } + + ret = clk_set_rate(ick, best_cout); + if (ret < 0) { + dev_err(dev, "ick clock failed\n"); + return -EIO; + } + + ret = clk_set_rate(div, clk_round_rate(div, best_act)); + if (ret < 0) { + dev_err(dev, "div clock failed\n"); + return -EIO; + } + + dev_dbg(dev, "ick/div = %ld/%ld\n", + clk_get_rate(ick), clk_get_rate(div)); + + return ret; +} + static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, long rate, int enable) { set_rate_func set_rate = fsi_get_info_set_rate(fsi); int ret; - if (!set_rate) - return 0; + /* + * CAUTION + * + * set_rate will be deleted + */ + if (!set_rate) { + if (enable) + return fsi_clk_enable(dev, fsi, rate); + else + return fsi_clk_disable(dev, fsi); + } ret = set_rate(dev, rate, enable); if (ret < 0) /* error */ @@ -792,10 +1147,9 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, */ static void fsi_pio_push16(struct fsi_priv *fsi, u8 *_buf, int samples) { - u32 enable_stream = fsi_get_info_flags(fsi) & SH_FSI_ENABLE_STREAM_MODE; int i; - if (enable_stream) { + if (fsi_is_enable_stream(fsi)) { /* * stream mode * see @@ -953,8 +1307,6 @@ static void fsi_pio_start_stop(struct fsi_priv *fsi, struct fsi_stream *io, static int fsi_pio_push_init(struct fsi_priv *fsi, struct fsi_stream *io) { - u32 enable_stream = fsi_get_info_flags(fsi) & SH_FSI_ENABLE_STREAM_MODE; - /* * we can use 16bit stream mode * when "playback" and "16bit data" @@ -962,7 +1314,7 @@ static int fsi_pio_push_init(struct fsi_priv *fsi, struct fsi_stream *io) * see * fsi_pio_push16() */ - if (enable_stream) + if (fsi_is_enable_stream(fsi)) io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) | BUSOP_SET(16, PACKAGE_16BITBUS_STREAM); else @@ -1296,6 +1648,16 @@ static int fsi_hw_startup(struct fsi_priv *fsi, /* clock inversion (CKG2) */ data = 0; + if (fsi->bit_clk_inv) + data |= (1 << 0); + if (fsi->lr_clk_inv) + data |= (1 << 4); + if (fsi_is_clk_master(fsi)) + data <<= 8; + /* FIXME + * + * SH_FSI_xxx_INV style will be removed + */ if (SH_FSI_LRM_INV & flags) data |= 1 << 12; if (SH_FSI_BRM_INV & flags) @@ -1334,14 +1696,21 @@ static int fsi_hw_startup(struct fsi_priv *fsi, /* fifo init */ fsi_fifo_init(fsi, io, dev); + /* start master clock */ + if (fsi_is_clk_master(fsi)) + return fsi_set_master_clk(dev, fsi, fsi->rate, 1); + return 0; } -static void fsi_hw_shutdown(struct fsi_priv *fsi, +static int fsi_hw_shutdown(struct fsi_priv *fsi, struct device *dev) { + /* stop master clock */ if (fsi_is_clk_master(fsi)) - fsi_set_master_clk(dev, fsi, fsi->rate, 0); + return fsi_set_master_clk(dev, fsi, fsi->rate, 0); + + return 0; } static int fsi_dai_startup(struct snd_pcm_substream *substream, @@ -1349,6 +1718,7 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, { struct fsi_priv *fsi = fsi_get_priv(substream); + fsi_clk_invalid(fsi); fsi->rate = 0; return 0; @@ -1359,6 +1729,7 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream, { struct fsi_priv *fsi = fsi_get_priv(substream); + fsi_clk_invalid(fsi); fsi->rate = 0; } @@ -1372,13 +1743,16 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, switch (cmd) { case SNDRV_PCM_TRIGGER_START: fsi_stream_init(fsi, io, substream); - fsi_hw_startup(fsi, io, dai->dev); - ret = fsi_stream_transfer(io); - if (0 == ret) + if (!ret) + ret = fsi_hw_startup(fsi, io, dai->dev); + if (!ret) + ret = fsi_stream_transfer(io); + if (!ret) fsi_stream_start(fsi, io); break; case SNDRV_PCM_TRIGGER_STOP: - fsi_hw_shutdown(fsi, dai->dev); + if (!ret) + ret = fsi_hw_shutdown(fsi, dai->dev); fsi_stream_stop(fsi, io); fsi_stream_quit(fsi, io); break; @@ -1414,7 +1788,6 @@ static int fsi_set_fmt_spdif(struct fsi_priv *fsi) fsi->fmt = CR_DTMD_SPDIF_PCM | CR_PCM; fsi->chan_num = 2; - fsi->spdif = 1; return 0; } @@ -1423,7 +1796,6 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) { struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai); set_rate_func set_rate = fsi_get_info_set_rate(fsi); - u32 flags = fsi_get_info_flags(fsi); int ret; /* set master/slave audio interface */ @@ -1437,23 +1809,50 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) return -EINVAL; } - if (fsi_is_clk_master(fsi) && !set_rate) { - dev_err(dai->dev, "platform doesn't have set_rate\n"); - return -EINVAL; - } - - /* set format */ - switch (flags & SH_FSI_FMT_MASK) { - case SH_FSI_FMT_DAI: - ret = fsi_set_fmt_dai(fsi, fmt & SND_SOC_DAIFMT_FORMAT_MASK); + /* set clock inversion */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_IF: + fsi->bit_clk_inv = 0; + fsi->lr_clk_inv = 1; break; - case SH_FSI_FMT_SPDIF: - ret = fsi_set_fmt_spdif(fsi); + case SND_SOC_DAIFMT_IB_NF: + fsi->bit_clk_inv = 1; + fsi->lr_clk_inv = 0; break; + case SND_SOC_DAIFMT_IB_IF: + fsi->bit_clk_inv = 1; + fsi->lr_clk_inv = 1; + break; + case SND_SOC_DAIFMT_NB_NF: default: - ret = -EINVAL; + fsi->bit_clk_inv = 0; + fsi->lr_clk_inv = 0; + break; + } + + if (fsi_is_clk_master(fsi)) { + /* + * CAUTION + * + * set_rate will be deleted + */ + if (set_rate) + dev_warn(dai->dev, "set_rate will be removed soon\n"); + + if (fsi->clk_cpg) + fsi_clk_init(dai->dev, fsi, 0, 1, 1, + fsi_clk_set_rate_cpg); + else + fsi_clk_init(dai->dev, fsi, 1, 1, 0, + fsi_clk_set_rate_external); } + /* set format */ + if (fsi_is_spdif(fsi)) + ret = fsi_set_fmt_spdif(fsi); + else + ret = fsi_set_fmt_dai(fsi, fmt & SND_SOC_DAIFMT_FORMAT_MASK); + return ret; } @@ -1462,19 +1861,13 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct fsi_priv *fsi = fsi_get_priv(substream); - long rate = params_rate(params); - int ret; - if (!fsi_is_clk_master(fsi)) - return 0; - - ret = fsi_set_master_clk(dai->dev, fsi, rate, 1); - if (ret < 0) - return ret; - - fsi->rate = rate; + if (fsi_is_clk_master(fsi)) { + fsi->rate = params_rate(params); + fsi_clk_valid(fsi, fsi->rate); + } - return ret; + return 0; } static const struct snd_soc_dai_ops fsi_dai_ops = { @@ -1498,7 +1891,7 @@ static struct snd_pcm_hardware fsi_pcm_hardware = { .rates = FSI_RATES, .rate_min = 8000, .rate_max = 192000, - .channels_min = 1, + .channels_min = 2, .channels_max = 2, .buffer_bytes_max = 64 * 1024, .period_bytes_min = 32, @@ -1586,14 +1979,14 @@ static struct snd_soc_dai_driver fsi_soc_dai[] = { .playback = { .rates = FSI_RATES, .formats = FSI_FMTS, - .channels_min = 1, - .channels_max = 8, + .channels_min = 2, + .channels_max = 2, }, .capture = { .rates = FSI_RATES, .formats = FSI_FMTS, - .channels_min = 1, - .channels_max = 8, + .channels_min = 2, + .channels_max = 2, }, .ops = &fsi_dai_ops, }, @@ -1602,14 +1995,14 @@ static struct snd_soc_dai_driver fsi_soc_dai[] = { .playback = { .rates = FSI_RATES, .formats = FSI_FMTS, - .channels_min = 1, - .channels_max = 8, + .channels_min = 2, + .channels_max = 2, }, .capture = { .rates = FSI_RATES, .formats = FSI_FMTS, - .channels_min = 1, - .channels_max = 8, + .channels_min = 2, + .channels_max = 2, }, .ops = &fsi_dai_ops, }, @@ -1624,15 +2017,29 @@ static struct snd_soc_platform_driver fsi_soc_platform = { /* * platform function */ -static void fsi_handler_init(struct fsi_priv *fsi) +static void fsi_port_info_init(struct fsi_priv *fsi, + struct sh_fsi_port_info *info) +{ + if (info->flags & SH_FSI_FMT_SPDIF) + fsi->spdif = 1; + + if (info->flags & SH_FSI_CLK_CPG) + fsi->clk_cpg = 1; + + if (info->flags & SH_FSI_ENABLE_STREAM_MODE) + fsi->enable_stream = 1; +} + +static void fsi_handler_init(struct fsi_priv *fsi, + struct sh_fsi_port_info *info) { fsi->playback.handler = &fsi_pio_push_handler; /* default PIO */ fsi->playback.priv = fsi; fsi->capture.handler = &fsi_pio_pop_handler; /* default PIO */ fsi->capture.priv = fsi; - if (fsi->info->tx_id) { - fsi->playback.slave.shdma_slave.slave_id = fsi->info->tx_id; + if (info->tx_id) { + fsi->playback.slave.shdma_slave.slave_id = info->tx_id; fsi->playback.handler = &fsi_dma_push_handler; } } @@ -1642,10 +2049,16 @@ static int fsi_probe(struct platform_device *pdev) struct fsi_master *master; const struct platform_device_id *id_entry; struct sh_fsi_platform_info *info = pdev->dev.platform_data; + struct sh_fsi_port_info nul_info, *pinfo; + struct fsi_priv *fsi; struct resource *res; unsigned int irq; int ret; + nul_info.flags = 0; + nul_info.tx_id = 0; + nul_info.rx_id = 0; + id_entry = pdev->id_entry; if (!id_entry) { dev_err(&pdev->dev, "unknown fsi device\n"); @@ -1678,22 +2091,28 @@ static int fsi_probe(struct platform_device *pdev) spin_lock_init(&master->lock); /* FSI A setting */ - master->fsia.base = master->base; - master->fsia.master = master; - master->fsia.info = &info->port_a; - fsi_handler_init(&master->fsia); - ret = fsi_stream_probe(&master->fsia, &pdev->dev); + pinfo = (info) ? &info->port_a : &nul_info; + fsi = &master->fsia; + fsi->base = master->base; + fsi->master = master; + fsi->info = pinfo; + fsi_port_info_init(fsi, pinfo); + fsi_handler_init(fsi, pinfo); + ret = fsi_stream_probe(fsi, &pdev->dev); if (ret < 0) { dev_err(&pdev->dev, "FSIA stream probe failed\n"); return ret; } /* FSI B setting */ - master->fsib.base = master->base + 0x40; - master->fsib.master = master; - master->fsib.info = &info->port_b; - fsi_handler_init(&master->fsib); - ret = fsi_stream_probe(&master->fsib, &pdev->dev); + pinfo = (info) ? &info->port_b : &nul_info; + fsi = &master->fsib; + fsi->base = master->base + 0x40; + fsi->master = master; + fsi->info = pinfo; + fsi_port_info_init(fsi, pinfo); + fsi_handler_init(fsi, pinfo); + ret = fsi_stream_probe(fsi, &pdev->dev); if (ret < 0) { dev_err(&pdev->dev, "FSIB stream probe failed\n"); goto exit_fsia; @@ -1702,7 +2121,7 @@ static int fsi_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); dev_set_drvdata(&pdev->dev, master); - ret = request_irq(irq, &fsi_interrupt, 0, + ret = devm_request_irq(&pdev->dev, irq, &fsi_interrupt, 0, id_entry->name, master); if (ret) { dev_err(&pdev->dev, "irq request err\n"); @@ -1712,7 +2131,7 @@ static int fsi_probe(struct platform_device *pdev) ret = snd_soc_register_platform(&pdev->dev, &fsi_soc_platform); if (ret < 0) { dev_err(&pdev->dev, "cannot snd soc register\n"); - goto exit_free_irq; + goto exit_fsib; } ret = snd_soc_register_dais(&pdev->dev, fsi_soc_dai, @@ -1726,8 +2145,6 @@ static int fsi_probe(struct platform_device *pdev) exit_snd_soc: snd_soc_unregister_platform(&pdev->dev); -exit_free_irq: - free_irq(irq, master); exit_fsib: pm_runtime_disable(&pdev->dev); fsi_stream_remove(&master->fsib); @@ -1743,7 +2160,6 @@ static int fsi_remove(struct platform_device *pdev) master = dev_get_drvdata(&pdev->dev); - free_irq(master->irq, master); pm_runtime_disable(&pdev->dev); snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(fsi_soc_dai)); @@ -1774,10 +2190,6 @@ static void __fsi_resume(struct fsi_priv *fsi, return; fsi_hw_startup(fsi, io, dev); - - if (fsi_is_clk_master(fsi) && fsi->rate) - fsi_set_master_clk(dev, fsi, fsi->rate, 1); - fsi_stream_start(fsi, io); } diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c index 3474d7befe5..4cc2d64ef47 100644 --- a/sound/soc/sh/hac.c +++ b/sound/soc/sh/hac.c @@ -310,13 +310,13 @@ static struct snd_soc_dai_driver sh4_hac_dai[] = { #endif }; -static int __devinit hac_soc_platform_probe(struct platform_device *pdev) +static int hac_soc_platform_probe(struct platform_device *pdev) { return snd_soc_register_dais(&pdev->dev, sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai)); } -static int __devexit hac_soc_platform_remove(struct platform_device *pdev) +static int hac_soc_platform_remove(struct platform_device *pdev) { snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(sh4_hac_dai)); return 0; @@ -329,7 +329,7 @@ static struct platform_driver hac_pcm_driver = { }, .probe = hac_soc_platform_probe, - .remove = __devexit_p(hac_soc_platform_remove), + .remove = hac_soc_platform_remove, }; module_platform_driver(hac_pcm_driver); diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c index 52d4c17b123..34facdc9e4a 100644 --- a/sound/soc/sh/siu_dai.c +++ b/sound/soc/sh/siu_dai.c @@ -726,7 +726,7 @@ static struct snd_soc_dai_driver siu_i2s_dai = { .ops = &siu_dai_ops, }; -static int __devinit siu_probe(struct platform_device *pdev) +static int siu_probe(struct platform_device *pdev) { const struct firmware *fw_entry; struct resource *res, *region; @@ -815,7 +815,7 @@ ereqfw: return ret; } -static int __devexit siu_remove(struct platform_device *pdev) +static int siu_remove(struct platform_device *pdev) { struct siu_info *info = dev_get_drvdata(&pdev->dev); struct resource *res; @@ -843,7 +843,7 @@ static struct platform_driver siu_driver = { .name = "siu-pcm-audio", }, .probe = siu_probe, - .remove = __devexit_p(siu_remove), + .remove = siu_remove, }; module_platform_driver(siu_driver); diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c index ff82b56a886..c8e73a70393 100644 --- a/sound/soc/sh/ssi.c +++ b/sound/soc/sh/ssi.c @@ -379,13 +379,13 @@ static struct snd_soc_dai_driver sh4_ssi_dai[] = { #endif }; -static int __devinit sh4_soc_dai_probe(struct platform_device *pdev) +static int sh4_soc_dai_probe(struct platform_device *pdev) { return snd_soc_register_dais(&pdev->dev, sh4_ssi_dai, ARRAY_SIZE(sh4_ssi_dai)); } -static int __devexit sh4_soc_dai_remove(struct platform_device *pdev) +static int sh4_soc_dai_remove(struct platform_device *pdev) { snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(sh4_ssi_dai)); return 0; @@ -398,7 +398,7 @@ static struct platform_driver sh4_ssi_driver = { }, .probe = sh4_soc_dai_probe, - .remove = __devexit_p(sh4_soc_dai_remove), + .remove = sh4_soc_dai_remove, }; module_platform_driver(sh4_ssi_driver); diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 9d56f0218f4..e72f55428f0 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) ret = snd_soc_write(codec, i, val); if (ret) return ret; - dev_dbg(codec->dev, "Synced register %#x, value = %#x\n", + dev_dbg(codec->dev, "ASoC: Synced register %#x, value = %#x\n", i, val); } return 0; @@ -156,7 +156,7 @@ int snd_soc_cache_init(struct snd_soc_codec *codec) /* Fall back to flat compression */ if (i == ARRAY_SIZE(cache_types)) { - dev_warn(codec->dev, "Could not match compress type: %d\n", + dev_warn(codec->dev, "ASoC: Could not match compress type: %d\n", codec->compress_type); i = 0; } @@ -166,7 +166,7 @@ int snd_soc_cache_init(struct snd_soc_codec *codec) if (codec->cache_ops->init) { if (codec->cache_ops->name) - dev_dbg(codec->dev, "Initializing %s cache for %s codec\n", + dev_dbg(codec->dev, "ASoC: Initializing %s cache for %s codec\n", codec->cache_ops->name, codec->name); return codec->cache_ops->init(codec); } @@ -181,7 +181,7 @@ int snd_soc_cache_exit(struct snd_soc_codec *codec) { if (codec->cache_ops && codec->cache_ops->exit) { if (codec->cache_ops->name) - dev_dbg(codec->dev, "Destroying %s cache for %s codec\n", + dev_dbg(codec->dev, "ASoC: Destroying %s cache for %s codec\n", codec->cache_ops->name, codec->name); return codec->cache_ops->exit(codec); } @@ -265,7 +265,7 @@ int snd_soc_cache_sync(struct snd_soc_codec *codec) name = "unknown"; if (codec->cache_ops->name) - dev_dbg(codec->dev, "Syncing %s cache for %s codec\n", + dev_dbg(codec->dev, "ASoC: Syncing %s cache for %s codec\n", codec->cache_ops->name, codec->name); trace_snd_soc_cache_sync(codec, name, "start"); ret = codec->cache_ops->sync(codec); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 10d21be383f..9c768bcb98a 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) codec->debugfs_codec_root = debugfs_create_dir(codec->name, debugfs_card_root); if (!codec->debugfs_codec_root) { - dev_warn(codec->dev, "Failed to create codec debugfs directory\n"); + dev_warn(codec->dev, "ASoC: Failed to create codec debugfs" + " directory\n"); return; } @@ -284,7 +285,8 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec) codec->debugfs_codec_root, codec, &codec_reg_fops); if (!codec->debugfs_reg) - dev_warn(codec->dev, "Failed to create codec register debugfs file\n"); + dev_warn(codec->dev, "ASoC: Failed to create codec register" + " debugfs file\n"); snd_soc_dapm_debugfs_init(&codec->dapm, codec->debugfs_codec_root); } @@ -302,7 +304,7 @@ static void soc_init_platform_debugfs(struct snd_soc_platform *platform) debugfs_card_root); if (!platform->debugfs_platform_root) { dev_warn(platform->dev, - "Failed to create platform debugfs directory\n"); + "ASoC: Failed to create platform debugfs directory\n"); return; } @@ -430,7 +432,7 @@ static void soc_init_card_debugfs(struct snd_soc_card *card) &card->pop_time); if (!card->debugfs_pop_time) dev_warn(card->dev, - "Failed to create pop time debugfs file\n"); + "ASoC: Failed to create pop time debugfs file\n"); } 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, !strcmp(card->rtd[i].dai_link->name, dai_link)) return card->rtd[i].pcm->streams[stream].substream; } - dev_dbg(card->dev, "failed to find dai link %s\n", dai_link); + dev_dbg(card->dev, "ASoC: failed to find dai link %s\n", dai_link); return NULL; } 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, if (!strcmp(card->rtd[i].dai_link->name, dai_link)) return &card->rtd[i]; } - dev_dbg(card->dev, "failed to find rtd %s\n", dai_link); + dev_dbg(card->dev, "ASoC: failed to find rtd %s\n", dai_link); return NULL; } EXPORT_SYMBOL_GPL(snd_soc_get_pcm_runtime); @@ -519,7 +521,7 @@ static int soc_ac97_dev_register(struct snd_soc_codec *codec) codec->card->snd_card->number, 0, codec->name); err = device_register(&codec->ac97->dev); if (err < 0) { - snd_printk(KERN_ERR "Can't register ac97 bus\n"); + dev_err(codec->dev, "ASoC: Can't register ac97 bus\n"); codec->ac97->dev.bus = NULL; return err; } @@ -628,7 +630,8 @@ int snd_soc_suspend(struct device *dev) */ if (codec->dapm.idle_bias_off) { dev_dbg(codec->dev, - "idle_bias_off CODEC on over suspend\n"); + "ASoC: idle_bias_off CODEC on" + " over suspend\n"); break; } case SND_SOC_BIAS_OFF: @@ -639,7 +642,8 @@ int snd_soc_suspend(struct device *dev) regcache_mark_dirty(codec->control_data); break; default: - dev_dbg(codec->dev, "CODEC is on over suspend\n"); + dev_dbg(codec->dev, "ASoC: CODEC is on" + " over suspend\n"); break; } } @@ -676,7 +680,7 @@ static void soc_resume_deferred(struct work_struct *work) * so userspace apps are blocked from touching us */ - dev_dbg(card->dev, "starting resume work\n"); + dev_dbg(card->dev, "ASoC: starting resume work\n"); /* Bring us up into D2 so that DAPM starts enabling things */ snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D2); @@ -708,7 +712,8 @@ static void soc_resume_deferred(struct work_struct *work) codec->suspended = 0; break; default: - dev_dbg(codec->dev, "CODEC was on over suspend\n"); + dev_dbg(codec->dev, "ASoC: CODEC was on over" + " suspend\n"); break; } } @@ -758,7 +763,7 @@ static void soc_resume_deferred(struct work_struct *work) if (card->resume_post) card->resume_post(card); - dev_dbg(card->dev, "resume work completed\n"); + dev_dbg(card->dev, "ASoC: resume work completed\n"); /* userspace can access us now we are back as we were before */ snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D0); @@ -790,12 +795,12 @@ int snd_soc_resume(struct device *dev) ac97_control |= cpu_dai->driver->ac97_control; } if (ac97_control) { - dev_dbg(dev, "Resuming AC97 immediately\n"); + dev_dbg(dev, "ASoC: Resuming AC97 immediately\n"); soc_resume_deferred(&card->deferred_resume_work); } else { - dev_dbg(dev, "Scheduling resume work\n"); + dev_dbg(dev, "ASoC: Scheduling resume work\n"); if (!schedule_work(&card->deferred_resume_work)) - dev_err(dev, "resume work item may be lost\n"); + dev_err(dev, "ASoC: resume work item may be lost\n"); } return 0; @@ -818,7 +823,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) struct snd_soc_dai *codec_dai, *cpu_dai; const char *platform_name; - dev_dbg(card->dev, "binding %s at idx %d\n", dai_link->name, num); + dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num); /* Find CPU DAI from registered DAIs*/ 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) } if (!rtd->cpu_dai) { - dev_err(card->dev, "CPU DAI %s not registered\n", + dev_err(card->dev, "ASoC: CPU DAI %s not registered\n", dai_link->cpu_dai_name); return -EPROBE_DEFER; } @@ -867,14 +872,14 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) } if (!rtd->codec_dai) { - dev_err(card->dev, "CODEC DAI %s not registered\n", + dev_err(card->dev, "ASoC: CODEC DAI %s not registered\n", dai_link->codec_dai_name); return -EPROBE_DEFER; } } if (!rtd->codec) { - dev_err(card->dev, "CODEC %s not registered\n", + dev_err(card->dev, "ASoC: CODEC %s not registered\n", dai_link->codec_name); return -EPROBE_DEFER; } @@ -898,7 +903,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) rtd->platform = platform; } if (!rtd->platform) { - dev_err(card->dev, "platform %s not registered\n", + dev_err(card->dev, "ASoC: platform %s not registered\n", dai_link->platform_name); return -EPROBE_DEFER; } @@ -915,8 +920,8 @@ static int soc_remove_platform(struct snd_soc_platform *platform) if (platform->driver->remove) { ret = platform->driver->remove(platform); if (ret < 0) - pr_err("asoc: failed to remove %s: %d\n", - platform->name, ret); + dev_err(platform->dev, "ASoC: failed to remove %d\n", + ret); } /* Make sure all DAPM widgets are freed */ @@ -937,9 +942,7 @@ static void soc_remove_codec(struct snd_soc_codec *codec) if (codec->driver->remove) { err = codec->driver->remove(codec); if (err < 0) - dev_err(codec->dev, - "asoc: failed to remove %s: %d\n", - codec->name, err); + dev_err(codec->dev, "ASoC: failed to remove %d\n", err); } /* 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) if (codec_dai->driver->remove) { err = codec_dai->driver->remove(codec_dai); if (err < 0) - pr_err("asoc: failed to remove %s: %d\n", - codec_dai->name, err); + dev_err(codec_dai->dev, + "ASoC: failed to remove %s: %d\n", + codec_dai->name, err); } codec_dai->probed = 0; 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) if (cpu_dai->driver->remove) { err = cpu_dai->driver->remove(cpu_dai); if (err < 0) - pr_err("asoc: failed to remove %s: %d\n", - cpu_dai->name, err); + dev_err(cpu_dai->dev, + "ASoC: failed to remove %s: %d\n", + cpu_dai->name, err); } cpu_dai->probed = 0; list_del(&cpu_dai->card_list); @@ -1099,8 +1104,7 @@ static int soc_probe_codec(struct snd_soc_card *card, ret = driver->probe(codec); if (ret < 0) { dev_err(codec->dev, - "asoc: failed to probe CODEC %s: %d\n", - codec->name, ret); + "ASoC: failed to probe CODEC %d\n", ret); goto err_probe; } } @@ -1163,8 +1167,7 @@ static int soc_probe_platform(struct snd_soc_card *card, ret = driver->probe(platform); if (ret < 0) { dev_err(platform->dev, - "asoc: failed to probe platform %s: %d\n", - platform->name, ret); + "ASoC: failed to probe platform %d\n", ret); goto err_probe; } } @@ -1229,7 +1232,7 @@ static int soc_post_component_init(struct snd_soc_card *card, else if (dailess && aux_dev->init) ret = aux_dev->init(&codec->dapm); if (ret < 0) { - dev_err(card->dev, "asoc: failed to init %s: %d\n", name, ret); + dev_err(card->dev, "ASoC: failed to init %s: %d\n", name, ret); return ret; } codec->name_prefix = temp; @@ -1253,7 +1256,7 @@ static int soc_post_component_init(struct snd_soc_card *card, ret = device_add(rtd->dev); if (ret < 0) { dev_err(card->dev, - "asoc: failed to register runtime device: %d\n", ret); + "ASoC: failed to register runtime device: %d\n", ret); return ret; } rtd->dev_registered = 1; @@ -1262,14 +1265,13 @@ static int soc_post_component_init(struct snd_soc_card *card, ret = snd_soc_dapm_sys_add(rtd->dev); if (ret < 0) dev_err(codec->dev, - "asoc: failed to add codec dapm sysfs entries: %d\n", - ret); + "ASoC: failed to add codec dapm sysfs entries: %d\n", ret); /* add codec sysfs entries */ ret = device_create_file(rtd->dev, &dev_attr_codec_reg); if (ret < 0) dev_err(codec->dev, - "asoc: failed to add codec sysfs files: %d\n", ret); + "ASoC: failed to add codec sysfs files: %d\n", ret); #ifdef CONFIG_DEBUG_FS /* add DPCM sysfs entries */ @@ -1278,7 +1280,7 @@ static int soc_post_component_init(struct snd_soc_card *card, ret = soc_dpcm_debugfs_add(rtd); if (ret < 0) - dev_err(rtd->dev, "asoc: failed to add dpcm sysfs entries: %d\n", ret); + dev_err(rtd->dev, "ASoC: failed to add dpcm sysfs entries: %d\n", ret); out: #endif @@ -1333,7 +1335,7 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) struct snd_soc_dapm_widget *play_w, *capture_w; int ret; - dev_dbg(card->dev, "probe %s dai link %d late %d\n", + dev_dbg(card->dev, "ASoC: probe %s dai link %d late %d\n", card->name, num, order); /* config components */ @@ -1359,8 +1361,9 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) if (cpu_dai->driver->probe) { ret = cpu_dai->driver->probe(cpu_dai); if (ret < 0) { - pr_err("asoc: failed to probe CPU DAI %s: %d\n", - cpu_dai->name, ret); + dev_err(cpu_dai->dev, + "ASoC: failed to probe CPU DAI %s: %d\n", + cpu_dai->name, ret); module_put(cpu_dai->dev->driver->owner); return ret; } @@ -1375,8 +1378,9 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) if (codec_dai->driver->probe) { ret = codec_dai->driver->probe(codec_dai); if (ret < 0) { - pr_err("asoc: failed to probe CODEC DAI %s: %d\n", - codec_dai->name, ret); + dev_err(codec_dai->dev, + "ASoC: failed to probe CODEC DAI %s: %d\n", + codec_dai->name, ret); return ret; } } @@ -1396,13 +1400,14 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) ret = device_create_file(rtd->dev, &dev_attr_pmdown_time); if (ret < 0) - pr_warn("asoc: failed to add pmdown_time sysfs:%d\n", ret); + dev_warn(rtd->dev, "ASoC: failed to add pmdown_time sysfs: %d\n", + ret); if (cpu_dai->driver->compress_dai) { /*create compress_device"*/ ret = soc_new_compress(rtd, num); if (ret < 0) { - pr_err("asoc: can't create compress %s\n", + dev_err(card->dev, "ASoC: can't create compress %s\n", dai_link->stream_name); return ret; } @@ -1412,7 +1417,7 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) /* create the pcm */ ret = soc_new_pcm(rtd, num); if (ret < 0) { - pr_err("asoc: can't create pcm %s :%d\n", + dev_err(card->dev, "ASoC: can't create pcm %s :%d\n", dai_link->stream_name, ret); return ret; } @@ -1424,7 +1429,7 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) ret = snd_soc_dapm_new_pcm(card, dai_link->params, capture_w, play_w); if (ret != 0) { - dev_err(card->dev, "Can't link %s to %s: %d\n", + dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", play_w->name, capture_w->name, ret); return ret; } @@ -1436,7 +1441,7 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) ret = snd_soc_dapm_new_pcm(card, dai_link->params, capture_w, play_w); if (ret != 0) { - dev_err(card->dev, "Can't link %s to %s: %d\n", + dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", play_w->name, capture_w->name, ret); return ret; } @@ -1473,7 +1478,8 @@ static int soc_register_ac97_dai_link(struct snd_soc_pcm_runtime *rtd) ret = soc_ac97_dev_register(rtd->codec); if (ret < 0) { - pr_err("asoc: AC97 device register failed:%d\n", ret); + dev_err(rtd->codec->dev, + "ASoC: AC97 device register failed: %d\n", ret); return ret; } @@ -1502,7 +1508,7 @@ static int soc_check_aux_dev(struct snd_soc_card *card, int num) return 0; } - dev_err(card->dev, "%s not registered\n", aux_dev->codec_name); + dev_err(card->dev, "ASoC: %s not registered\n", aux_dev->codec_name); return -EPROBE_DEFER; } @@ -1518,7 +1524,7 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num) if (!strcmp(codec->name, aux_dev->codec_name)) { if (codec->probed) { dev_err(codec->dev, - "asoc: codec already probed"); + "ASoC: codec already probed"); ret = -EBUSY; goto out; } @@ -1526,7 +1532,7 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num) } } /* codec not found */ - dev_err(card->dev, "asoc: codec %s not found", aux_dev->codec_name); + dev_err(card->dev, "ASoC: codec %s not found", aux_dev->codec_name); return -EPROBE_DEFER; found: @@ -1569,8 +1575,8 @@ static int snd_soc_init_codec_cache(struct snd_soc_codec *codec, codec->compress_type = compress_type; ret = snd_soc_cache_init(codec); if (ret < 0) { - dev_err(codec->dev, "Failed to set cache compression type: %d\n", - ret); + dev_err(codec->dev, "ASoC: Failed to set cache compression" + " type: %d\n", ret); return ret; } codec->cache_init = 1; @@ -1626,8 +1632,8 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, card->owner, 0, &card->snd_card); if (ret < 0) { - pr_err("asoc: can't create sound card for card %s: %d\n", - card->name, ret); + dev_err(card->dev, "ASoC: can't create sound card for" + " card %s: %d\n", card->name, ret); goto base_error; } card->snd_card->dev = card->dev; @@ -1663,8 +1669,9 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) for (i = 0; i < card->num_links; i++) { ret = soc_probe_link_components(card, i, order); if (ret < 0) { - pr_err("asoc: failed to instantiate card %s: %d\n", - card->name, ret); + dev_err(card->dev, + "ASoC: failed to instantiate card %d\n", + ret); goto probe_dai_err; } } @@ -1676,8 +1683,9 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) for (i = 0; i < card->num_links; i++) { ret = soc_probe_link_dais(card, i, order); if (ret < 0) { - pr_err("asoc: failed to instantiate card %s: %d\n", - card->name, ret); + dev_err(card->dev, + "ASoC: failed to instantiate card %d\n", + ret); goto probe_dai_err; } } @@ -1686,8 +1694,9 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) for (i = 0; i < card->num_aux_devs; i++) { ret = soc_probe_aux_dev(card, i); if (ret < 0) { - pr_err("asoc: failed to add auxiliary devices %s: %d\n", - card->name, ret); + dev_err(card->dev, + "ASoC: failed to add auxiliary devices %d\n", + ret); goto probe_aux_dev_err; } } @@ -1712,7 +1721,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) dai_fmt); if (ret != 0 && ret != -ENOTSUPP) dev_warn(card->rtd[i].codec_dai->dev, - "Failed to set DAI format: %d\n", + "ASoC: Failed to set DAI format: %d\n", ret); } @@ -1723,7 +1732,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) dai_fmt); if (ret != 0 && ret != -ENOTSUPP) dev_warn(card->rtd[i].cpu_dai->dev, - "Failed to set DAI format: %d\n", + "ASoC: Failed to set DAI format: %d\n", ret); } else if (dai_fmt) { /* Flip the polarity for the "CPU" end */ @@ -1748,7 +1757,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) dai_fmt); if (ret != 0 && ret != -ENOTSUPP) dev_warn(card->rtd[i].cpu_dai->dev, - "Failed to set DAI format: %d\n", + "ASoC: Failed to set DAI format: %d\n", ret); } } @@ -1775,7 +1784,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) if (card->late_probe) { ret = card->late_probe(card); if (ret < 0) { - dev_err(card->dev, "%s late_probe() failed: %d\n", + dev_err(card->dev, "ASoC: %s late_probe() failed: %d\n", card->name, ret); goto probe_aux_dev_err; } @@ -1789,8 +1798,8 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) ret = snd_card_register(card->snd_card); if (ret < 0) { - pr_err("asoc: failed to register soundcard for %s: %d\n", - card->name, ret); + dev_err(card->dev, "ASoC: failed to register soundcard %d\n", + ret); goto probe_aux_dev_err; } @@ -1799,8 +1808,8 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) for (i = 0; i < card->num_rtd; i++) { ret = soc_register_ac97_dai_link(&card->rtd[i]); if (ret < 0) { - pr_err("asoc: failed to register AC97 %s: %d\n", - card->name, ret); + dev_err(card->dev, "ASoC: failed to register AC97:" + " %d\n", ret); while (--i >= 0) soc_unregister_ac97_dai_link(card->rtd[i].codec); goto probe_aux_dev_err; @@ -1846,7 +1855,7 @@ static int soc_probe(struct platform_device *pdev) return -EINVAL; dev_warn(&pdev->dev, - "ASoC machine %s should use snd_soc_register_card()\n", + "ASoC: machine %s should use snd_soc_register_card()\n", card->name); /* Bodge while we unpick instantiation */ @@ -1996,7 +2005,7 @@ int snd_soc_platform_read(struct snd_soc_platform *platform, unsigned int ret; if (!platform->driver->read) { - dev_err(platform->dev, "platform has no read back\n"); + dev_err(platform->dev, "ASoC: platform has no read back\n"); return -1; } @@ -2012,7 +2021,7 @@ int snd_soc_platform_write(struct snd_soc_platform *platform, unsigned int reg, unsigned int val) { if (!platform->driver->write) { - dev_err(platform->dev, "platform has no write back\n"); + dev_err(platform->dev, "ASoC: platform has no write back\n"); return -1; } @@ -2283,7 +2292,8 @@ static int snd_soc_add_controls(struct snd_card *card, struct device *dev, err = snd_ctl_add(card, snd_soc_cnew(control, data, control->name, prefix)); if (err < 0) { - dev_err(dev, "Failed to add %s: %d\n", control->name, err); + dev_err(dev, "ASoC: Failed to add %s: %d\n", + control->name, err); return err; } } @@ -3534,15 +3544,14 @@ int snd_soc_register_card(struct snd_soc_card *card) * not both or neither. */ if (!!link->codec_name == !!link->codec_of_node) { - dev_err(card->dev, - "Neither/both codec name/of_node are set for %s\n", - link->name); + dev_err(card->dev, "ASoC: Neither/both codec" + " name/of_node are set for %s\n", link->name); return -EINVAL; } /* Codec DAI name must be specified */ if (!link->codec_dai_name) { - dev_err(card->dev, "codec_dai_name not set for %s\n", - link->name); + dev_err(card->dev, "ASoC: codec_dai_name not" + " set for %s\n", link->name); return -EINVAL; } @@ -3551,8 +3560,8 @@ int snd_soc_register_card(struct snd_soc_card *card) * can be left unspecified, and a dummy platform will be used. */ if (link->platform_name && link->platform_of_node) { - dev_err(card->dev, - "Both platform name/of_node are set for %s\n", link->name); + dev_err(card->dev, "ASoC: Both platform name/of_node" + " are set for %s\n", link->name); return -EINVAL; } @@ -3562,9 +3571,8 @@ int snd_soc_register_card(struct snd_soc_card *card) * name alone.. */ if (link->cpu_name && link->cpu_of_node) { - dev_err(card->dev, - "Neither/both cpu name/of_node are set for %s\n", - link->name); + dev_err(card->dev, "ASoC: Neither/both " + "cpu name/of_node are set for %s\n",link->name); return -EINVAL; } /* @@ -3573,9 +3581,8 @@ int snd_soc_register_card(struct snd_soc_card *card) */ if (!link->cpu_dai_name && !(link->cpu_name || link->cpu_of_node)) { - dev_err(card->dev, - "Neither cpu_dai_name nor cpu_name/of_node are set for %s\n", - link->name); + dev_err(card->dev, "ASoC: Neither cpu_dai_name nor " + "cpu_name/of_node are set for %s\n", link->name); return -EINVAL; } } @@ -3622,7 +3629,7 @@ int snd_soc_unregister_card(struct snd_soc_card *card) { if (card->instantiated) soc_cleanup_card_resources(card); - dev_dbg(card->dev, "Unregistered card '%s'\n", card->name); + dev_dbg(card->dev, "ASoC: Unregistered card '%s'\n", card->name); return 0; } @@ -3679,8 +3686,8 @@ static inline char *fmt_multiple_name(struct device *dev, struct snd_soc_dai_driver *dai_drv) { if (dai_drv->name == NULL) { - pr_err("asoc: error - multiple DAI %s registered with no name\n", - dev_name(dev)); + dev_err(dev, "ASoC: error - multiple DAI %s registered with" + " no name\n", dev_name(dev)); return NULL; } @@ -3698,7 +3705,7 @@ int snd_soc_register_dai(struct device *dev, struct snd_soc_codec *codec; struct snd_soc_dai *dai; - dev_dbg(dev, "dai register %s\n", dev_name(dev)); + dev_dbg(dev, "ASoC: dai register %s\n", dev_name(dev)); dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL); if (dai == NULL) @@ -3721,7 +3728,7 @@ int snd_soc_register_dai(struct device *dev, list_for_each_entry(codec, &codec_list, list) { if (codec->dev == dev) { - dev_dbg(dev, "Mapped DAI %s to CODEC %s\n", + dev_dbg(dev, "ASoC: Mapped DAI %s to CODEC %s\n", dai->name, codec->name); dai->codec = codec; break; @@ -3735,7 +3742,7 @@ int snd_soc_register_dai(struct device *dev, mutex_unlock(&client_mutex); - pr_debug("Registered DAI '%s'\n", dai->name); + dev_dbg(dev, "ASoC: Registered DAI '%s'\n", dai->name); return 0; } @@ -3761,7 +3768,7 @@ found: list_del(&dai->list); mutex_unlock(&client_mutex); - pr_debug("Unregistered DAI '%s'\n", dai->name); + dev_dbg(dev, "ASoC: Unregistered DAI '%s'\n", dai->name); kfree(dai->name); kfree(dai); } @@ -3780,7 +3787,7 @@ int snd_soc_register_dais(struct device *dev, struct snd_soc_dai *dai; int i, ret = 0; - dev_dbg(dev, "dai register %s #%Zu\n", dev_name(dev), count); + dev_dbg(dev, "ASoC: dai register %s #%Zu\n", dev_name(dev), count); for (i = 0; i < count; i++) { @@ -3812,8 +3819,8 @@ int snd_soc_register_dais(struct device *dev, list_for_each_entry(codec, &codec_list, list) { if (codec->dev == dev) { - dev_dbg(dev, "Mapped DAI %s to CODEC %s\n", - dai->name, codec->name); + dev_dbg(dev, "ASoC: Mapped DAI %s to " + "CODEC %s\n", dai->name, codec->name); dai->codec = codec; break; } @@ -3826,7 +3833,7 @@ int snd_soc_register_dais(struct device *dev, mutex_unlock(&client_mutex); - pr_debug("Registered DAI '%s'\n", dai->name); + dev_dbg(dai->dev, "ASoC: Registered DAI '%s'\n", dai->name); } return 0; @@ -3864,7 +3871,7 @@ int snd_soc_register_platform(struct device *dev, { struct snd_soc_platform *platform; - dev_dbg(dev, "platform register %s\n", dev_name(dev)); + dev_dbg(dev, "ASoC: platform register %s\n", dev_name(dev)); platform = kzalloc(sizeof(struct snd_soc_platform), GFP_KERNEL); if (platform == NULL) @@ -3888,7 +3895,7 @@ int snd_soc_register_platform(struct device *dev, list_add(&platform->list, &platform_list); mutex_unlock(&client_mutex); - pr_debug("Registered platform '%s'\n", platform->name); + dev_dbg(dev, "ASoC: Registered platform '%s'\n", platform->name); return 0; } @@ -3914,7 +3921,7 @@ found: list_del(&platform->list); mutex_unlock(&client_mutex); - pr_debug("Unregistered platform '%s'\n", platform->name); + dev_dbg(dev, "ASoC: Unregistered platform '%s'\n", platform->name); kfree(platform->name); kfree(platform); } @@ -4007,7 +4014,7 @@ int snd_soc_register_codec(struct device *dev, codec->reg_size = reg_size; /* it is necessary to make a copy of the default register cache * because in the case of using a compression type that requires - * the default register cache to be marked as __devinitconst the + * the default register cache to be marked as the * kernel might have freed the array by the time we initialize * the cache. */ @@ -4043,11 +4050,11 @@ int snd_soc_register_codec(struct device *dev, if (num_dai) { ret = snd_soc_register_dais(dev, dai_drv, num_dai); if (ret < 0) - dev_err(codec->dev, "Failed to regster DAIs: %d\n", - ret); + dev_err(codec->dev, "ASoC: Failed to regster" + " DAIs: %d\n", ret); } - pr_debug("Registered codec '%s'\n", codec->name); + dev_dbg(codec->dev, "ASoC: Registered codec '%s'\n", codec->name); return 0; fail: @@ -4082,7 +4089,7 @@ found: list_del(&codec->list); mutex_unlock(&client_mutex); - pr_debug("Unregistered codec '%s'\n", codec->name); + dev_dbg(codec->dev, "ASoC: Unregistered codec '%s'\n", codec->name); snd_soc_cache_exit(codec); kfree(codec->reg_def_copy); @@ -4106,7 +4113,7 @@ int snd_soc_of_parse_card_name(struct snd_soc_card *card, */ if (ret < 0 && ret != -EINVAL) { dev_err(card->dev, - "Property '%s' could not be read: %d\n", + "ASoC: Property '%s' could not be read: %d\n", propname, ret); return ret; } @@ -4125,15 +4132,13 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, num_routes = of_property_count_strings(np, propname); if (num_routes < 0 || num_routes & 1) { - dev_err(card->dev, - "Property '%s' does not exist or its length is not even\n", - propname); + dev_err(card->dev, "ASoC: Property '%s' does not exist or its" + " length is not even\n", propname); return -EINVAL; } num_routes /= 2; if (!num_routes) { - dev_err(card->dev, - "Property '%s's length is zero\n", + dev_err(card->dev, "ASoC: Property '%s's length is zero\n", propname); return -EINVAL; } @@ -4142,7 +4147,7 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, GFP_KERNEL); if (!routes) { dev_err(card->dev, - "Could not allocate DAPM route table\n"); + "ASoC: Could not allocate DAPM route table\n"); return -EINVAL; } @@ -4150,9 +4155,9 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, ret = of_property_read_string_index(np, propname, 2 * i, &routes[i].sink); if (ret) { - dev_err(card->dev, - "Property '%s' index %d could not be read: %d\n", - propname, 2 * i, ret); + dev_err(card->dev, "ASoC: Property '%s' index %d" + " could not be read: %d\n", propname, 2 * i, + ret); kfree(routes); return -EINVAL; } @@ -4160,8 +4165,8 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, (2 * i) + 1, &routes[i].source); if (ret) { dev_err(card->dev, - "Property '%s' index %d could not be read: %d\n", - propname, (2 * i) + 1, ret); + "ASoC: Property '%s' index %d could not be" + " read: %d\n", propname, (2 * i) + 1, ret); kfree(routes); return -EINVAL; } diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 6e35bcae02d..1e36bc81e5a 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) else if (w->platform) return snd_soc_platform_read(w->platform, reg); - dev_err(w->dapm->dev, "no valid widget read method\n"); + dev_err(w->dapm->dev, "ASoC: no valid widget read method\n"); return -1; } @@ -231,7 +231,7 @@ static int soc_widget_write(struct snd_soc_dapm_widget *w, int reg, int val) else if (w->platform) return snd_soc_platform_write(w->platform, reg, val); - dev_err(w->dapm->dev, "no valid widget write method\n"); + dev_err(w->dapm->dev, "ASoC: no valid widget write method\n"); return -1; } @@ -546,7 +546,7 @@ static int dapm_new_mixer(struct snd_soc_dapm_widget *w) wlist = kzalloc(wlistsize, GFP_KERNEL); if (wlist == NULL) { dev_err(dapm->dev, - "asoc: can't allocate widget list for %s\n", + "ASoC: can't allocate widget list for %s\n", w->name); return -ENOMEM; } @@ -595,9 +595,9 @@ static int dapm_new_mixer(struct snd_soc_dapm_widget *w) prefix); ret = snd_ctl_add(card, path->kcontrol); if (ret < 0) { - dev_err(dapm->dev, - "asoc: failed to add dapm kcontrol %s: %d\n", - path->long_name, ret); + dev_err(dapm->dev, "ASoC: failed to add widget" + " %s dapm kcontrol %s: %d\n", + w->name, path->long_name, ret); kfree(wlist); kfree(path->long_name); path->long_name = NULL; @@ -626,7 +626,7 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w) if (w->num_kcontrols != 1) { dev_err(dapm->dev, - "asoc: mux %s has incorrect number of controls\n", + "ASoC: mux %s has incorrect number of controls\n", w->name); return -EINVAL; } @@ -645,7 +645,7 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w) wlist = krealloc(wlist, wlistsize, GFP_KERNEL); if (wlist == NULL) { dev_err(dapm->dev, - "asoc: can't allocate widget list for %s\n", w->name); + "ASoC: can't allocate widget list for %s\n", w->name); return -ENOMEM; } wlist->num_widgets = wlistentries; @@ -677,7 +677,7 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w) name + prefix_len, prefix); ret = snd_ctl_add(card, kcontrol); if (ret < 0) { - dev_err(dapm->dev, "failed to add kcontrol %s: %d\n", + dev_err(dapm->dev, "ASoC: failed to add kcontrol %s: %d\n", w->name, ret); kfree(wlist); return ret; @@ -699,7 +699,7 @@ static int dapm_new_pga(struct snd_soc_dapm_widget *w) { if (w->num_kcontrols) dev_err(w->dapm->dev, - "asoc: PGA controls not supported: '%s'\n", w->name); + "ASoC: PGA controls not supported: '%s'\n", w->name); return 0; } @@ -725,7 +725,7 @@ static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget) case SNDRV_CTL_POWER_D3hot: case SNDRV_CTL_POWER_D3cold: if (widget->ignore_suspend) - dev_dbg(widget->dapm->dev, "%s ignoring suspend\n", + dev_dbg(widget->dapm->dev, "ASoC: %s ignoring suspend\n", widget->name); return widget->ignore_suspend; default: @@ -757,14 +757,14 @@ static int dapm_list_add_widget(struct snd_soc_dapm_widget_list **list, wlistentries * sizeof(struct snd_soc_dapm_widget *); *list = krealloc(wlist, wlistsize, GFP_KERNEL); if (*list == NULL) { - dev_err(w->dapm->dev, "can't allocate widget list for %s\n", + dev_err(w->dapm->dev, "ASoC: can't allocate widget list for %s\n", w->name); return -ENOMEM; } wlist = *list; /* insert the widget */ - dev_dbg(w->dapm->dev, "added %s in widget list pos %d\n", + dev_dbg(w->dapm->dev, "ASoC: added %s in widget list pos %d\n", w->name, wlist->num_widgets); wlist->widgets[wlist->num_widgets] = w; @@ -844,7 +844,8 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget, int err; err = dapm_list_add_widget(list, path->sink); if (err < 0) { - dev_err(widget->dapm->dev, "could not add widget %s\n", + dev_err(widget->dapm->dev, + "ASoC: could not add widget %s\n", widget->name); return con; } @@ -943,7 +944,8 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget, int err; err = dapm_list_add_widget(list, path->source); if (err < 0) { - dev_err(widget->dapm->dev, "could not add widget %s\n", + dev_err(widget->dapm->dev, + "ASoC: could not add widget %s\n", widget->name); return con; } @@ -1024,7 +1026,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w, ret = regulator_allow_bypass(w->regulator, true); if (ret != 0) dev_warn(w->dapm->dev, - "Failed to bypass %s: %d\n", + "ASoC: Failed to bypass %s: %d\n", w->name, ret); } @@ -1034,7 +1036,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w, ret = regulator_allow_bypass(w->regulator, false); if (ret != 0) dev_warn(w->dapm->dev, - "Failed to unbypass %s: %d\n", + "ASoC: Failed to unbypass %s: %d\n", w->name, ret); } @@ -1253,7 +1255,7 @@ static void dapm_seq_check_event(struct snd_soc_dapm_context *dapm, ret = w->event(w, NULL, event); trace_snd_soc_dapm_widget_event_done(w, event); if (ret < 0) - pr_err("%s: %s event failed: %d\n", + dev_err(dapm->dev, "ASoC: %s: %s event failed: %d\n", ev_name, w->name, ret); } } @@ -1402,7 +1404,7 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm, if (ret < 0) dev_err(w->dapm->dev, - "Failed to apply widget power: %d\n", ret); + "ASoC: Failed to apply widget power: %d\n", ret); } if (!list_empty(&pending)) @@ -1431,20 +1433,21 @@ static void dapm_widget_update(struct snd_soc_dapm_context *dapm) (w->event_flags & SND_SOC_DAPM_PRE_REG)) { ret = w->event(w, update->kcontrol, SND_SOC_DAPM_PRE_REG); if (ret != 0) - pr_err("%s DAPM pre-event failed: %d\n", + dev_err(dapm->dev, "ASoC: %s DAPM pre-event failed: %d\n", w->name, ret); } ret = soc_widget_update_bits_locked(w, update->reg, update->mask, update->val); if (ret < 0) - pr_err("%s DAPM update failed: %d\n", w->name, ret); + dev_err(dapm->dev, "ASoC: %s DAPM update failed: %d\n", + w->name, ret); if (w->event && (w->event_flags & SND_SOC_DAPM_POST_REG)) { ret = w->event(w, update->kcontrol, SND_SOC_DAPM_POST_REG); if (ret != 0) - pr_err("%s DAPM post-event failed: %d\n", + dev_err(dapm->dev, "ASoC: %s DAPM post-event failed: %d\n", w->name, ret); } } @@ -1466,7 +1469,7 @@ static void dapm_pre_sequence_async(void *data, async_cookie_t cookie) ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY); if (ret != 0) dev_err(d->dev, - "Failed to turn on bias: %d\n", ret); + "ASoC: Failed to turn on bias: %d\n", ret); } /* 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) ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_PREPARE); if (ret != 0) dev_err(d->dev, - "Failed to prepare bias: %d\n", ret); + "ASoC: Failed to prepare bias: %d\n", ret); } } @@ -1492,7 +1495,7 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie) d->target_bias_level == SND_SOC_BIAS_OFF)) { ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY); if (ret != 0) - dev_err(d->dev, "Failed to apply standby bias: %d\n", + dev_err(d->dev, "ASoC: Failed to apply standby bias: %d\n", ret); } @@ -1501,7 +1504,8 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie) d->target_bias_level == SND_SOC_BIAS_OFF) { ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_OFF); if (ret != 0) - dev_err(d->dev, "Failed to turn off bias: %d\n", ret); + dev_err(d->dev, "ASoC: Failed to turn off bias: %d\n", + ret); if (d->dev) pm_runtime_put(d->dev); @@ -1512,7 +1516,7 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie) d->target_bias_level == SND_SOC_BIAS_ON) { ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_ON); if (ret != 0) - dev_err(d->dev, "Failed to apply active bias: %d\n", + dev_err(d->dev, "ASoC: Failed to apply active bias: %d\n", ret); } } @@ -1838,7 +1842,7 @@ void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm, if (!dapm->debugfs_dapm) { dev_warn(dapm->dev, - "Failed to create DAPM debugfs directory\n"); + "ASoC: Failed to create DAPM debugfs directory\n"); return; } @@ -2123,7 +2127,7 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); if (!w) { - dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); + dev_err(dapm->dev, "ASoC: DAPM unknown pin %s\n", pin); return -EINVAL; } @@ -2212,8 +2216,16 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, if (!wsource) wsource = wtsource; - if (wsource == NULL || wsink == NULL) + if (wsource == NULL) { + dev_err(dapm->dev, "ASoC: no source widget found for %s\n", + route->source); return -ENODEV; + } + if (wsink == NULL) { + dev_err(dapm->dev, "ASoC: no sink widget found for %s\n", + route->sink); + return -ENODEV; + } path = kzalloc(sizeof(struct snd_soc_dapm_path), GFP_KERNEL); if (!path) @@ -2308,7 +2320,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, return 0; err: - dev_warn(dapm->dev, "asoc: no dapm match for %s --> %s --> %s\n", + dev_warn(dapm->dev, "ASoC: no dapm match for %s --> %s --> %s\n", source, control, sink); kfree(path); return ret; @@ -2325,7 +2337,7 @@ static int snd_soc_dapm_del_route(struct snd_soc_dapm_context *dapm, if (route->control) { dev_err(dapm->dev, - "Removal of routes with controls not supported\n"); + "ASoC: Removal of routes with controls not supported\n"); return -EINVAL; } @@ -2360,7 +2372,7 @@ static int snd_soc_dapm_del_route(struct snd_soc_dapm_context *dapm, list_del(&path->list_source); kfree(path); } else { - dev_warn(dapm->dev, "Route %s->%s does not exist\n", + dev_warn(dapm->dev, "ASoC: Route %s->%s does not exist\n", source, sink); } @@ -2389,8 +2401,10 @@ int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, for (i = 0; i < num; i++) { r = snd_soc_dapm_add_route(dapm, route); if (r < 0) { - dev_err(dapm->dev, "Failed to add route %s->%s\n", - route->source, route->sink); + dev_err(dapm->dev, "ASoC: Failed to add route %s -> %s -> %s\n", + route->source, + route->control ? route->control : "direct", + route->sink); ret = r; } route++; @@ -2438,19 +2452,19 @@ static int snd_soc_dapm_weak_route(struct snd_soc_dapm_context *dapm, int count = 0; if (!source) { - dev_err(dapm->dev, "Unable to find source %s for weak route\n", + dev_err(dapm->dev, "ASoC: Unable to find source %s for weak route\n", route->source); return -ENODEV; } if (!sink) { - dev_err(dapm->dev, "Unable to find sink %s for weak route\n", + dev_err(dapm->dev, "ASoC: Unable to find sink %s for weak route\n", route->sink); return -ENODEV; } if (route->control || route->connected) - dev_warn(dapm->dev, "Ignoring control for weak route %s->%s\n", + dev_warn(dapm->dev, "ASoC: Ignoring control for weak route %s->%s\n", route->source, route->sink); 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, } if (count == 0) - dev_err(dapm->dev, "No path found for weak route %s->%s\n", + dev_err(dapm->dev, "ASoC: No path found for weak route %s->%s\n", route->source, route->sink); if (count > 1) - dev_warn(dapm->dev, "%d paths found for weak route %s->%s\n", + dev_warn(dapm->dev, "ASoC: %d paths found for weak route %s->%s\n", count, route->source, route->sink); return 0; @@ -2601,7 +2615,7 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, if (snd_soc_volsw_is_stereo(mc)) dev_warn(widget->dapm->dev, - "Control '%s' is stereo, which is not supported\n", + "ASoC: Control '%s' is stereo, which is not supported\n", kcontrol->id.name); ucontrol->value.integer.value[0] = @@ -2644,7 +2658,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, if (snd_soc_volsw_is_stereo(mc)) dev_warn(widget->dapm->dev, - "Control '%s' is stereo, which is not supported\n", + "ASoC: Control '%s' is stereo, which is not supported\n", kcontrol->id.name); val = (ucontrol->value.integer.value[0] & mask); @@ -3021,7 +3035,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, w->regulator = devm_regulator_get(dapm->dev, w->name); if (IS_ERR(w->regulator)) { ret = PTR_ERR(w->regulator); - dev_err(dapm->dev, "Failed to request %s: %d\n", + dev_err(dapm->dev, "ASoC: Failed to request %s: %d\n", w->name, ret); return NULL; } @@ -3031,7 +3045,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, w->clk = devm_clk_get(dapm->dev, w->name); if (IS_ERR(w->clk)) { ret = PTR_ERR(w->clk); - dev_err(dapm->dev, "Failed to request %s: %d\n", + dev_err(dapm->dev, "ASoC: Failed to request %s: %d\n", w->name, ret); return NULL; } @@ -3182,7 +3196,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w, if (config->formats) { fmt = ffs(config->formats) - 1; } else { - dev_warn(w->dapm->dev, "Invalid format %llx specified\n", + dev_warn(w->dapm->dev, "ASoC: Invalid format %llx specified\n", config->formats); fmt = 0; } @@ -3215,7 +3229,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w, params, source); if (ret != 0) { dev_err(source->dev, - "hw_params() failed: %d\n", ret); + "ASoC: hw_params() failed: %d\n", ret); goto out; } } @@ -3226,7 +3240,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w, sink); if (ret != 0) { dev_err(sink->dev, - "hw_params() failed: %d\n", ret); + "ASoC: hw_params() failed: %d\n", ret); goto out; } } @@ -3235,14 +3249,14 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMU: ret = snd_soc_dai_digital_mute(sink, 0); if (ret != 0 && ret != -ENOTSUPP) - dev_warn(sink->dev, "Failed to unmute: %d\n", ret); + dev_warn(sink->dev, "ASoC: Failed to unmute: %d\n", ret); ret = 0; break; case SND_SOC_DAPM_PRE_PMD: ret = snd_soc_dai_digital_mute(sink, 1); if (ret != 0 && ret != -ENOTSUPP) - dev_warn(sink->dev, "Failed to mute: %d\n", ret); + dev_warn(sink->dev, "ASoC: Failed to mute: %d\n", ret); ret = 0; break; @@ -3281,11 +3295,11 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card, template.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD; - dev_dbg(card->dev, "adding %s widget\n", link_name); + dev_dbg(card->dev, "ASoC: adding %s widget\n", link_name); w = snd_soc_dapm_new_control(&card->dapm, &template); if (!w) { - dev_err(card->dev, "Failed to create %s widget\n", + dev_err(card->dev, "ASoC: Failed to create %s widget\n", link_name); return -ENOMEM; } @@ -3319,12 +3333,12 @@ int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, template.name = dai->driver->playback.stream_name; template.sname = dai->driver->playback.stream_name; - dev_dbg(dai->dev, "adding %s widget\n", + dev_dbg(dai->dev, "ASoC: adding %s widget\n", template.name); w = snd_soc_dapm_new_control(dapm, &template); if (!w) { - dev_err(dapm->dev, "Failed to create %s widget\n", + dev_err(dapm->dev, "ASoC: Failed to create %s widget\n", dai->driver->playback.stream_name); } @@ -3337,12 +3351,12 @@ int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, template.name = dai->driver->capture.stream_name; template.sname = dai->driver->capture.stream_name; - dev_dbg(dai->dev, "adding %s widget\n", + dev_dbg(dai->dev, "ASoC: adding %s widget\n", template.name); w = snd_soc_dapm_new_control(dapm, &template); if (!w) { - dev_err(dapm->dev, "Failed to create %s widget\n", + dev_err(dapm->dev, "ASoC: Failed to create %s widget\n", dai->driver->capture.stream_name); } @@ -3518,11 +3532,11 @@ int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); if (!w) { - dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); + dev_err(dapm->dev, "ASoC: unknown pin %s\n", pin); return -EINVAL; } - dev_dbg(w->dapm->dev, "dapm: force enable pin %s\n", pin); + dev_dbg(w->dapm->dev, "ASoC: force enable pin %s\n", pin); w->connected = 1; w->force = 1; dapm_mark_dirty(w, "force enable"); @@ -3605,7 +3619,7 @@ int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, false); if (!w) { - dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); + dev_err(dapm->dev, "ASoC: unknown pin %s\n", pin); return -EINVAL; } @@ -3664,7 +3678,7 @@ void snd_soc_dapm_auto_nc_codec_pins(struct snd_soc_codec *codec) struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_dapm_widget *w; - dev_dbg(codec->dev, "Auto NC: DAPMs: card:%p codec:%p\n", + dev_dbg(codec->dev, "ASoC: Auto NC: DAPMs: card:%p codec:%p\n", &card->dapm, &codec->dapm); 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) case snd_soc_dapm_input: case snd_soc_dapm_output: case snd_soc_dapm_micbias: - dev_dbg(codec->dev, "Auto NC: Checking widget %s\n", + dev_dbg(codec->dev, "ASoC: Auto NC: Checking widget %s\n", w->name); if (!snd_soc_dapm_widget_in_card_paths(card, w)) { dev_dbg(codec->dev, diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c index bbc125748a3..111b7d921e8 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) return 0; } EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close); + +MODULE_LICENSE("GPL"); diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index 1ab5fe04bfc..0bb5cccd776 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) struct snd_soc_dapm_context *dapm; struct snd_soc_jack_pin *pin; int enable; - int oldstatus; trace_snd_soc_jack_report(jack, mask, status); @@ -78,8 +77,6 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) mutex_lock(&jack->mutex); - oldstatus = jack->status; - jack->status &= ~mask; jack->status |= status & mask; @@ -172,12 +169,13 @@ int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count, for (i = 0; i < count; i++) { if (!pins[i].pin) { - printk(KERN_ERR "No name for pin %d\n", i); + dev_err(jack->codec->dev, "ASoC: No name for pin %d\n", + i); return -EINVAL; } if (!pins[i].mask) { - printk(KERN_ERR "No mask for pin %d (%s)\n", i, - pins[i].pin); + dev_err(jack->codec->dev, "ASoC: No mask for pin %d" + " (%s)\n", i, pins[i].pin); return -EINVAL; } @@ -297,13 +295,13 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, for (i = 0; i < count; i++) { if (!gpio_is_valid(gpios[i].gpio)) { - printk(KERN_ERR "Invalid gpio %d\n", + dev_err(jack->codec->dev, "ASoC: Invalid gpio %d\n", gpios[i].gpio); ret = -EINVAL; goto undo; } if (!gpios[i].name) { - printk(KERN_ERR "No name for gpio %d\n", + dev_err(jack->codec->dev, "ASoC: No name for gpio %d\n", gpios[i].gpio); ret = -EINVAL; goto undo; @@ -332,7 +330,7 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, if (gpios[i].wake) { ret = irq_set_irq_wake(gpio_to_irq(gpios[i].gpio), 1); if (ret != 0) - printk(KERN_ERR + dev_err(jack->codec->dev, "ASoC: " "Failed to mark GPIO %d as wake source: %d\n", gpios[i].gpio, ret); } diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index ef22d0bd9e9..5c3ca2a3466 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, struct snd_soc_pcm_runtime *be = dpcm->be; - dev_dbg(be->dev, "pm: BE %s event %d dir %d\n", + dev_dbg(be->dev, "ASoC: BE %s event %d dir %d\n", be->dai_link->name, event, dir); snd_soc_dapm_stream_event(be, dir, event); @@ -70,18 +70,19 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream, */ if (!soc_dai->rate) { dev_warn(soc_dai->dev, - "Not enforcing symmetric_rates due to race\n"); + "ASoC: Not enforcing symmetric_rates due to race\n"); return 0; } - dev_dbg(soc_dai->dev, "Symmetry forces %dHz rate\n", soc_dai->rate); + dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %dHz rate\n", soc_dai->rate); ret = snd_pcm_hw_constraint_minmax(substream->runtime, SNDRV_PCM_HW_PARAM_RATE, soc_dai->rate, soc_dai->rate); if (ret < 0) { dev_err(soc_dai->dev, - "Unable to apply rate symmetry constraint: %d\n", ret); + "ASoC: Unable to apply rate symmetry constraint: %d\n", + ret); return ret; } @@ -118,7 +119,7 @@ static void soc_pcm_apply_msb(struct snd_pcm_substream *substream, sample_sizes[i], bits); if (ret != 0) dev_warn(dai->dev, - "Failed to set MSB %d/%d: %d\n", + "ASoC: Failed to set MSB %d/%d: %d\n", bits, sample_sizes[i], ret); } } @@ -149,8 +150,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) if (cpu_dai->driver->ops->startup) { ret = cpu_dai->driver->ops->startup(substream, cpu_dai); if (ret < 0) { - dev_err(cpu_dai->dev, "can't open interface %s: %d\n", - cpu_dai->name, ret); + dev_err(cpu_dai->dev, "ASoC: can't open interface" + " %s: %d\n", cpu_dai->name, ret); goto out; } } @@ -158,8 +159,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) if (platform->driver->ops && platform->driver->ops->open) { ret = platform->driver->ops->open(substream); if (ret < 0) { - dev_err(platform->dev, "can't open platform %s: %d\n", - platform->name, ret); + dev_err(platform->dev, "ASoC: can't open platform" + " %s: %d\n", platform->name, ret); goto platform_err; } } @@ -167,8 +168,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) if (codec_dai->driver->ops->startup) { ret = codec_dai->driver->ops->startup(substream, codec_dai); if (ret < 0) { - dev_err(codec_dai->dev, "can't open codec %s: %d\n", - codec_dai->name, ret); + dev_err(codec_dai->dev, "ASoC: can't open codec" + " %s: %d\n", codec_dai->name, ret); goto codec_dai_err; } } @@ -176,7 +177,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) if (rtd->dai_link->ops && rtd->dai_link->ops->startup) { ret = rtd->dai_link->ops->startup(substream); if (ret < 0) { - pr_err("asoc: %s startup failed: %d\n", + pr_err("ASoC: %s startup failed: %d\n", rtd->dai_link->name, ret); goto machine_err; } @@ -238,18 +239,18 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) ret = -EINVAL; snd_pcm_limit_hw_rates(runtime); if (!runtime->hw.rates) { - printk(KERN_ERR "asoc: %s <-> %s No matching rates\n", + printk(KERN_ERR "ASoC: %s <-> %s No matching rates\n", codec_dai->name, cpu_dai->name); goto config_err; } if (!runtime->hw.formats) { - printk(KERN_ERR "asoc: %s <-> %s No matching formats\n", + printk(KERN_ERR "ASoC: %s <-> %s No matching formats\n", codec_dai->name, cpu_dai->name); goto config_err; } if (!runtime->hw.channels_min || !runtime->hw.channels_max || runtime->hw.channels_min > runtime->hw.channels_max) { - printk(KERN_ERR "asoc: %s <-> %s No matching channels\n", + printk(KERN_ERR "ASoC: %s <-> %s No matching channels\n", codec_dai->name, cpu_dai->name); goto config_err; } @@ -270,12 +271,12 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) goto config_err; } - pr_debug("asoc: %s <-> %s info:\n", + pr_debug("ASoC: %s <-> %s info:\n", codec_dai->name, cpu_dai->name); - pr_debug("asoc: rate mask 0x%x\n", runtime->hw.rates); - pr_debug("asoc: min ch %d max ch %d\n", runtime->hw.channels_min, + pr_debug("ASoC: rate mask 0x%x\n", runtime->hw.rates); + pr_debug("ASoC: min ch %d max ch %d\n", runtime->hw.channels_min, runtime->hw.channels_max); - pr_debug("asoc: min rate %d max rate %d\n", runtime->hw.rate_min, + pr_debug("ASoC: min rate %d max rate %d\n", runtime->hw.rate_min, runtime->hw.rate_max); dynamic: @@ -330,7 +331,7 @@ static void close_delayed_work(struct work_struct *work) mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); - pr_debug("pop wq checking: %s status: %s waiting: %s\n", + dev_dbg(rtd->dev, "ASoC: pop wq checking: %s status: %s waiting: %s\n", codec_dai->driver->playback.stream_name, codec_dai->playback_active ? "active" : "inactive", codec_dai->pop_wait ? "yes" : "no"); @@ -444,7 +445,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) if (rtd->dai_link->ops && rtd->dai_link->ops->prepare) { ret = rtd->dai_link->ops->prepare(substream); if (ret < 0) { - pr_err("asoc: machine prepare error: %d\n", ret); + dev_err(rtd->card->dev, "ASoC: machine prepare error:" + " %d\n", ret); goto out; } } @@ -452,8 +454,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) if (platform->driver->ops && platform->driver->ops->prepare) { ret = platform->driver->ops->prepare(substream); if (ret < 0) { - dev_err(platform->dev, "platform prepare error: %d\n", - ret); + dev_err(platform->dev, "ASoC: platform prepare error:" + " %d\n", ret); goto out; } } @@ -461,7 +463,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) if (codec_dai->driver->ops->prepare) { ret = codec_dai->driver->ops->prepare(substream, codec_dai); if (ret < 0) { - dev_err(codec_dai->dev, "DAI prepare error: %d\n", + dev_err(codec_dai->dev, "ASoC: DAI prepare error: %d\n", ret); goto out; } @@ -470,7 +472,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) if (cpu_dai->driver->ops->prepare) { ret = cpu_dai->driver->ops->prepare(substream, cpu_dai); if (ret < 0) { - dev_err(cpu_dai->dev, "DAI prepare error: %d\n", + dev_err(cpu_dai->dev, "ASoC: DAI prepare error: %d\n", ret); goto out; } @@ -512,7 +514,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, if (rtd->dai_link->ops && rtd->dai_link->ops->hw_params) { ret = rtd->dai_link->ops->hw_params(substream, params); if (ret < 0) { - pr_err("asoc: machine hw_params failed: %d\n", ret); + dev_err(rtd->card->dev, "ASoC: machine hw_params" + " failed: %d\n", ret); goto out; } } @@ -520,8 +523,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, if (codec_dai->driver->ops->hw_params) { ret = codec_dai->driver->ops->hw_params(substream, params, codec_dai); if (ret < 0) { - dev_err(codec_dai->dev, "can't set %s hw params: %d\n", - codec_dai->name, ret); + dev_err(codec_dai->dev, "ASoC: can't set %s hw params:" + " %d\n", codec_dai->name, ret); goto codec_err; } } @@ -529,7 +532,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, if (cpu_dai->driver->ops->hw_params) { ret = cpu_dai->driver->ops->hw_params(substream, params, cpu_dai); if (ret < 0) { - dev_err(cpu_dai->dev, "%s hw params failed: %d\n", + dev_err(cpu_dai->dev, "ASoC: %s hw params failed: %d\n", cpu_dai->name, ret); goto interface_err; } @@ -538,7 +541,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, if (platform->driver->ops && platform->driver->ops->hw_params) { ret = platform->driver->ops->hw_params(substream, params); if (ret < 0) { - dev_err(platform->dev, "%s hw params failed: %d\n", + dev_err(platform->dev, "ASoC: %s hw params failed: %d\n", platform->name, ret); goto platform_err; } @@ -760,7 +763,7 @@ static void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream) struct snd_soc_dpcm *dpcm, *d; list_for_each_entry_safe(dpcm, d, &fe->dpcm[stream].be_clients, list_be) { - dev_dbg(fe->dev, "BE %s disconnect check for %s\n", + dev_dbg(fe->dev, "ASoC: BE %s disconnect check for %s\n", stream ? "capture" : "playback", dpcm->be->dai_link->name); @@ -815,7 +818,7 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card, } } - dev_err(card->dev, "can't get %s BE for %s\n", + dev_err(card->dev, "ASoC: can't get %s BE for %s\n", stream ? "capture" : "playback", widget->name); return NULL; } @@ -866,7 +869,7 @@ static int dpcm_path_get(struct snd_soc_pcm_runtime *fe, /* get number of valid DAI paths and their widgets */ paths = snd_soc_dapm_dai_get_connected_widgets(cpu_dai, stream, &list); - dev_dbg(fe->dev, "found %d audio %s paths\n", paths, + dev_dbg(fe->dev, "ASoC: found %d audio %s paths\n", paths, stream ? "capture" : "playback"); *list_ = list; @@ -903,7 +906,7 @@ static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream, if (widget && widget_in_list(list, widget)) continue; - dev_dbg(fe->dev, "pruning %s BE %s for %s\n", + dev_dbg(fe->dev, "ASoC: pruning %s BE %s for %s\n", stream ? "capture" : "playback", dpcm->be->dai_link->name, fe->dai_link->name); 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, prune++; } - dev_dbg(fe->dev, "found %d old BE paths for pruning\n", prune); + dev_dbg(fe->dev, "ASoC: found %d old BE paths for pruning\n", prune); return prune; } @@ -932,7 +935,7 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream, /* is there a valid BE rtd for this widget */ be = dpcm_get_be(card, list->widgets[i], stream); if (!be) { - dev_err(fe->dev, "no BE found for %s\n", + dev_err(fe->dev, "ASoC: no BE found for %s\n", list->widgets[i]->name); continue; } @@ -948,7 +951,7 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream, /* newly connected FE and BE */ err = dpcm_be_connect(fe, be, stream); if (err < 0) { - dev_err(fe->dev, "can't connect %s\n", + dev_err(fe->dev, "ASoC: can't connect %s\n", list->widgets[i]->name); break; } else if (err == 0) /* already connected */ @@ -959,7 +962,7 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream, new++; } - dev_dbg(fe->dev, "found %d new BE paths\n", new); + dev_dbg(fe->dev, "ASoC: found %d new BE paths\n", new); return new; } @@ -998,7 +1001,7 @@ static void dpcm_be_dai_startup_unwind(struct snd_soc_pcm_runtime *fe, snd_soc_dpcm_get_substream(be, stream); if (be->dpcm[stream].users == 0) - dev_err(be->dev, "no users %s at close - state %d\n", + dev_err(be->dev, "ASoC: no users %s at close - state %d\n", stream ? "capture" : "playback", be->dpcm[stream].state); @@ -1032,7 +1035,7 @@ static int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream) /* first time the dpcm is open ? */ if (be->dpcm[stream].users == DPCM_MAX_BE_USERS) - dev_err(be->dev, "too many users %s at open %d\n", + dev_err(be->dev, "ASoC: too many users %s at open %d\n", stream ? "capture" : "playback", be->dpcm[stream].state); @@ -1043,15 +1046,15 @@ static int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream) (be->dpcm[stream].state != SND_SOC_DPCM_STATE_CLOSE)) continue; - dev_dbg(be->dev, "dpcm: open BE %s\n", be->dai_link->name); + dev_dbg(be->dev, "ASoC: open BE %s\n", be->dai_link->name); be_substream->runtime = be->dpcm[stream].runtime; err = soc_pcm_open(be_substream); if (err < 0) { - dev_err(be->dev, "BE open failed %d\n", err); + dev_err(be->dev, "ASoC: BE open failed %d\n", err); be->dpcm[stream].users--; if (be->dpcm[stream].users < 0) - dev_err(be->dev, "no users %s at unwind %d\n", + dev_err(be->dev, "ASoC: no users %s at unwind %d\n", stream ? "capture" : "playback", be->dpcm[stream].state); @@ -1076,7 +1079,7 @@ unwind: continue; if (be->dpcm[stream].users == 0) - dev_err(be->dev, "no users %s at close %d\n", + dev_err(be->dev, "ASoC: no users %s at close %d\n", stream ? "capture" : "playback", be->dpcm[stream].state); @@ -1128,16 +1131,16 @@ static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream) ret = dpcm_be_dai_startup(fe, fe_substream->stream); if (ret < 0) { - dev_err(fe->dev,"dpcm: failed to start some BEs %d\n", ret); + dev_err(fe->dev,"ASoC: failed to start some BEs %d\n", ret); goto be_err; } - dev_dbg(fe->dev, "dpcm: open FE %s\n", fe->dai_link->name); + dev_dbg(fe->dev, "ASoC: open FE %s\n", fe->dai_link->name); /* start the DAI frontend */ ret = soc_pcm_open(fe_substream); if (ret < 0) { - dev_err(fe->dev,"dpcm: failed to start FE %d\n", ret); + dev_err(fe->dev,"ASoC: failed to start FE %d\n", ret); goto unwind; } @@ -1172,7 +1175,7 @@ static int dpcm_be_dai_shutdown(struct snd_soc_pcm_runtime *fe, int stream) continue; if (be->dpcm[stream].users == 0) - dev_err(be->dev, "no users %s at close - state %d\n", + dev_err(be->dev, "ASoC: no users %s at close - state %d\n", stream ? "capture" : "playback", be->dpcm[stream].state); @@ -1183,7 +1186,7 @@ static int dpcm_be_dai_shutdown(struct snd_soc_pcm_runtime *fe, int stream) (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN)) continue; - dev_dbg(be->dev, "dpcm: close BE %s\n", + dev_dbg(be->dev, "ASoC: close BE %s\n", dpcm->fe->dai_link->name); soc_pcm_close(be_substream); @@ -1204,7 +1207,7 @@ static int dpcm_fe_dai_shutdown(struct snd_pcm_substream *substream) /* shutdown the BEs */ dpcm_be_dai_shutdown(fe, substream->stream); - dev_dbg(fe->dev, "dpcm: close FE %s\n", fe->dai_link->name); + dev_dbg(fe->dev, "ASoC: close FE %s\n", fe->dai_link->name); /* now shutdown the frontend */ soc_pcm_close(substream); @@ -1243,7 +1246,7 @@ static int dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream) (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) continue; - dev_dbg(be->dev, "dpcm: hw_free BE %s\n", + dev_dbg(be->dev, "ASoC: hw_free BE %s\n", dpcm->fe->dai_link->name); soc_pcm_hw_free(be_substream); @@ -1262,12 +1265,12 @@ static int dpcm_fe_dai_hw_free(struct snd_pcm_substream *substream) mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; - dev_dbg(fe->dev, "dpcm: hw_free FE %s\n", fe->dai_link->name); + dev_dbg(fe->dev, "ASoC: hw_free FE %s\n", fe->dai_link->name); /* call hw_free on the frontend */ err = soc_pcm_hw_free(substream); if (err < 0) - dev_err(fe->dev,"dpcm: hw_free FE %s failed\n", + dev_err(fe->dev,"ASoC: hw_free FE %s failed\n", fe->dai_link->name); /* 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) (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE)) continue; - dev_dbg(be->dev, "dpcm: hw_params BE %s\n", + dev_dbg(be->dev, "ASoC: hw_params BE %s\n", dpcm->fe->dai_link->name); /* copy params for each dpcm */ @@ -1318,7 +1321,7 @@ static int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream) &dpcm->hw_params); if (ret < 0) { dev_err(be->dev, - "dpcm: hw_params BE fixup failed %d\n", + "ASoC: hw_params BE fixup failed %d\n", ret); goto unwind; } @@ -1327,7 +1330,7 @@ static int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream) ret = soc_pcm_hw_params(be_substream, &dpcm->hw_params); if (ret < 0) { dev_err(dpcm->be->dev, - "dpcm: hw_params BE failed %d\n", ret); + "ASoC: hw_params BE failed %d\n", ret); goto unwind; } @@ -1374,18 +1377,18 @@ static int dpcm_fe_dai_hw_params(struct snd_pcm_substream *substream, sizeof(struct snd_pcm_hw_params)); ret = dpcm_be_dai_hw_params(fe, substream->stream); if (ret < 0) { - dev_err(fe->dev,"dpcm: hw_params BE failed %d\n", ret); + dev_err(fe->dev,"ASoC: hw_params BE failed %d\n", ret); goto out; } - dev_dbg(fe->dev, "dpcm: hw_params FE %s rate %d chan %x fmt %d\n", + dev_dbg(fe->dev, "ASoC: hw_params FE %s rate %d chan %x fmt %d\n", fe->dai_link->name, params_rate(params), params_channels(params), params_format(params)); /* call hw_params on the frontend */ ret = soc_pcm_hw_params(substream, params); if (ret < 0) { - dev_err(fe->dev,"dpcm: hw_params FE failed %d\n", ret); + dev_err(fe->dev,"ASoC: hw_params FE failed %d\n", ret); dpcm_be_dai_hw_free(fe, stream); } else fe->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_PARAMS; @@ -1401,12 +1404,12 @@ static int dpcm_do_trigger(struct snd_soc_dpcm *dpcm, { int ret; - dev_dbg(dpcm->be->dev, "dpcm: trigger BE %s cmd %d\n", + dev_dbg(dpcm->be->dev, "ASoC: trigger BE %s cmd %d\n", dpcm->fe->dai_link->name, cmd); ret = soc_pcm_trigger(substream, cmd); if (ret < 0) - dev_err(dpcm->be->dev,"dpcm: trigger BE failed %d\n", ret); + dev_err(dpcm->be->dev,"ASoC: trigger BE failed %d\n", ret); return ret; } @@ -1517,12 +1520,12 @@ static int dpcm_fe_dai_trigger(struct snd_pcm_substream *substream, int cmd) case SND_SOC_DPCM_TRIGGER_PRE: /* call trigger on the frontend before the backend. */ - dev_dbg(fe->dev, "dpcm: pre trigger FE %s cmd %d\n", + dev_dbg(fe->dev, "ASoC: pre trigger FE %s cmd %d\n", fe->dai_link->name, cmd); ret = soc_pcm_trigger(substream, cmd); if (ret < 0) { - dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret); + dev_err(fe->dev,"ASoC: trigger FE failed %d\n", ret); goto out; } @@ -1533,11 +1536,11 @@ static int dpcm_fe_dai_trigger(struct snd_pcm_substream *substream, int cmd) ret = dpcm_be_dai_trigger(fe, substream->stream, cmd); if (ret < 0) { - dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret); + dev_err(fe->dev,"ASoC: trigger FE failed %d\n", ret); goto out; } - dev_dbg(fe->dev, "dpcm: post trigger FE %s cmd %d\n", + dev_dbg(fe->dev, "ASoC: post trigger FE %s cmd %d\n", fe->dai_link->name, cmd); ret = soc_pcm_trigger(substream, cmd); @@ -1545,17 +1548,17 @@ static int dpcm_fe_dai_trigger(struct snd_pcm_substream *substream, int cmd) case SND_SOC_DPCM_TRIGGER_BESPOKE: /* bespoke trigger() - handles both FE and BEs */ - dev_dbg(fe->dev, "dpcm: bespoke trigger FE %s cmd %d\n", + dev_dbg(fe->dev, "ASoC: bespoke trigger FE %s cmd %d\n", fe->dai_link->name, cmd); ret = soc_pcm_bespoke_trigger(substream, cmd); if (ret < 0) { - dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret); + dev_err(fe->dev,"ASoC: trigger FE failed %d\n", ret); goto out; } break; default: - dev_err(fe->dev, "dpcm: invalid trigger cmd %d for %s\n", cmd, + dev_err(fe->dev, "ASoC: invalid trigger cmd %d for %s\n", cmd, fe->dai_link->name); ret = -EINVAL; goto out; @@ -1598,12 +1601,12 @@ static int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream) (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) continue; - dev_dbg(be->dev, "dpcm: prepare BE %s\n", + dev_dbg(be->dev, "ASoC: prepare BE %s\n", dpcm->fe->dai_link->name); ret = soc_pcm_prepare(be_substream); if (ret < 0) { - dev_err(be->dev, "dpcm: backend prepare failed %d\n", + dev_err(be->dev, "ASoC: backend prepare failed %d\n", ret); break; } @@ -1620,13 +1623,13 @@ static int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream) mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); - dev_dbg(fe->dev, "dpcm: prepare FE %s\n", fe->dai_link->name); + dev_dbg(fe->dev, "ASoC: prepare FE %s\n", fe->dai_link->name); fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; /* there is no point preparing this FE if there are no BEs */ if (list_empty(&fe->dpcm[stream].be_clients)) { - dev_err(fe->dev, "dpcm: no backend DAIs enabled for %s\n", + dev_err(fe->dev, "ASoC: no backend DAIs enabled for %s\n", fe->dai_link->name); ret = -EINVAL; goto out; @@ -1639,7 +1642,7 @@ static int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream) /* call prepare on the frontend */ ret = soc_pcm_prepare(substream); if (ret < 0) { - dev_err(fe->dev,"dpcm: prepare FE %s failed\n", + dev_err(fe->dev,"ASoC: prepare FE %s failed\n", fe->dai_link->name); goto out; } @@ -1673,33 +1676,33 @@ static int dpcm_run_update_shutdown(struct snd_soc_pcm_runtime *fe, int stream) enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream]; int err; - dev_dbg(fe->dev, "runtime %s close on FE %s\n", + dev_dbg(fe->dev, "ASoC: runtime %s close on FE %s\n", stream ? "capture" : "playback", fe->dai_link->name); if (trigger == SND_SOC_DPCM_TRIGGER_BESPOKE) { /* call bespoke trigger - FE takes care of all BE triggers */ - dev_dbg(fe->dev, "dpcm: bespoke trigger FE %s cmd stop\n", + dev_dbg(fe->dev, "ASoC: bespoke trigger FE %s cmd stop\n", fe->dai_link->name); err = soc_pcm_bespoke_trigger(substream, SNDRV_PCM_TRIGGER_STOP); if (err < 0) - dev_err(fe->dev,"dpcm: trigger FE failed %d\n", err); + dev_err(fe->dev,"ASoC: trigger FE failed %d\n", err); } else { - dev_dbg(fe->dev, "dpcm: trigger FE %s cmd stop\n", + dev_dbg(fe->dev, "ASoC: trigger FE %s cmd stop\n", fe->dai_link->name); err = dpcm_be_dai_trigger(fe, stream, SNDRV_PCM_TRIGGER_STOP); if (err < 0) - dev_err(fe->dev,"dpcm: trigger FE failed %d\n", err); + dev_err(fe->dev,"ASoC: trigger FE failed %d\n", err); } err = dpcm_be_dai_hw_free(fe, stream); if (err < 0) - dev_err(fe->dev,"dpcm: hw_free FE failed %d\n", err); + dev_err(fe->dev,"ASoC: hw_free FE failed %d\n", err); err = dpcm_be_dai_shutdown(fe, stream); if (err < 0) - dev_err(fe->dev,"dpcm: shutdown FE failed %d\n", err); + dev_err(fe->dev,"ASoC: shutdown FE failed %d\n", err); /* run the stream event for each BE */ 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) enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream]; int ret; - dev_dbg(fe->dev, "runtime %s open on FE %s\n", + dev_dbg(fe->dev, "ASoC: runtime %s open on FE %s\n", stream ? "capture" : "playback", fe->dai_link->name); /* 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) if (trigger == SND_SOC_DPCM_TRIGGER_BESPOKE) { /* call trigger on the frontend - FE takes care of all BE triggers */ - dev_dbg(fe->dev, "dpcm: bespoke trigger FE %s cmd start\n", + dev_dbg(fe->dev, "ASoC: bespoke trigger FE %s cmd start\n", fe->dai_link->name); ret = soc_pcm_bespoke_trigger(substream, SNDRV_PCM_TRIGGER_START); if (ret < 0) { - dev_err(fe->dev,"dpcm: bespoke trigger FE failed %d\n", ret); + dev_err(fe->dev,"ASoC: bespoke trigger FE failed %d\n", ret); goto hw_free; } } else { - dev_dbg(fe->dev, "dpcm: trigger FE %s cmd start\n", + dev_dbg(fe->dev, "ASoC: trigger FE %s cmd start\n", fe->dai_link->name); ret = dpcm_be_dai_trigger(fe, stream, SNDRV_PCM_TRIGGER_START); if (ret < 0) { - dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret); + dev_err(fe->dev,"ASoC: trigger FE failed %d\n", ret); goto hw_free; } } @@ -1805,7 +1808,7 @@ static int dpcm_run_new_update(struct snd_soc_pcm_runtime *fe, int stream) fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE; ret = dpcm_run_update_startup(fe, stream); if (ret < 0) - dev_err(fe->dev, "failed to startup some BEs\n"); + dev_err(fe->dev, "ASoC: failed to startup some BEs\n"); fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; return ret; @@ -1818,7 +1821,7 @@ static int dpcm_run_old_update(struct snd_soc_pcm_runtime *fe, int stream) fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE; ret = dpcm_run_update_shutdown(fe, stream); if (ret < 0) - dev_err(fe->dev, "failed to shutdown some BEs\n"); + dev_err(fe->dev, "ASoC: failed to shutdown some BEs\n"); fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; return ret; @@ -1853,7 +1856,7 @@ int soc_dpcm_runtime_update(struct snd_soc_dapm_widget *widget) continue; /* DAPM sync will call this to update DSP paths */ - dev_dbg(fe->dev, "DPCM runtime update for FE %s\n", + dev_dbg(fe->dev, "ASoC: DPCM runtime update for FE %s\n", fe->dai_link->name); /* skip if FE doesn't have playback capability */ @@ -1862,7 +1865,7 @@ int soc_dpcm_runtime_update(struct snd_soc_dapm_widget *widget) paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_PLAYBACK, &list); if (paths < 0) { - dev_warn(fe->dev, "%s no valid %s path\n", + dev_warn(fe->dev, "ASoC: %s no valid %s path\n", fe->dai_link->name, "playback"); mutex_unlock(&card->mutex); return paths; @@ -1891,7 +1894,7 @@ capture: paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_CAPTURE, &list); if (paths < 0) { - dev_warn(fe->dev, "%s no valid %s path\n", + dev_warn(fe->dev, "ASoC: %s no valid %s path\n", fe->dai_link->name, "capture"); mutex_unlock(&card->mutex); return paths; @@ -1934,7 +1937,7 @@ int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute) if (be->dai_link->ignore_suspend) continue; - dev_dbg(be->dev, "BE digital mute %s\n", be->dai_link->name); + dev_dbg(be->dev, "ASoC: BE digital mute %s\n", be->dai_link->name); if (drv->ops->digital_mute && dai->playback_active) drv->ops->digital_mute(dai, mute); @@ -1955,7 +1958,7 @@ static int dpcm_fe_dai_open(struct snd_pcm_substream *fe_substream) fe->dpcm[stream].runtime = fe_substream->runtime; if (dpcm_path_get(fe, stream, &list) <= 0) { - dev_dbg(fe->dev, "asoc: %s no valid %s route\n", + dev_dbg(fe->dev, "ASoC: %s no valid %s route\n", fe->dai_link->name, stream ? "capture" : "playback"); } @@ -2039,11 +2042,11 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) capture, &pcm); } if (ret < 0) { - dev_err(rtd->card->dev, "can't create pcm for %s\n", + dev_err(rtd->card->dev, "ASoC: can't create pcm for %s\n", rtd->dai_link->name); return ret; } - dev_dbg(rtd->card->dev, "registered pcm #%d %s\n",num, new_name); + dev_dbg(rtd->card->dev, "ASoC: registered pcm #%d %s\n",num, new_name); /* DAPM dai link stream work */ 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) if (platform->driver->pcm_new) { ret = platform->driver->pcm_new(rtd); if (ret < 0) { - dev_err(platform->dev, "pcm constructor failed\n"); + dev_err(platform->dev, + "ASoC: pcm constructor failed: %d\n", + ret); return ret; } } diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c index 60053709e41..fe4541df498 100644 --- a/sound/soc/soc-utils.c +++ b/sound/soc/soc-utils.c @@ -94,7 +94,7 @@ static struct snd_soc_dai_driver dummy_dai = { .name = "snd-soc-dummy-dai", }; -static __devinit int snd_soc_dummy_probe(struct platform_device *pdev) +static int snd_soc_dummy_probe(struct platform_device *pdev) { int ret; @@ -111,7 +111,7 @@ static __devinit int snd_soc_dummy_probe(struct platform_device *pdev) return ret; } -static __devexit int snd_soc_dummy_remove(struct platform_device *pdev) +static int snd_soc_dummy_remove(struct platform_device *pdev) { snd_soc_unregister_platform(&pdev->dev); snd_soc_unregister_codec(&pdev->dev); @@ -125,7 +125,7 @@ static struct platform_driver soc_dummy_driver = { .owner = THIS_MODULE, }, .probe = snd_soc_dummy_probe, - .remove = __devexit_p(snd_soc_dummy_remove), + .remove = snd_soc_dummy_remove, }; static struct platform_device *soc_dummy_dev; diff --git a/sound/soc/spear/spear_pcm.c b/sound/soc/spear/spear_pcm.c index 8c7f2372944..9b76cc5a114 100644 --- a/sound/soc/spear/spear_pcm.c +++ b/sound/soc/spear/spear_pcm.c @@ -184,12 +184,12 @@ struct snd_soc_platform_driver spear_soc_platform = { .pcm_free = spear_pcm_free, }; -static int __devinit spear_soc_platform_probe(struct platform_device *pdev) +static int spear_soc_platform_probe(struct platform_device *pdev) { return snd_soc_register_platform(&pdev->dev, &spear_soc_platform); } -static int __devexit spear_soc_platform_remove(struct platform_device *pdev) +static int spear_soc_platform_remove(struct platform_device *pdev) { snd_soc_unregister_platform(&pdev->dev); @@ -203,7 +203,7 @@ static struct platform_driver spear_pcm_driver = { }, .probe = spear_soc_platform_probe, - .remove = __devexit_p(spear_soc_platform_remove), + .remove = spear_soc_platform_remove, }; module_platform_driver(spear_pcm_driver); diff --git a/sound/soc/tegra/tegra20_das.c b/sound/soc/tegra/tegra20_das.c index bf99296bce9..65431848387 100644 --- a/sound/soc/tegra/tegra20_das.c +++ b/sound/soc/tegra/tegra20_das.c @@ -131,7 +131,7 @@ static const struct regmap_config tegra20_das_regmap_config = { .cache_type = REGCACHE_RBTREE, }; -static int __devinit tegra20_das_probe(struct platform_device *pdev) +static int tegra20_das_probe(struct platform_device *pdev) { struct resource *res, *region; void __iomem *regs; @@ -200,7 +200,7 @@ err: return ret; } -static int __devexit tegra20_das_remove(struct platform_device *pdev) +static int tegra20_das_remove(struct platform_device *pdev) { if (!das) return -ENODEV; @@ -210,14 +210,14 @@ static int __devexit tegra20_das_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id tegra20_das_of_match[] __devinitconst = { +static const struct of_device_id tegra20_das_of_match[] = { { .compatible = "nvidia,tegra20-das", }, {}, }; static struct platform_driver tegra20_das_driver = { .probe = tegra20_das_probe, - .remove = __devexit_p(tegra20_das_remove), + .remove = tegra20_das_remove, .driver = { .name = DRV_NAME, .owner = THIS_MODULE, diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c index 0832e8afd73..caa772de5a1 100644 --- a/sound/soc/tegra/tegra20_i2s.c +++ b/sound/soc/tegra/tegra20_i2s.c @@ -331,7 +331,7 @@ static const struct regmap_config tegra20_i2s_regmap_config = { .cache_type = REGCACHE_RBTREE, }; -static __devinit int tegra20_i2s_platform_probe(struct platform_device *pdev) +static int tegra20_i2s_platform_probe(struct platform_device *pdev) { struct tegra20_i2s *i2s; struct resource *mem, *memregion, *dmareq; @@ -447,7 +447,7 @@ err: return ret; } -static int __devexit tegra20_i2s_platform_remove(struct platform_device *pdev) +static int tegra20_i2s_platform_remove(struct platform_device *pdev) { struct tegra20_i2s *i2s = dev_get_drvdata(&pdev->dev); @@ -463,12 +463,12 @@ static int __devexit tegra20_i2s_platform_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id tegra20_i2s_of_match[] __devinitconst = { +static const struct of_device_id tegra20_i2s_of_match[] = { { .compatible = "nvidia,tegra20-i2s", }, {}, }; -static const struct dev_pm_ops tegra20_i2s_pm_ops __devinitconst = { +static const struct dev_pm_ops tegra20_i2s_pm_ops = { SET_RUNTIME_PM_OPS(tegra20_i2s_runtime_suspend, tegra20_i2s_runtime_resume, NULL) }; @@ -481,7 +481,7 @@ static struct platform_driver tegra20_i2s_driver = { .pm = &tegra20_i2s_pm_ops, }, .probe = tegra20_i2s_platform_probe, - .remove = __devexit_p(tegra20_i2s_platform_remove), + .remove = tegra20_i2s_platform_remove, }; module_platform_driver(tegra20_i2s_driver); diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c index 3ebc8670ba0..04771d14d34 100644 --- a/sound/soc/tegra/tegra20_spdif.c +++ b/sound/soc/tegra/tegra20_spdif.c @@ -257,7 +257,7 @@ static const struct regmap_config tegra20_spdif_regmap_config = { .cache_type = REGCACHE_RBTREE, }; -static __devinit int tegra20_spdif_platform_probe(struct platform_device *pdev) +static int tegra20_spdif_platform_probe(struct platform_device *pdev) { struct tegra20_spdif *spdif; struct resource *mem, *memregion, *dmareq; @@ -357,7 +357,7 @@ err: return ret; } -static int __devexit tegra20_spdif_platform_remove(struct platform_device *pdev) +static int tegra20_spdif_platform_remove(struct platform_device *pdev) { struct tegra20_spdif *spdif = dev_get_drvdata(&pdev->dev); @@ -373,7 +373,7 @@ static int __devexit tegra20_spdif_platform_remove(struct platform_device *pdev) return 0; } -static const struct dev_pm_ops tegra20_spdif_pm_ops __devinitconst = { +static const struct dev_pm_ops tegra20_spdif_pm_ops = { SET_RUNTIME_PM_OPS(tegra20_spdif_runtime_suspend, tegra20_spdif_runtime_resume, NULL) }; @@ -385,7 +385,7 @@ static struct platform_driver tegra20_spdif_driver = { .pm = &tegra20_spdif_pm_ops, }, .probe = tegra20_spdif_platform_probe, - .remove = __devexit_p(tegra20_spdif_platform_remove), + .remove = tegra20_spdif_platform_remove, }; module_platform_driver(tegra20_spdif_driver); diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c index bf5610122c7..fd596d2a19b 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) } EXPORT_SYMBOL_GPL(tegra30_ahub_unset_rx_cif_source); -static const char * const configlink_clocks[] __devinitconst = { +static const char * const configlink_clocks[] = { "i2s0", "i2s1", "i2s2", @@ -300,7 +300,7 @@ static const char * const configlink_clocks[] __devinitconst = { "spdif_in", }; -struct of_dev_auxdata ahub_auxdata[] __devinitdata = { +struct of_dev_auxdata ahub_auxdata[] = { OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080300, "tegra30-i2s.0", NULL), OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080400, "tegra30-i2s.1", NULL), OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080500, "tegra30-i2s.2", NULL), @@ -434,7 +434,7 @@ static const struct regmap_config tegra30_ahub_ahub_regmap_config = { .cache_type = REGCACHE_RBTREE, }; -static int __devinit tegra30_ahub_probe(struct platform_device *pdev) +static int tegra30_ahub_probe(struct platform_device *pdev) { struct clk *clk; int i; @@ -586,7 +586,7 @@ err: return ret; } -static int __devexit tegra30_ahub_remove(struct platform_device *pdev) +static int tegra30_ahub_remove(struct platform_device *pdev) { if (!ahub) return -ENODEV; @@ -603,19 +603,19 @@ static int __devexit tegra30_ahub_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id tegra30_ahub_of_match[] __devinitconst = { +static const struct of_device_id tegra30_ahub_of_match[] = { { .compatible = "nvidia,tegra30-ahub", }, {}, }; -static const struct dev_pm_ops tegra30_ahub_pm_ops __devinitconst = { +static const struct dev_pm_ops tegra30_ahub_pm_ops = { SET_RUNTIME_PM_OPS(tegra30_ahub_runtime_suspend, tegra30_ahub_runtime_resume, NULL) }; static struct platform_driver tegra30_ahub_driver = { .probe = tegra30_ahub_probe, - .remove = __devexit_p(tegra30_ahub_remove), + .remove = tegra30_ahub_remove, .driver = { .name = DRV_NAME, .owner = THIS_MODULE, diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index 44184228d1f..27e91dd0b91 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c @@ -391,7 +391,7 @@ static const struct regmap_config tegra30_i2s_regmap_config = { .cache_type = REGCACHE_RBTREE, }; -static __devinit int tegra30_i2s_platform_probe(struct platform_device *pdev) +static int tegra30_i2s_platform_probe(struct platform_device *pdev) { struct tegra30_i2s *i2s; u32 cif_ids[2]; @@ -492,7 +492,7 @@ err: return ret; } -static int __devexit tegra30_i2s_platform_remove(struct platform_device *pdev) +static int tegra30_i2s_platform_remove(struct platform_device *pdev) { struct tegra30_i2s *i2s = dev_get_drvdata(&pdev->dev); @@ -508,12 +508,12 @@ static int __devexit tegra30_i2s_platform_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id tegra30_i2s_of_match[] __devinitconst = { +static const struct of_device_id tegra30_i2s_of_match[] = { { .compatible = "nvidia,tegra30-i2s", }, {}, }; -static const struct dev_pm_ops tegra30_i2s_pm_ops __devinitconst = { +static const struct dev_pm_ops tegra30_i2s_pm_ops = { SET_RUNTIME_PM_OPS(tegra30_i2s_runtime_suspend, tegra30_i2s_runtime_resume, NULL) }; @@ -526,7 +526,7 @@ static struct platform_driver tegra30_i2s_driver = { .pm = &tegra30_i2s_pm_ops, }, .probe = tegra30_i2s_platform_probe, - .remove = __devexit_p(tegra30_i2s_platform_remove), + .remove = tegra30_i2s_platform_remove, }; module_platform_driver(tegra30_i2s_driver); diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c index 76cb1b363b7..c80adb9da47 100644 --- a/sound/soc/tegra/tegra_alc5632.c +++ b/sound/soc/tegra/tegra_alc5632.c @@ -150,7 +150,7 @@ static struct snd_soc_card snd_soc_tegra_alc5632 = { .fully_routed = true, }; -static __devinit int tegra_alc5632_probe(struct platform_device *pdev) +static int tegra_alc5632_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct snd_soc_card *card = &snd_soc_tegra_alc5632; @@ -227,7 +227,7 @@ err: return ret; } -static int __devexit tegra_alc5632_remove(struct platform_device *pdev) +static int tegra_alc5632_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(card); @@ -242,7 +242,7 @@ static int __devexit tegra_alc5632_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id tegra_alc5632_of_match[] __devinitconst = { +static const struct of_device_id tegra_alc5632_of_match[] = { { .compatible = "nvidia,tegra-audio-alc5632", }, {}, }; @@ -255,7 +255,7 @@ static struct platform_driver tegra_alc5632_driver = { .of_match_table = tegra_alc5632_of_match, }, .probe = tegra_alc5632_probe, - .remove = __devexit_p(tegra_alc5632_remove), + .remove = tegra_alc5632_remove, }; module_platform_driver(tegra_alc5632_driver); diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c index e18733963cb..c925ab0adeb 100644 --- a/sound/soc/tegra/tegra_pcm.c +++ b/sound/soc/tegra/tegra_pcm.c @@ -253,13 +253,13 @@ static struct snd_soc_platform_driver tegra_pcm_platform = { .pcm_free = tegra_pcm_free, }; -int __devinit tegra_pcm_platform_register(struct device *dev) +int tegra_pcm_platform_register(struct device *dev) { return snd_soc_register_platform(dev, &tegra_pcm_platform); } EXPORT_SYMBOL_GPL(tegra_pcm_platform_register); -void __devexit tegra_pcm_platform_unregister(struct device *dev) +void tegra_pcm_platform_unregister(struct device *dev) { snd_soc_unregister_platform(dev); } diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c index ea9166d5c4e..c8ef88a67c5 100644 --- a/sound/soc/tegra/tegra_wm8753.c +++ b/sound/soc/tegra/tegra_wm8753.c @@ -122,7 +122,7 @@ static struct snd_soc_card snd_soc_tegra_wm8753 = { .fully_routed = true, }; -static __devinit int tegra_wm8753_driver_probe(struct platform_device *pdev) +static int tegra_wm8753_driver_probe(struct platform_device *pdev) { struct snd_soc_card *card = &snd_soc_tegra_wm8753; struct tegra_wm8753 *machine; @@ -188,7 +188,7 @@ err: return ret; } -static int __devexit tegra_wm8753_driver_remove(struct platform_device *pdev) +static int tegra_wm8753_driver_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); struct tegra_wm8753 *machine = snd_soc_card_get_drvdata(card); @@ -200,7 +200,7 @@ static int __devexit tegra_wm8753_driver_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id tegra_wm8753_of_match[] __devinitconst = { +static const struct of_device_id tegra_wm8753_of_match[] = { { .compatible = "nvidia,tegra-audio-wm8753", }, {}, }; @@ -213,7 +213,7 @@ static struct platform_driver tegra_wm8753_driver = { .of_match_table = tegra_wm8753_of_match, }, .probe = tegra_wm8753_driver_probe, - .remove = __devexit_p(tegra_wm8753_driver_remove), + .remove = tegra_wm8753_driver_remove, }; module_platform_driver(tegra_wm8753_driver); diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index cee13b7bfb9..bbd79bf5630 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -252,7 +252,7 @@ static struct snd_soc_card snd_soc_tegra_wm8903 = { .fully_routed = true, }; -static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev) +static int tegra_wm8903_driver_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct snd_soc_card *card = &snd_soc_tegra_wm8903; @@ -402,7 +402,7 @@ err: return ret; } -static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev) +static int tegra_wm8903_driver_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); @@ -417,7 +417,7 @@ static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id tegra_wm8903_of_match[] __devinitconst = { +static const struct of_device_id tegra_wm8903_of_match[] = { { .compatible = "nvidia,tegra-audio-wm8903", }, {}, }; @@ -430,7 +430,7 @@ static struct platform_driver tegra_wm8903_driver = { .of_match_table = tegra_wm8903_of_match, }, .probe = tegra_wm8903_driver_probe, - .remove = __devexit_p(tegra_wm8903_driver_remove), + .remove = tegra_wm8903_driver_remove, }; module_platform_driver(tegra_wm8903_driver); diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c index e69a4f7000d..7fcf6c2297d 100644 --- a/sound/soc/tegra/trimslice.c +++ b/sound/soc/tegra/trimslice.c @@ -120,7 +120,7 @@ static struct snd_soc_card snd_soc_trimslice = { .fully_routed = true, }; -static __devinit int tegra_snd_trimslice_probe(struct platform_device *pdev) +static int tegra_snd_trimslice_probe(struct platform_device *pdev) { struct snd_soc_card *card = &snd_soc_trimslice; struct tegra_trimslice *trimslice; @@ -183,7 +183,7 @@ err: return ret; } -static int __devexit tegra_snd_trimslice_remove(struct platform_device *pdev) +static int tegra_snd_trimslice_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); struct tegra_trimslice *trimslice = snd_soc_card_get_drvdata(card); @@ -195,7 +195,7 @@ static int __devexit tegra_snd_trimslice_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id trimslice_of_match[] __devinitconst = { +static const struct of_device_id trimslice_of_match[] = { { .compatible = "nvidia,tegra-audio-trimslice", }, {}, }; @@ -208,7 +208,7 @@ static struct platform_driver tegra_snd_trimslice_driver = { .of_match_table = trimslice_of_match, }, .probe = tegra_snd_trimslice_probe, - .remove = __devexit_p(tegra_snd_trimslice_remove), + .remove = tegra_snd_trimslice_remove, }; module_platform_driver(tegra_snd_trimslice_driver); diff --git a/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c index 28db4ca997c..16ab69635e2 100644 --- a/sound/soc/txx9/txx9aclc-ac97.c +++ b/sound/soc/txx9/txx9aclc-ac97.c @@ -170,7 +170,7 @@ static struct snd_soc_dai_driver txx9aclc_ac97_dai = { }, }; -static int __devinit txx9aclc_ac97_dev_probe(struct platform_device *pdev) +static int txx9aclc_ac97_dev_probe(struct platform_device *pdev) { struct txx9aclc_plat_drvdata *drvdata; struct resource *r; @@ -208,7 +208,7 @@ static int __devinit txx9aclc_ac97_dev_probe(struct platform_device *pdev) return snd_soc_register_dai(&pdev->dev, &txx9aclc_ac97_dai); } -static int __devexit txx9aclc_ac97_dev_remove(struct platform_device *pdev) +static int txx9aclc_ac97_dev_remove(struct platform_device *pdev) { snd_soc_unregister_dai(&pdev->dev); return 0; @@ -216,7 +216,7 @@ static int __devexit txx9aclc_ac97_dev_remove(struct platform_device *pdev) static struct platform_driver txx9aclc_ac97_driver = { .probe = txx9aclc_ac97_dev_probe, - .remove = __devexit_p(txx9aclc_ac97_dev_remove), + .remove = txx9aclc_ac97_dev_remove, .driver = { .name = "txx9aclc-ac97", .owner = THIS_MODULE, diff --git a/sound/soc/txx9/txx9aclc.c b/sound/soc/txx9/txx9aclc.c index b609d2c64c5..45a6428cba8 100644 --- a/sound/soc/txx9/txx9aclc.c +++ b/sound/soc/txx9/txx9aclc.c @@ -417,12 +417,12 @@ static struct snd_soc_platform_driver txx9aclc_soc_platform = { .pcm_free = txx9aclc_pcm_free_dma_buffers, }; -static int __devinit txx9aclc_soc_platform_probe(struct platform_device *pdev) +static int txx9aclc_soc_platform_probe(struct platform_device *pdev) { return snd_soc_register_platform(&pdev->dev, &txx9aclc_soc_platform); } -static int __devexit txx9aclc_soc_platform_remove(struct platform_device *pdev) +static int txx9aclc_soc_platform_remove(struct platform_device *pdev) { snd_soc_unregister_platform(&pdev->dev); return 0; @@ -435,7 +435,7 @@ static struct platform_driver txx9aclc_pcm_driver = { }, .probe = txx9aclc_soc_platform_probe, - .remove = __devexit_p(txx9aclc_soc_platform_remove), + .remove = txx9aclc_soc_platform_remove, }; module_platform_driver(txx9aclc_pcm_driver); diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c index 54f7e25b6f7..ae699073878 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[] = { .stream_name = "ab8500_0", .cpu_dai_name = "ux500-msp-i2s.1", .codec_dai_name = "ab8500-codec-dai.0", - .platform_name = "ux500-pcm.0", + .platform_name = "ux500-msp-i2s.1", .codec_name = "ab8500-codec.0", .init = mop500_ab8500_machine_init, .ops = mop500_ab8500_ops, @@ -43,7 +43,7 @@ struct snd_soc_dai_link mop500_dai_links[] = { .stream_name = "ab8500_1", .cpu_dai_name = "ux500-msp-i2s.3", .codec_dai_name = "ab8500-codec-dai.1", - .platform_name = "ux500-pcm.0", + .platform_name = "ux500-msp-i2s.3", .codec_name = "ab8500-codec.0", .init = NULL, .ops = mop500_ab8500_ops, @@ -71,8 +71,8 @@ static void mop500_of_node_put(void) } } -static int __devinit mop500_of_probe(struct platform_device *pdev, - struct device_node *np) +static int mop500_of_probe(struct platform_device *pdev, + struct device_node *np) { struct device_node *codec_np, *msp_np[2]; int i; @@ -99,7 +99,7 @@ static int __devinit mop500_of_probe(struct platform_device *pdev, return 0; } -static int __devinit mop500_probe(struct platform_device *pdev) +static int mop500_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; int ret; @@ -136,7 +136,7 @@ static int __devinit mop500_probe(struct platform_device *pdev) return ret; } -static int __devexit mop500_remove(struct platform_device *pdev) +static int mop500_remove(struct platform_device *pdev) { struct snd_soc_card *mop500_card = platform_get_drvdata(pdev); @@ -161,7 +161,7 @@ static struct platform_driver snd_soc_mop500_driver = { .of_match_table = snd_soc_mop500_match, }, .probe = mop500_probe, - .remove = __devexit_p(mop500_remove), + .remove = mop500_remove, }; module_platform_driver(snd_soc_mop500_driver); diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c index be94bf9bf94..94a3e5705aa 100644 --- a/sound/soc/ux500/ux500_msp_dai.c +++ b/sound/soc/ux500/ux500_msp_dai.c @@ -28,6 +28,7 @@ #include "ux500_msp_i2s.h" #include "ux500_msp_dai.h" +#include "ux500_pcm.h" static int setup_pcm_multichan(struct snd_soc_dai *dai, struct ux500_msp_config *msp_config) @@ -398,11 +399,28 @@ static int ux500_msp_dai_startup(struct snd_pcm_substream *substream, return ret; } - /* Enable clock */ - dev_dbg(dai->dev, "%s: Enabling MSP-clock.\n", __func__); - clk_enable(drvdata->clk); + /* Prepare and enable clocks */ + dev_dbg(dai->dev, "%s: Enabling MSP-clocks.\n", __func__); + ret = clk_prepare_enable(drvdata->pclk); + if (ret) { + dev_err(drvdata->msp->dev, + "%s: Failed to prepare/enable pclk!\n", __func__); + goto err_pclk; + } - return 0; + ret = clk_prepare_enable(drvdata->clk); + if (ret) { + dev_err(drvdata->msp->dev, + "%s: Failed to prepare/enable clk!\n", __func__); + goto err_clk; + } + + return ret; +err_clk: + clk_disable_unprepare(drvdata->pclk); +err_pclk: + regulator_disable(drvdata->reg_vape); + return ret; } 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, __func__, dai->id, snd_pcm_stream_str(substream)); } - /* Disable clock */ - clk_disable(drvdata->clk); + /* Disable and unprepare clocks */ + clk_disable_unprepare(drvdata->clk); + clk_disable_unprepare(drvdata->pclk); /* Disable regulator */ ret = regulator_disable(drvdata->reg_vape); @@ -749,7 +768,7 @@ static struct snd_soc_dai_driver ux500_msp_dai_drv[UX500_NBR_OF_DAI] = { }, }; -static int __devinit ux500_msp_drv_probe(struct platform_device *pdev) +static int ux500_msp_drv_probe(struct platform_device *pdev) { struct ux500_msp_i2s_drvdata *drvdata; int ret = 0; @@ -780,6 +799,14 @@ static int __devinit ux500_msp_drv_probe(struct platform_device *pdev) } prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP, (char *)pdev->name, 50); + drvdata->pclk = clk_get(&pdev->dev, "apb_pclk"); + if (IS_ERR(drvdata->pclk)) { + ret = (int)PTR_ERR(drvdata->pclk); + dev_err(&pdev->dev, "%s: ERROR: clk_get of pclk failed (%d)!\n", + __func__, ret); + goto err_pclk; + } + drvdata->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(drvdata->clk)) { ret = (int)PTR_ERR(drvdata->clk); @@ -806,27 +833,41 @@ static int __devinit ux500_msp_drv_probe(struct platform_device *pdev) goto err_init_msp; } + ret = ux500_pcm_register_platform(pdev); + if (ret < 0) { + dev_err(&pdev->dev, + "Error: %s: Failed to register PCM platform device!\n", + __func__); + goto err_reg_plat; + } + return 0; +err_reg_plat: + snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(ux500_msp_dai_drv)); err_init_msp: clk_put(drvdata->clk); - err_clk: + clk_put(drvdata->pclk); +err_pclk: devm_regulator_put(drvdata->reg_vape); return ret; } -static int __devexit ux500_msp_drv_remove(struct platform_device *pdev) +static int ux500_msp_drv_remove(struct platform_device *pdev) { struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(&pdev->dev); + ux500_pcm_unregister_platform(pdev); + snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(ux500_msp_dai_drv)); devm_regulator_put(drvdata->reg_vape); prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, "ux500_msp_i2s"); clk_put(drvdata->clk); + clk_put(drvdata->pclk); ux500_msp_i2s_cleanup_msp(pdev, drvdata->msp); diff --git a/sound/soc/ux500/ux500_msp_dai.h b/sound/soc/ux500/ux500_msp_dai.h index 98202a34a5d..9c778d9c383 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 { /* Clocks */ unsigned int master_clk; struct clk *clk; + struct clk *pclk; /* Regulators */ int vape_opp_constraint; diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c index 1a04e248453..c6821a5ab0f 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 = { .pcm_new = ux500_pcm_new, }; -static int __devexit ux500_pcm_drv_probe(struct platform_device *pdev) +int ux500_pcm_register_platform(struct platform_device *pdev) { int ret; @@ -296,23 +296,12 @@ static int __devexit ux500_pcm_drv_probe(struct platform_device *pdev) return 0; } +EXPORT_SYMBOL_GPL(ux500_pcm_register_platform); -static int __devinit ux500_pcm_drv_remove(struct platform_device *pdev) +int ux500_pcm_unregister_platform(struct platform_device *pdev) { snd_soc_unregister_platform(&pdev->dev); return 0; } - -static struct platform_driver ux500_pcm_driver = { - .driver = { - .name = "ux500-pcm", - .owner = THIS_MODULE, - }, - - .probe = ux500_pcm_drv_probe, - .remove = __devexit_p(ux500_pcm_drv_remove), -}; -module_platform_driver(ux500_pcm_driver); - -MODULE_LICENSE("GPL v2"); +EXPORT_SYMBOL_GPL(ux500_pcm_unregister_platform); diff --git a/sound/soc/ux500/ux500_pcm.h b/sound/soc/ux500/ux500_pcm.h index 77ed44d371e..76d344476af 100644 --- a/sound/soc/ux500/ux500_pcm.h +++ b/sound/soc/ux500/ux500_pcm.h @@ -32,4 +32,7 @@ #define UX500_PLATFORM_PERIODS_MAX 48 #define UX500_PLATFORM_BUFFER_BYTES_MAX (2048 * PAGE_SIZE) +int ux500_pcm_register_platform(struct platform_device *pdev); +int ux500_pcm_unregister_platform(struct platform_device *pdev); + #endif |