diff options
| author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-08-22 15:19:01 -0400 |
|---|---|---|
| committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-08-22 15:19:01 -0400 |
| commit | 2bbf6078dc948e87564c1a947f23ea4cf2349a13 (patch) | |
| tree | 2fc93ee7a26febb4ff9554e40043f8e097726c6d | |
| parent | 02e79476998ba7e62842d20dca898c403ad55c7e (diff) | |
| parent | b8101048f0f3cd281ed4c4901e38ae2bcfb32030 (diff) | |
Merge branch 'asoc-omap' into for-3.7
| -rw-r--r-- | Documentation/devicetree/bindings/sound/omap-mcbsp.txt | 37 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/board-am3517evm.c | 13 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/mcbsp.c | 126 | ||||
| -rw-r--r-- | arch/arm/plat-omap/include/plat/mcbsp.h | 2 | ||||
| -rw-r--r-- | sound/soc/omap/am3517evm.c | 20 | ||||
| -rw-r--r-- | sound/soc/omap/mcbsp.c | 31 | ||||
| -rw-r--r-- | sound/soc/omap/mcbsp.h | 3 | ||||
| -rw-r--r-- | sound/soc/omap/omap-mcbsp.c | 106 | ||||
| -rw-r--r-- | sound/soc/omap/omap-mcbsp.h | 20 |
9 files changed, 158 insertions, 200 deletions
diff --git a/Documentation/devicetree/bindings/sound/omap-mcbsp.txt b/Documentation/devicetree/bindings/sound/omap-mcbsp.txt new file mode 100644 index 000000000000..17cce4490456 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/omap-mcbsp.txt | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | * Texas Instruments OMAP2+ McBSP module | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible: "ti,omap2420-mcbsp" for McBSP on OMAP2420 | ||
| 5 | "ti,omap2430-mcbsp" for McBSP on OMAP2430 | ||
| 6 | "ti,omap3-mcbsp" for McBSP on OMAP3 | ||
| 7 | "ti,omap4-mcbsp" for McBSP on OMAP4 and newer SoC | ||
| 8 | - reg: Register location and size, for OMAP4+ as an array: | ||
| 9 | <MPU access base address, size>, | ||
| 10 | <L3 interconnect address, size>; | ||
| 11 | - reg-names: Array of strings associated with the address space | ||
| 12 | - interrupts: Interrupt numbers for the McBSP port, as an array in case the | ||
| 13 | McBSP IP have more interrupt lines: | ||
| 14 | <OCP compliant irq>, | ||
| 15 | <TX irq>, | ||
| 16 | <RX irq>; | ||
| 17 | - interrupt-names: Array of strings associated with the interrupt numbers | ||
| 18 | - interrupt-parent: The parent interrupt controller | ||
| 19 | - ti,buffer-size: Size of the FIFO on the port (OMAP2430 and newer SoC) | ||
| 20 | - ti,hwmods: Name of the hwmod associated to the McBSP port | ||
| 21 | |||
| 22 | Example: | ||
| 23 | |||
| 24 | mcbsp2: mcbsp@49022000 { | ||
| 25 | compatible = "ti,omap3-mcbsp"; | ||
| 26 | reg = <0x49022000 0xff>, | ||
| 27 | <0x49028000 0xff>; | ||
| 28 | reg-names = "mpu", "sidetone"; | ||
| 29 | interrupts = <0 17 0x4>, /* OCP compliant interrupt */ | ||
| 30 | <0 62 0x4>, /* TX interrupt */ | ||
| 31 | <0 63 0x4>, /* RX interrupt */ | ||
| 32 | <0 4 0x4>; /* Sidetone */ | ||
| 33 | interrupt-names = "common", "tx", "rx", "sidetone"; | ||
| 34 | interrupt-parent = <&intc>; | ||
| 35 | ti,buffer-size = <1280>; | ||
| 36 | ti,hwmods = "mcbsp2"; | ||
| 37 | }; | ||
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index 18f601096ce1..592812af84da 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c | |||
| @@ -264,6 +264,16 @@ static __init void am3517_evm_musb_init(void) | |||
| 264 | usb_musb_init(&musb_board_data); | 264 | usb_musb_init(&musb_board_data); |
| 265 | } | 265 | } |
| 266 | 266 | ||
| 267 | static __init void am3517_evm_mcbsp1_init(void) | ||
| 268 | { | ||
| 269 | u32 devconf0; | ||
| 270 | |||
| 271 | /* McBSP1 CLKR/FSR signal to be connected to CLKX/FSX pin */ | ||
| 272 | devconf0 = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); | ||
| 273 | devconf0 |= OMAP2_MCBSP1_CLKR_MASK | OMAP2_MCBSP1_FSR_MASK; | ||
| 274 | omap_ctrl_writel(devconf0, OMAP2_CONTROL_DEVCONF0); | ||
| 275 | } | ||
| 276 | |||
| 267 | static const struct usbhs_omap_board_data usbhs_bdata __initconst = { | 277 | static const struct usbhs_omap_board_data usbhs_bdata __initconst = { |
| 268 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, | 278 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, |
| 269 | #if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \ | 279 | #if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \ |
| @@ -373,6 +383,9 @@ static void __init am3517_evm_init(void) | |||
| 373 | /* MUSB */ | 383 | /* MUSB */ |
| 374 | am3517_evm_musb_init(); | 384 | am3517_evm_musb_init(); |
| 375 | 385 | ||
| 386 | /* McBSP1 */ | ||
| 387 | am3517_evm_mcbsp1_init(); | ||
| 388 | |||
| 376 | /* MMC init function */ | 389 | /* MMC init function */ |
| 377 | omap_hsmmc_init(mmc); | 390 | omap_hsmmc_init(mmc); |
| 378 | } | 391 | } |
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c index 577cb77db26c..d57a3578bf03 100644 --- a/arch/arm/mach-omap2/mcbsp.c +++ b/arch/arm/mach-omap2/mcbsp.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/clk.h> | 15 | #include <linux/clk.h> |
| 16 | #include <linux/err.h> | 16 | #include <linux/err.h> |
| 17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
| 18 | #include <linux/of.h> | ||
| 18 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
| 19 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
| 20 | 21 | ||
| @@ -25,8 +26,6 @@ | |||
| 25 | #include <plat/omap_device.h> | 26 | #include <plat/omap_device.h> |
| 26 | #include <linux/pm_runtime.h> | 27 | #include <linux/pm_runtime.h> |
| 27 | 28 | ||
| 28 | #include "control.h" | ||
| 29 | |||
| 30 | /* | 29 | /* |
| 31 | * FIXME: Find a mechanism to enable/disable runtime the McBSP ICLK autoidle. | 30 | * FIXME: Find a mechanism to enable/disable runtime the McBSP ICLK autoidle. |
| 32 | * Sidetone needs non-gated ICLK and sidetone autoidle is broken. | 31 | * Sidetone needs non-gated ICLK and sidetone autoidle is broken. |
| @@ -34,112 +33,6 @@ | |||
| 34 | #include "cm2xxx_3xxx.h" | 33 | #include "cm2xxx_3xxx.h" |
| 35 | #include "cm-regbits-34xx.h" | 34 | #include "cm-regbits-34xx.h" |
| 36 | 35 | ||
| 37 | /* McBSP1 internal signal muxing function for OMAP2/3 */ | ||
| 38 | static int omap2_mcbsp1_mux_rx_clk(struct device *dev, const char *signal, | ||
| 39 | const char *src) | ||
| 40 | { | ||
| 41 | u32 v; | ||
| 42 | |||
| 43 | v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); | ||
| 44 | |||
| 45 | if (!strcmp(signal, "clkr")) { | ||
| 46 | if (!strcmp(src, "clkr")) | ||
| 47 | v &= ~OMAP2_MCBSP1_CLKR_MASK; | ||
| 48 | else if (!strcmp(src, "clkx")) | ||
| 49 | v |= OMAP2_MCBSP1_CLKR_MASK; | ||
| 50 | else | ||
| 51 | return -EINVAL; | ||
| 52 | } else if (!strcmp(signal, "fsr")) { | ||
| 53 | if (!strcmp(src, "fsr")) | ||
| 54 | v &= ~OMAP2_MCBSP1_FSR_MASK; | ||
| 55 | else if (!strcmp(src, "fsx")) | ||
| 56 | v |= OMAP2_MCBSP1_FSR_MASK; | ||
| 57 | else | ||
| 58 | return -EINVAL; | ||
| 59 | } else { | ||
| 60 | return -EINVAL; | ||
| 61 | } | ||
| 62 | |||
| 63 | omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0); | ||
| 64 | |||
| 65 | return 0; | ||
| 66 | } | ||
| 67 | |||
| 68 | /* McBSP4 internal signal muxing function for OMAP4 */ | ||
| 69 | #define OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_FSX (1 << 31) | ||
| 70 | #define OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_CLKX (1 << 30) | ||
| 71 | static int omap4_mcbsp4_mux_rx_clk(struct device *dev, const char *signal, | ||
| 72 | const char *src) | ||
| 73 | { | ||
| 74 | u32 v; | ||
| 75 | |||
| 76 | /* | ||
| 77 | * In CONTROL_MCBSPLP register only bit 30 (CLKR mux), and bit 31 (FSR | ||
| 78 | * mux) is used */ | ||
| 79 | v = omap4_ctrl_pad_readl(OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MCBSPLP); | ||
| 80 | |||
| 81 | if (!strcmp(signal, "clkr")) { | ||
| 82 | if (!strcmp(src, "clkr")) | ||
| 83 | v &= ~OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_CLKX; | ||
| 84 | else if (!strcmp(src, "clkx")) | ||
| 85 | v |= OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_CLKX; | ||
| 86 | else | ||
| 87 | return -EINVAL; | ||
| 88 | } else if (!strcmp(signal, "fsr")) { | ||
| 89 | if (!strcmp(src, "fsr")) | ||
| 90 | v &= ~OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_FSX; | ||
| 91 | else if (!strcmp(src, "fsx")) | ||
| 92 | v |= OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_FSX; | ||
| 93 | else | ||
| 94 | return -EINVAL; | ||
| 95 | } else { | ||
| 96 | return -EINVAL; | ||
| 97 | } | ||
| 98 | |||
| 99 | omap4_ctrl_pad_writel(v, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MCBSPLP); | ||
| 100 | |||
| 101 | return 0; | ||
| 102 | } | ||
| 103 | |||
| 104 | /* McBSP CLKS source switching function */ | ||
| 105 | static int omap2_mcbsp_set_clk_src(struct device *dev, struct clk *clk, | ||
| 106 | const char *src) | ||
| 107 | { | ||
| 108 | struct clk *fck_src; | ||
| 109 | char *fck_src_name; | ||
| 110 | int r; | ||
| 111 | |||
| 112 | if (!strcmp(src, "clks_ext")) | ||
| 113 | fck_src_name = "pad_fck"; | ||
| 114 | else if (!strcmp(src, "clks_fclk")) | ||
| 115 | fck_src_name = "prcm_fck"; | ||
| 116 | else | ||
| 117 | return -EINVAL; | ||
| 118 | |||
| 119 | fck_src = clk_get(dev, fck_src_name); | ||
| 120 | if (IS_ERR_OR_NULL(fck_src)) { | ||
| 121 | pr_err("omap-mcbsp: %s: could not clk_get() %s\n", "clks", | ||
| 122 | fck_src_name); | ||
| 123 | return -EINVAL; | ||
| 124 | } | ||
| 125 | |||
| 126 | pm_runtime_put_sync(dev); | ||
| 127 | |||
| 128 | r = clk_set_parent(clk, fck_src); | ||
| 129 | if (IS_ERR_VALUE(r)) { | ||
| 130 | pr_err("omap-mcbsp: %s: could not clk_set_parent() to %s\n", | ||
| 131 | "clks", fck_src_name); | ||
| 132 | clk_put(fck_src); | ||
| 133 | return -EINVAL; | ||
| 134 | } | ||
| 135 | |||
| 136 | pm_runtime_get_sync(dev); | ||
| 137 | |||
| 138 | clk_put(fck_src); | ||
| 139 | |||
| 140 | return 0; | ||
| 141 | } | ||
| 142 | |||
| 143 | static int omap3_enable_st_clock(unsigned int id, bool enable) | 36 | static int omap3_enable_st_clock(unsigned int id, bool enable) |
| 144 | { | 37 | { |
| 145 | unsigned int w; | 38 | unsigned int w; |
| @@ -181,17 +74,11 @@ static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused) | |||
| 181 | pdata->reg_size = 4; | 74 | pdata->reg_size = 4; |
| 182 | pdata->has_ccr = true; | 75 | pdata->has_ccr = true; |
| 183 | } | 76 | } |
| 184 | pdata->set_clk_src = omap2_mcbsp_set_clk_src; | ||
| 185 | |||
| 186 | /* On OMAP2/3 the McBSP1 port has 6 pin configuration */ | ||
| 187 | if (id == 1 && oh->class->rev < MCBSP_CONFIG_TYPE4) | ||
| 188 | pdata->mux_signal = omap2_mcbsp1_mux_rx_clk; | ||
| 189 | 77 | ||
| 190 | /* On OMAP4 the McBSP4 port has 6 pin configuration */ | 78 | if (oh->class->rev == MCBSP_CONFIG_TYPE2) { |
| 191 | if (id == 4 && oh->class->rev == MCBSP_CONFIG_TYPE4) | 79 | /* The FIFO has 128 locations */ |
| 192 | pdata->mux_signal = omap4_mcbsp4_mux_rx_clk; | 80 | pdata->buffer_size = 0x80; |
| 193 | 81 | } else if (oh->class->rev == MCBSP_CONFIG_TYPE3) { | |
| 194 | if (oh->class->rev == MCBSP_CONFIG_TYPE3) { | ||
| 195 | if (id == 2) | 82 | if (id == 2) |
| 196 | /* The FIFO has 1024 + 256 locations */ | 83 | /* The FIFO has 1024 + 256 locations */ |
| 197 | pdata->buffer_size = 0x500; | 84 | pdata->buffer_size = 0x500; |
| @@ -227,7 +114,8 @@ static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused) | |||
| 227 | 114 | ||
| 228 | static int __init omap2_mcbsp_init(void) | 115 | static int __init omap2_mcbsp_init(void) |
| 229 | { | 116 | { |
| 230 | omap_hwmod_for_each_by_class("mcbsp", omap_init_mcbsp, NULL); | 117 | if (!of_have_populated_dt()) |
| 118 | omap_hwmod_for_each_by_class("mcbsp", omap_init_mcbsp, NULL); | ||
| 231 | 119 | ||
| 232 | return 0; | 120 | return 0; |
| 233 | } | 121 | } |
diff --git a/arch/arm/plat-omap/include/plat/mcbsp.h b/arch/arm/plat-omap/include/plat/mcbsp.h index 18814127809a..c78d90b28b19 100644 --- a/arch/arm/plat-omap/include/plat/mcbsp.h +++ b/arch/arm/plat-omap/include/plat/mcbsp.h | |||
| @@ -47,8 +47,6 @@ struct omap_mcbsp_platform_data { | |||
| 47 | bool has_wakeup; /* Wakeup capability */ | 47 | bool has_wakeup; /* Wakeup capability */ |
| 48 | bool has_ccr; /* Transceiver has configuration control registers */ | 48 | bool has_ccr; /* Transceiver has configuration control registers */ |
| 49 | int (*enable_st_clock)(unsigned int, bool); | 49 | int (*enable_st_clock)(unsigned int, bool); |
| 50 | int (*set_clk_src)(struct device *dev, struct clk *clk, const char *src); | ||
| 51 | int (*mux_signal)(struct device *dev, const char *signal, const char *src); | ||
| 52 | }; | 50 | }; |
| 53 | 51 | ||
| 54 | /** | 52 | /** |
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c index 009533ab8d18..a997988af147 100644 --- a/sound/soc/omap/am3517evm.c +++ b/sound/soc/omap/am3517evm.c | |||
| @@ -47,26 +47,10 @@ static int am3517evm_hw_params(struct snd_pcm_substream *substream, | |||
| 47 | /* Set the codec system clock for DAC and ADC */ | 47 | /* Set the codec system clock for DAC and ADC */ |
| 48 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, | 48 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, |
| 49 | CODEC_CLOCK, SND_SOC_CLOCK_IN); | 49 | CODEC_CLOCK, SND_SOC_CLOCK_IN); |
| 50 | if (ret < 0) { | 50 | if (ret < 0) |
| 51 | printk(KERN_ERR "can't set codec system clock\n"); | 51 | printk(KERN_ERR "can't set codec system clock\n"); |
| 52 | return ret; | ||
| 53 | } | ||
| 54 | |||
| 55 | ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_CLKR_SRC_CLKX, 0, | ||
| 56 | SND_SOC_CLOCK_IN); | ||
| 57 | if (ret < 0) { | ||
| 58 | printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_CLKR_SRC_CLKX\n"); | ||
| 59 | return ret; | ||
| 60 | } | ||
| 61 | 52 | ||
| 62 | snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_FSR_SRC_FSX, 0, | 53 | return ret; |
| 63 | SND_SOC_CLOCK_IN); | ||
| 64 | if (ret < 0) { | ||
| 65 | printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_FSR_SRC_FSX\n"); | ||
| 66 | return ret; | ||
| 67 | } | ||
| 68 | |||
| 69 | return 0; | ||
| 70 | } | 54 | } |
| 71 | 55 | ||
| 72 | static struct snd_soc_ops am3517evm_ops = { | 56 | static struct snd_soc_ops am3517evm_ops = { |
diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c index 34835e8a9160..6afbc26cef70 100644 --- a/sound/soc/omap/mcbsp.c +++ b/sound/soc/omap/mcbsp.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
| 25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
| 26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
| 27 | #include <linux/pm_runtime.h> | ||
| 27 | 28 | ||
| 28 | #include <plat/mcbsp.h> | 29 | #include <plat/mcbsp.h> |
| 29 | 30 | ||
| @@ -726,19 +727,39 @@ void omap_mcbsp_stop(struct omap_mcbsp *mcbsp, int tx, int rx) | |||
| 726 | 727 | ||
| 727 | int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id) | 728 | int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id) |
| 728 | { | 729 | { |
| 730 | struct clk *fck_src; | ||
| 729 | const char *src; | 731 | const char *src; |
| 732 | int r; | ||
| 730 | 733 | ||
| 731 | if (fck_src_id == MCBSP_CLKS_PAD_SRC) | 734 | if (fck_src_id == MCBSP_CLKS_PAD_SRC) |
| 732 | src = "clks_ext"; | 735 | src = "pad_fck"; |
| 733 | else if (fck_src_id == MCBSP_CLKS_PRCM_SRC) | 736 | else if (fck_src_id == MCBSP_CLKS_PRCM_SRC) |
| 734 | src = "clks_fclk"; | 737 | src = "prcm_fck"; |
| 735 | else | 738 | else |
| 736 | return -EINVAL; | 739 | return -EINVAL; |
| 737 | 740 | ||
| 738 | if (mcbsp->pdata->set_clk_src) | 741 | fck_src = clk_get(mcbsp->dev, src); |
| 739 | return mcbsp->pdata->set_clk_src(mcbsp->dev, mcbsp->fclk, src); | 742 | if (IS_ERR(fck_src)) { |
| 740 | else | 743 | dev_err(mcbsp->dev, "CLKS: could not clk_get() %s\n", src); |
| 741 | return -EINVAL; | 744 | return -EINVAL; |
| 745 | } | ||
| 746 | |||
| 747 | pm_runtime_put_sync(mcbsp->dev); | ||
| 748 | |||
| 749 | r = clk_set_parent(mcbsp->fclk, fck_src); | ||
| 750 | if (r) { | ||
| 751 | dev_err(mcbsp->dev, "CLKS: could not clk_set_parent() to %s\n", | ||
| 752 | src); | ||
| 753 | clk_put(fck_src); | ||
| 754 | return r; | ||
| 755 | } | ||
| 756 | |||
| 757 | pm_runtime_get_sync(mcbsp->dev); | ||
| 758 | |||
| 759 | clk_put(fck_src); | ||
| 760 | |||
| 761 | return 0; | ||
| 762 | |||
| 742 | } | 763 | } |
| 743 | 764 | ||
| 744 | int omap_mcbsp_6pin_src_mux(struct omap_mcbsp *mcbsp, u8 mux) | 765 | int omap_mcbsp_6pin_src_mux(struct omap_mcbsp *mcbsp, u8 mux) |
diff --git a/sound/soc/omap/mcbsp.h b/sound/soc/omap/mcbsp.h index 262a6152111f..49a67259ce5a 100644 --- a/sound/soc/omap/mcbsp.h +++ b/sound/soc/omap/mcbsp.h | |||
| @@ -334,9 +334,6 @@ void omap_mcbsp_stop(struct omap_mcbsp *mcbsp, int tx, int rx); | |||
| 334 | /* McBSP functional clock source changing function */ | 334 | /* McBSP functional clock source changing function */ |
| 335 | int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id); | 335 | int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id); |
| 336 | 336 | ||
| 337 | /* McBSP signal muxing API */ | ||
| 338 | int omap_mcbsp_6pin_src_mux(struct omap_mcbsp *mcbsp, u8 mux); | ||
| 339 | |||
| 340 | /* Sidetone specific API */ | 337 | /* Sidetone specific API */ |
| 341 | int omap_st_set_chgain(struct omap_mcbsp *mcbsp, int channel, s16 chgain); | 338 | int omap_st_set_chgain(struct omap_mcbsp *mcbsp, int channel, s16 chgain); |
| 342 | int omap_st_get_chgain(struct omap_mcbsp *mcbsp, int channel, s16 *chgain); | 339 | int omap_st_get_chgain(struct omap_mcbsp *mcbsp, int channel, s16 *chgain); |
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index acdd3ef14e08..d6de066ad7ea 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c | |||
| @@ -26,6 +26,8 @@ | |||
| 26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
| 27 | #include <linux/device.h> | 27 | #include <linux/device.h> |
| 28 | #include <linux/pm_runtime.h> | 28 | #include <linux/pm_runtime.h> |
| 29 | #include <linux/of.h> | ||
| 30 | #include <linux/of_device.h> | ||
| 29 | #include <sound/core.h> | 31 | #include <sound/core.h> |
| 30 | #include <sound/pcm.h> | 32 | #include <sound/pcm.h> |
| 31 | #include <sound/pcm_params.h> | 33 | #include <sound/pcm_params.h> |
| @@ -398,12 +400,14 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
| 398 | /* Generic McBSP register settings */ | 400 | /* Generic McBSP register settings */ |
| 399 | regs->spcr2 |= XINTM(3) | FREE; | 401 | regs->spcr2 |= XINTM(3) | FREE; |
| 400 | regs->spcr1 |= RINTM(3); | 402 | regs->spcr1 |= RINTM(3); |
| 401 | /* RFIG and XFIG are not defined in 34xx */ | 403 | /* RFIG and XFIG are not defined in 2430 and on OMAP3+ */ |
| 402 | if (!cpu_is_omap34xx() && !cpu_is_omap44xx()) { | 404 | if (!mcbsp->pdata->has_ccr) { |
| 403 | regs->rcr2 |= RFIG; | 405 | regs->rcr2 |= RFIG; |
| 404 | regs->xcr2 |= XFIG; | 406 | regs->xcr2 |= XFIG; |
| 405 | } | 407 | } |
| 406 | if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) { | 408 | |
| 409 | /* Configure XCCR/RCCR only for revisions which have ccr registers */ | ||
| 410 | if (mcbsp->pdata->has_ccr) { | ||
| 407 | regs->xccr = DXENDLY(1) | XDMAEN | XDISABLE; | 411 | regs->xccr = DXENDLY(1) | XDMAEN | XDISABLE; |
| 408 | regs->rccr = RFULL_CYCLE | RDMAEN | RDISABLE; | 412 | regs->rccr = RFULL_CYCLE | RDMAEN | RDISABLE; |
| 409 | } | 413 | } |
| @@ -516,21 +520,9 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, | |||
| 516 | return -EBUSY; | 520 | return -EBUSY; |
| 517 | } | 521 | } |
| 518 | 522 | ||
| 519 | if (clk_id == OMAP_MCBSP_SYSCLK_CLK || | 523 | mcbsp->in_freq = freq; |
| 520 | clk_id == OMAP_MCBSP_SYSCLK_CLKS_FCLK || | 524 | regs->srgr2 &= ~CLKSM; |
| 521 | clk_id == OMAP_MCBSP_SYSCLK_CLKS_EXT || | 525 | regs->pcr0 &= ~SCLKME; |
| 522 | clk_id == OMAP_MCBSP_SYSCLK_CLKX_EXT || | ||
| 523 | clk_id == OMAP_MCBSP_SYSCLK_CLKR_EXT) { | ||
| 524 | mcbsp->in_freq = freq; | ||
| 525 | regs->srgr2 &= ~CLKSM; | ||
| 526 | regs->pcr0 &= ~SCLKME; | ||
| 527 | } else if (cpu_class_is_omap1()) { | ||
| 528 | /* | ||
| 529 | * McBSP CLKR/FSR signal muxing functions are only available on | ||
| 530 | * OMAP2 or newer versions | ||
| 531 | */ | ||
| 532 | return -EINVAL; | ||
| 533 | } | ||
| 534 | 526 | ||
| 535 | switch (clk_id) { | 527 | switch (clk_id) { |
| 536 | case OMAP_MCBSP_SYSCLK_CLK: | 528 | case OMAP_MCBSP_SYSCLK_CLK: |
| @@ -558,20 +550,6 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, | |||
| 558 | case OMAP_MCBSP_SYSCLK_CLKR_EXT: | 550 | case OMAP_MCBSP_SYSCLK_CLKR_EXT: |
| 559 | regs->pcr0 |= SCLKME; | 551 | regs->pcr0 |= SCLKME; |
| 560 | break; | 552 | break; |
| 561 | |||
| 562 | |||
| 563 | case OMAP_MCBSP_CLKR_SRC_CLKR: | ||
| 564 | err = omap_mcbsp_6pin_src_mux(mcbsp, CLKR_SRC_CLKR); | ||
| 565 | break; | ||
| 566 | case OMAP_MCBSP_CLKR_SRC_CLKX: | ||
| 567 | err = omap_mcbsp_6pin_src_mux(mcbsp, CLKR_SRC_CLKX); | ||
| 568 | break; | ||
| 569 | case OMAP_MCBSP_FSR_SRC_FSR: | ||
| 570 | err = omap_mcbsp_6pin_src_mux(mcbsp, FSR_SRC_FSR); | ||
| 571 | break; | ||
| 572 | case OMAP_MCBSP_FSR_SRC_FSX: | ||
| 573 | err = omap_mcbsp_6pin_src_mux(mcbsp, FSR_SRC_FSX); | ||
| 574 | break; | ||
| 575 | default: | 553 | default: |
| 576 | err = -ENODEV; | 554 | err = -ENODEV; |
| 577 | } | 555 | } |
| @@ -761,13 +739,74 @@ int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd) | |||
| 761 | } | 739 | } |
| 762 | EXPORT_SYMBOL_GPL(omap_mcbsp_st_add_controls); | 740 | EXPORT_SYMBOL_GPL(omap_mcbsp_st_add_controls); |
| 763 | 741 | ||
| 742 | static struct omap_mcbsp_platform_data omap2420_pdata = { | ||
| 743 | .reg_step = 4, | ||
| 744 | .reg_size = 2, | ||
| 745 | }; | ||
| 746 | |||
| 747 | static struct omap_mcbsp_platform_data omap2430_pdata = { | ||
| 748 | .reg_step = 4, | ||
| 749 | .reg_size = 4, | ||
| 750 | .has_ccr = true, | ||
| 751 | }; | ||
| 752 | |||
| 753 | static struct omap_mcbsp_platform_data omap3_pdata = { | ||
| 754 | .reg_step = 4, | ||
| 755 | .reg_size = 4, | ||
| 756 | .has_ccr = true, | ||
| 757 | .has_wakeup = true, | ||
| 758 | }; | ||
| 759 | |||
| 760 | static struct omap_mcbsp_platform_data omap4_pdata = { | ||
| 761 | .reg_step = 4, | ||
| 762 | .reg_size = 4, | ||
| 763 | .has_ccr = true, | ||
| 764 | .has_wakeup = true, | ||
| 765 | }; | ||
| 766 | |||
| 767 | static const struct of_device_id omap_mcbsp_of_match[] = { | ||
| 768 | { | ||
| 769 | .compatible = "ti,omap2420-mcbsp", | ||
| 770 | .data = &omap2420_pdata, | ||
| 771 | }, | ||
| 772 | { | ||
| 773 | .compatible = "ti,omap2430-mcbsp", | ||
| 774 | .data = &omap2430_pdata, | ||
| 775 | }, | ||
| 776 | { | ||
| 777 | .compatible = "ti,omap3-mcbsp", | ||
| 778 | .data = &omap3_pdata, | ||
| 779 | }, | ||
| 780 | { | ||
| 781 | .compatible = "ti,omap4-mcbsp", | ||
| 782 | .data = &omap4_pdata, | ||
| 783 | }, | ||
| 784 | { }, | ||
| 785 | }; | ||
| 786 | MODULE_DEVICE_TABLE(of, omap_mcbsp_of_match); | ||
| 787 | |||
| 764 | static __devinit int asoc_mcbsp_probe(struct platform_device *pdev) | 788 | static __devinit int asoc_mcbsp_probe(struct platform_device *pdev) |
| 765 | { | 789 | { |
| 766 | struct omap_mcbsp_platform_data *pdata = dev_get_platdata(&pdev->dev); | 790 | struct omap_mcbsp_platform_data *pdata = dev_get_platdata(&pdev->dev); |
| 767 | struct omap_mcbsp *mcbsp; | 791 | struct omap_mcbsp *mcbsp; |
| 792 | const struct of_device_id *match; | ||
| 768 | int ret; | 793 | int ret; |
| 769 | 794 | ||
| 770 | if (!pdata) { | 795 | match = of_match_device(omap_mcbsp_of_match, &pdev->dev); |
| 796 | if (match) { | ||
| 797 | struct device_node *node = pdev->dev.of_node; | ||
| 798 | int buffer_size; | ||
| 799 | |||
| 800 | pdata = devm_kzalloc(&pdev->dev, | ||
| 801 | sizeof(struct omap_mcbsp_platform_data), | ||
| 802 | GFP_KERNEL); | ||
| 803 | if (!pdata) | ||
| 804 | return -ENOMEM; | ||
| 805 | |||
| 806 | memcpy(pdata, match->data, sizeof(*pdata)); | ||
| 807 | if (!of_property_read_u32(node, "ti,buffer-size", &buffer_size)) | ||
| 808 | pdata->buffer_size = buffer_size; | ||
| 809 | } else if (!pdata) { | ||
| 771 | dev_err(&pdev->dev, "missing platform data.\n"); | 810 | dev_err(&pdev->dev, "missing platform data.\n"); |
| 772 | return -EINVAL; | 811 | return -EINVAL; |
| 773 | } | 812 | } |
| @@ -809,6 +848,7 @@ static struct platform_driver asoc_mcbsp_driver = { | |||
| 809 | .driver = { | 848 | .driver = { |
| 810 | .name = "omap-mcbsp", | 849 | .name = "omap-mcbsp", |
| 811 | .owner = THIS_MODULE, | 850 | .owner = THIS_MODULE, |
| 851 | .of_match_table = omap_mcbsp_of_match, | ||
| 812 | }, | 852 | }, |
| 813 | 853 | ||
| 814 | .probe = asoc_mcbsp_probe, | 854 | .probe = asoc_mcbsp_probe, |
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h index f877b16f19c9..ba8386a0d8dc 100644 --- a/sound/soc/omap/omap-mcbsp.h +++ b/sound/soc/omap/omap-mcbsp.h | |||
| @@ -32,10 +32,6 @@ enum omap_mcbsp_clksrg_clk { | |||
| 32 | OMAP_MCBSP_SYSCLK_CLK, /* Internal ICLK */ | 32 | OMAP_MCBSP_SYSCLK_CLK, /* Internal ICLK */ |
| 33 | OMAP_MCBSP_SYSCLK_CLKX_EXT, /* External CLKX pin */ | 33 | OMAP_MCBSP_SYSCLK_CLKX_EXT, /* External CLKX pin */ |
| 34 | OMAP_MCBSP_SYSCLK_CLKR_EXT, /* External CLKR pin */ | 34 | OMAP_MCBSP_SYSCLK_CLKR_EXT, /* External CLKR pin */ |
| 35 | OMAP_MCBSP_CLKR_SRC_CLKR, /* CLKR from CLKR pin */ | ||
| 36 | OMAP_MCBSP_CLKR_SRC_CLKX, /* CLKR from CLKX pin */ | ||
| 37 | OMAP_MCBSP_FSR_SRC_FSR, /* FSR from FSR pin */ | ||
| 38 | OMAP_MCBSP_FSR_SRC_FSX, /* FSR from FSX pin */ | ||
| 39 | }; | 35 | }; |
| 40 | 36 | ||
| 41 | /* McBSP dividers */ | 37 | /* McBSP dividers */ |
| @@ -43,22 +39,6 @@ enum omap_mcbsp_div { | |||
| 43 | OMAP_MCBSP_CLKGDV, /* Sample rate generator divider */ | 39 | OMAP_MCBSP_CLKGDV, /* Sample rate generator divider */ |
| 44 | }; | 40 | }; |
| 45 | 41 | ||
| 46 | #if defined(CONFIG_SOC_OMAP2420) | ||
| 47 | #define NUM_LINKS 2 | ||
| 48 | #endif | ||
| 49 | #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) | ||
| 50 | #undef NUM_LINKS | ||
| 51 | #define NUM_LINKS 3 | ||
| 52 | #endif | ||
| 53 | #if defined(CONFIG_ARCH_OMAP4) | ||
| 54 | #undef NUM_LINKS | ||
| 55 | #define NUM_LINKS 4 | ||
| 56 | #endif | ||
| 57 | #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_OMAP2430) | ||
| 58 | #undef NUM_LINKS | ||
| 59 | #define NUM_LINKS 5 | ||
| 60 | #endif | ||
| 61 | |||
| 62 | int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd); | 42 | int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd); |
| 63 | 43 | ||
| 64 | #endif | 44 | #endif |
