aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-22 16:00:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-22 16:00:13 -0400
commitb2094ef840697bc8ca5d17a83b7e30fad5f1e9fa (patch)
tree64e5f7253b6a85b6d5d36f95c0d3c67c1798918d /arch/arm
parent424a6f6ef990b7e9f56f6627bfc6c46b493faeb4 (diff)
parent6681bc0deba495fad0d6fb349e40524abd1b1732 (diff)
Merge tag 'sound-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull updates of sound stuff from Takashi Iwai: "Here is the first big update chunk of sound stuff for 3.4-rc1. In the common sound infrastructure, there are a few changes for dynamic PCM support (used in ASoC) and a few clean-ups. Majority of changes are found, as usual, in HD-audio and ASoC. Some highlights of HD-audio changes: - All the long-standing static quirk codes for Realtek codec were finally removed by fixing and extending the Realtek auto-parser. - The mute-LED control is standardized over all HD-audio codec drivers using the extended vmaster hook. - The vmaster slave mixer elements are initialized to 0dB as default so that the user won't be annoyed by the silent output after updates, e.g. due to the additions of new elements. - Other many fix-ups for the misc HD-audio devices. In the ASoC side, this is a very active release, including a quite a few framework enhancements. Some highlights: - Support for widgets not associated with a CODEC, an important part of the dynamic PCM framework. - A library factoring out the common code shared by dmaengine based DMA drivers contributed by Lars-Peter Clausen. This will save a lot of code and make it much easier to deploy enhancements to dmaengine. - Support for binary controls, used for providing runtime configuration of algorithm coefficients. - A new DAPM widget type for regulator supplies allowing drivers for devices that can power down unused supplies while active to do without any per-driver code. - DAPM widgets for DAIs, initially giving a speed boost for playback startup and shutdown and also the basis for CODEC<->CODEC DAI link support. - Support for specifying the number of significant bits on audio interfaces, useful for allowing applications to know how much effort to put into generating data for a larger sample format. - Conversion of the FSI driver used on some SH processors to DMAEngine. - Conversion of EP93xx drivers to DMAEngine. - New CODEC drivers for Maxim MAX9768 and Wolfson Microelectronics WM2200. - Move audmux driver from arc/arm to sound/soc - McBSP move from arch/ to sound/ and updates Also, a few small updates and fixes for other drivers like au88x0, ymfpci, USB 6fire, USB usx2yaudio are included." * tag 'sound-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (446 commits) ASoC: wm8994: Provide VMID mode control and fix default sequence ASoC: wm8994: Add missing break in resume ASoC: wm_hubs: Don't actively manage LINEOUT_VMID_BUF ASoC: pxa-ssp: atomically set stream active masks ASoC: fsl: p1022ds: tell the WM8776 codec driver that it's the master ASoC: Samsung: Added to support mono recording ALSA: hda - Fix build with CONFIG_PM=n ALSA: au88x0 - Avoid possible Oops at unbinding ALSA: usb-audio - Fix build error by consitification of rate list ASoC: core: Fix obscure leak of runtime array ALSA: pcm - Avoid GFP_ATOMIC in snd_pcm_link() ALSA: pcm: Constify the list in snd_pcm_hw_constraint_list ASoC: wm8996: Add 44.1kHz support ALSA: hda - Fix build of patch_sigmatel.c without CONFIG_SND_HDA_POWER_SAVE ASoC: mx27vis-aic32x4: Convert it to platform driver ALSA: hda - fix printing of high HDMI sample rates ALSA: ymfpci - Fix legacy registers on S3/S4 resume ALSA: control - Fixe a trailing white space error ALSA: hda - Add expose_enum_ctl flag to snd_hda_add_vmaster_hook() ALSA: hda - Add "Mute-LED Mode" enum control ...
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-ep93xx/core.c19
-rw-r--r--arch/arm/mach-ep93xx/include/mach/platform.h2
-rw-r--r--arch/arm/mach-imx/Kconfig6
-rw-r--r--arch/arm/mach-imx/eukrea_mbimx27-baseboard.c20
-rw-r--r--arch/arm/mach-imx/eukrea_mbimxsd-baseboard.c1
-rw-r--r--arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c17
-rw-r--r--arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c17
-rw-r--r--arch/arm/mach-imx/mach-imx27_visstrim_m10.c1
-rw-r--r--arch/arm/mach-imx/mach-pca100.c13
-rw-r--r--arch/arm/mach-imx/mach-pcm043.c13
-rw-r--r--arch/arm/mach-imx/mm-imx21.c6
-rw-r--r--arch/arm/mach-imx/mm-imx25.c7
-rw-r--r--arch/arm/mach-imx/mm-imx27.c7
-rw-r--r--arch/arm/mach-imx/mm-imx3.c13
-rw-r--r--arch/arm/mach-imx/mm-imx5.c22
-rw-r--r--arch/arm/mach-kirkwood/openrd-setup.c6
-rw-r--r--arch/arm/mach-kirkwood/t5325-setup.c6
-rw-r--r--arch/arm/mach-omap1/Kconfig3
-rw-r--r--arch/arm/mach-omap1/Makefile4
-rw-r--r--arch/arm/mach-omap1/devices.c9
-rw-r--r--arch/arm/mach-omap1/mcbsp.c14
-rw-r--r--arch/arm/mach-omap2/Makefile4
-rw-r--r--arch/arm/mach-omap2/board-4430sdp.c29
-rw-r--r--arch/arm/mach-omap2/board-omap4panda.c60
-rw-r--r--arch/arm/mach-omap2/devices.c22
-rw-r--r--arch/arm/mach-omap2/mcbsp.c54
-rw-r--r--arch/arm/mach-s3c64xx/mach-crag6410-module.c1
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c30
-rw-r--r--arch/arm/mach-shmobile/board-mackerel.c18
-rw-r--r--arch/arm/plat-mxc/Kconfig6
-rw-r--r--arch/arm/plat-mxc/Makefile2
-rw-r--r--arch/arm/plat-mxc/audmux-v1.c64
-rw-r--r--arch/arm/plat-mxc/audmux-v2.c219
-rw-r--r--arch/arm/plat-mxc/include/mach/audmux.h60
-rw-r--r--arch/arm/plat-omap/Kconfig8
-rw-r--r--arch/arm/plat-omap/Makefile2
-rw-r--r--arch/arm/plat-omap/include/plat/mcbsp.h333
-rw-r--r--arch/arm/plat-omap/mcbsp.c1361
38 files changed, 233 insertions, 2246 deletions
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 24203f9a6796..b5c1dae8327f 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -817,23 +817,12 @@ void __init ep93xx_register_i2s(void)
817#define EP93XX_I2SCLKDIV_MASK (EP93XX_SYSCON_I2SCLKDIV_ORIDE | \ 817#define EP93XX_I2SCLKDIV_MASK (EP93XX_SYSCON_I2SCLKDIV_ORIDE | \
818 EP93XX_SYSCON_I2SCLKDIV_SPOL) 818 EP93XX_SYSCON_I2SCLKDIV_SPOL)
819 819
820int ep93xx_i2s_acquire(unsigned i2s_pins, unsigned i2s_config) 820int ep93xx_i2s_acquire(void)
821{ 821{
822 unsigned val; 822 unsigned val;
823 823
824 /* Sanity check */ 824 ep93xx_devcfg_set_clear(EP93XX_SYSCON_DEVCFG_I2SONAC97,
825 if (i2s_pins & ~EP93XX_SYSCON_DEVCFG_I2S_MASK) 825 EP93XX_SYSCON_DEVCFG_I2S_MASK);
826 return -EINVAL;
827 if (i2s_config & ~EP93XX_I2SCLKDIV_MASK)
828 return -EINVAL;
829
830 /* Must have only one of I2SONSSP/I2SONAC97 set */
831 if ((i2s_pins & EP93XX_SYSCON_DEVCFG_I2SONSSP) ==
832 (i2s_pins & EP93XX_SYSCON_DEVCFG_I2SONAC97))
833 return -EINVAL;
834
835 ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_I2S_MASK);
836 ep93xx_devcfg_set_bits(i2s_pins);
837 826
838 /* 827 /*
839 * This is potentially racy with the clock api for i2s_mclk, sclk and 828 * This is potentially racy with the clock api for i2s_mclk, sclk and
@@ -843,7 +832,7 @@ int ep93xx_i2s_acquire(unsigned i2s_pins, unsigned i2s_config)
843 */ 832 */
844 val = __raw_readl(EP93XX_SYSCON_I2SCLKDIV); 833 val = __raw_readl(EP93XX_SYSCON_I2SCLKDIV);
845 val &= ~EP93XX_I2SCLKDIV_MASK; 834 val &= ~EP93XX_I2SCLKDIV_MASK;
846 val |= i2s_config; 835 val |= EP93XX_SYSCON_I2SCLKDIV_ORIDE | EP93XX_SYSCON_I2SCLKDIV_SPOL;
847 ep93xx_syscon_swlocked_write(val, EP93XX_SYSCON_I2SCLKDIV); 836 ep93xx_syscon_swlocked_write(val, EP93XX_SYSCON_I2SCLKDIV);
848 837
849 return 0; 838 return 0;
diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h
index d4c934931f9d..ad63d4be693f 100644
--- a/arch/arm/mach-ep93xx/include/mach/platform.h
+++ b/arch/arm/mach-ep93xx/include/mach/platform.h
@@ -59,7 +59,7 @@ void ep93xx_register_keypad(struct ep93xx_keypad_platform_data *data);
59int ep93xx_keypad_acquire_gpio(struct platform_device *pdev); 59int ep93xx_keypad_acquire_gpio(struct platform_device *pdev);
60void ep93xx_keypad_release_gpio(struct platform_device *pdev); 60void ep93xx_keypad_release_gpio(struct platform_device *pdev);
61void ep93xx_register_i2s(void); 61void ep93xx_register_i2s(void);
62int ep93xx_i2s_acquire(unsigned i2s_pins, unsigned i2s_config); 62int ep93xx_i2s_acquire(void);
63void ep93xx_i2s_release(void); 63void ep93xx_i2s_release(void);
64void ep93xx_register_ac97(void); 64void ep93xx_register_ac97(void);
65 65
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 4defb97bbfc8..3919fba52ac8 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -46,7 +46,6 @@ config SOC_IMX21
46 bool 46 bool
47 select MACH_MX21 47 select MACH_MX21
48 select CPU_ARM926T 48 select CPU_ARM926T
49 select ARCH_MXC_AUDMUX_V1
50 select IMX_HAVE_DMA_V1 49 select IMX_HAVE_DMA_V1
51 select IMX_HAVE_IOMUX_V1 50 select IMX_HAVE_IOMUX_V1
52 select MXC_AVIC 51 select MXC_AVIC
@@ -55,7 +54,6 @@ config SOC_IMX25
55 bool 54 bool
56 select ARCH_MX25 55 select ARCH_MX25
57 select CPU_ARM926T 56 select CPU_ARM926T
58 select ARCH_MXC_AUDMUX_V2
59 select ARCH_MXC_IOMUX_V3 57 select ARCH_MXC_IOMUX_V3
60 select MXC_AVIC 58 select MXC_AVIC
61 59
@@ -63,7 +61,6 @@ config SOC_IMX27
63 bool 61 bool
64 select MACH_MX27 62 select MACH_MX27
65 select CPU_ARM926T 63 select CPU_ARM926T
66 select ARCH_MXC_AUDMUX_V1
67 select IMX_HAVE_DMA_V1 64 select IMX_HAVE_DMA_V1
68 select IMX_HAVE_IOMUX_V1 65 select IMX_HAVE_IOMUX_V1
69 select MXC_AVIC 66 select MXC_AVIC
@@ -72,7 +69,6 @@ config SOC_IMX31
72 bool 69 bool
73 select CPU_V6 70 select CPU_V6
74 select IMX_HAVE_PLATFORM_MXC_RNGA 71 select IMX_HAVE_PLATFORM_MXC_RNGA
75 select ARCH_MXC_AUDMUX_V2
76 select MXC_AVIC 72 select MXC_AVIC
77 select SMP_ON_UP if SMP 73 select SMP_ON_UP if SMP
78 74
@@ -80,7 +76,6 @@ config SOC_IMX35
80 bool 76 bool
81 select CPU_V6 77 select CPU_V6
82 select ARCH_MXC_IOMUX_V3 78 select ARCH_MXC_IOMUX_V3
83 select ARCH_MXC_AUDMUX_V2
84 select HAVE_EPIT 79 select HAVE_EPIT
85 select MXC_AVIC 80 select MXC_AVIC
86 select SMP_ON_UP if SMP 81 select SMP_ON_UP if SMP
@@ -89,7 +84,6 @@ config SOC_IMX5
89 select CPU_V7 84 select CPU_V7
90 select MXC_TZIC 85 select MXC_TZIC
91 select ARCH_MXC_IOMUX_V3 86 select ARCH_MXC_IOMUX_V3
92 select ARCH_MXC_AUDMUX_V2
93 select ARCH_HAS_CPUFREQ 87 select ARCH_HAS_CPUFREQ
94 select ARCH_MX5 88 select ARCH_MX5
95 bool 89 bool
diff --git a/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c b/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
index 5db3e1463af7..5f2f91d1798b 100644
--- a/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
+++ b/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
@@ -32,7 +32,6 @@
32#include <mach/common.h> 32#include <mach/common.h>
33#include <mach/iomux-mx27.h> 33#include <mach/iomux-mx27.h>
34#include <mach/hardware.h> 34#include <mach/hardware.h>
35#include <mach/audmux.h>
36 35
37#include "devices-imx27.h" 36#include "devices-imx27.h"
38 37
@@ -306,25 +305,6 @@ void __init eukrea_mbimx27_baseboard_init(void)
306 mxc_gpio_setup_multiple_pins(eukrea_mbimx27_pins, 305 mxc_gpio_setup_multiple_pins(eukrea_mbimx27_pins,
307 ARRAY_SIZE(eukrea_mbimx27_pins), "MBIMX27"); 306 ARRAY_SIZE(eukrea_mbimx27_pins), "MBIMX27");
308 307
309#if defined(CONFIG_SND_SOC_EUKREA_TLV320) \
310 || defined(CONFIG_SND_SOC_EUKREA_TLV320_MODULE)
311 /* SSI unit master I2S codec connected to SSI_PINS_4*/
312 mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
313 MXC_AUDMUX_V1_PCR_SYN |
314 MXC_AUDMUX_V1_PCR_TFSDIR |
315 MXC_AUDMUX_V1_PCR_TCLKDIR |
316 MXC_AUDMUX_V1_PCR_RFSDIR |
317 MXC_AUDMUX_V1_PCR_RCLKDIR |
318 MXC_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) |
319 MXC_AUDMUX_V1_PCR_RFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) |
320 MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4)
321 );
322 mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR3_SSI_PINS_4,
323 MXC_AUDMUX_V1_PCR_SYN |
324 MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0)
325 );
326#endif
327
328 imx27_add_imx_uart1(&uart_pdata); 308 imx27_add_imx_uart1(&uart_pdata);
329 imx27_add_imx_uart2(&uart_pdata); 309 imx27_add_imx_uart2(&uart_pdata);
330#if !defined(MACH_EUKREA_CPUIMX27_USEUART4) 310#if !defined(MACH_EUKREA_CPUIMX27_USEUART4)
diff --git a/arch/arm/mach-imx/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-imx/eukrea_mbimxsd-baseboard.c
index d817fc80b986..aaa592fdb9ce 100644
--- a/arch/arm/mach-imx/eukrea_mbimxsd-baseboard.c
+++ b/arch/arm/mach-imx/eukrea_mbimxsd-baseboard.c
@@ -37,7 +37,6 @@
37#include <mach/hardware.h> 37#include <mach/hardware.h>
38#include <mach/common.h> 38#include <mach/common.h>
39#include <mach/iomux-mx51.h> 39#include <mach/iomux-mx51.h>
40#include <mach/audmux.h>
41 40
42#include "devices-imx51.h" 41#include "devices-imx51.h"
43 42
diff --git a/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c b/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c
index 66e8726253fa..2cf603e11c4f 100644
--- a/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c
+++ b/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c
@@ -31,7 +31,6 @@
31#include <asm/mach-types.h> 31#include <asm/mach-types.h>
32#include <asm/mach/arch.h> 32#include <asm/mach/arch.h>
33#include <mach/mx25.h> 33#include <mach/mx25.h>
34#include <mach/audmux.h>
35 34
36#include "devices-imx25.h" 35#include "devices-imx25.h"
37 36
@@ -241,22 +240,6 @@ void __init eukrea_mbimxsd25_baseboard_init(void)
241 ARRAY_SIZE(eukrea_mbimxsd_pads))) 240 ARRAY_SIZE(eukrea_mbimxsd_pads)))
242 printk(KERN_ERR "error setting mbimxsd pads !\n"); 241 printk(KERN_ERR "error setting mbimxsd pads !\n");
243 242
244#if defined(CONFIG_SND_SOC_EUKREA_TLV320)
245 /* SSI unit master I2S codec connected to SSI_AUD5*/
246 mxc_audmux_v2_configure_port(0,
247 MXC_AUDMUX_V2_PTCR_SYN |
248 MXC_AUDMUX_V2_PTCR_TFSDIR |
249 MXC_AUDMUX_V2_PTCR_TFSEL(4) |
250 MXC_AUDMUX_V2_PTCR_TCLKDIR |
251 MXC_AUDMUX_V2_PTCR_TCSEL(4),
252 MXC_AUDMUX_V2_PDCR_RXDSEL(4)
253 );
254 mxc_audmux_v2_configure_port(4,
255 MXC_AUDMUX_V2_PTCR_SYN,
256 MXC_AUDMUX_V2_PDCR_RXDSEL(0)
257 );
258#endif
259
260 imx25_add_imx_uart1(&uart_pdata); 243 imx25_add_imx_uart1(&uart_pdata);
261 imx25_add_imx_fb(&eukrea_mximxsd_fb_pdata); 244 imx25_add_imx_fb(&eukrea_mximxsd_fb_pdata);
262 imx25_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata); 245 imx25_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);
diff --git a/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c b/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c
index 0f0af02b3182..fd8bf8a425a7 100644
--- a/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c
+++ b/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c
@@ -38,7 +38,6 @@
38#include <mach/hardware.h> 38#include <mach/hardware.h>
39#include <mach/common.h> 39#include <mach/common.h>
40#include <mach/iomux-mx35.h> 40#include <mach/iomux-mx35.h>
41#include <mach/audmux.h>
42 41
43#include "devices-imx35.h" 42#include "devices-imx35.h"
44 43
@@ -252,22 +251,6 @@ void __init eukrea_mbimxsd35_baseboard_init(void)
252 ARRAY_SIZE(eukrea_mbimxsd_pads))) 251 ARRAY_SIZE(eukrea_mbimxsd_pads)))
253 printk(KERN_ERR "error setting mbimxsd pads !\n"); 252 printk(KERN_ERR "error setting mbimxsd pads !\n");
254 253
255#if defined(CONFIG_SND_SOC_EUKREA_TLV320)
256 /* SSI unit master I2S codec connected to SSI_AUD4 */
257 mxc_audmux_v2_configure_port(0,
258 MXC_AUDMUX_V2_PTCR_SYN |
259 MXC_AUDMUX_V2_PTCR_TFSDIR |
260 MXC_AUDMUX_V2_PTCR_TFSEL(3) |
261 MXC_AUDMUX_V2_PTCR_TCLKDIR |
262 MXC_AUDMUX_V2_PTCR_TCSEL(3),
263 MXC_AUDMUX_V2_PDCR_RXDSEL(3)
264 );
265 mxc_audmux_v2_configure_port(3,
266 MXC_AUDMUX_V2_PTCR_SYN,
267 MXC_AUDMUX_V2_PDCR_RXDSEL(0)
268 );
269#endif
270
271 imx35_add_imx_uart1(&uart_pdata); 254 imx35_add_imx_uart1(&uart_pdata);
272 imx35_add_ipu_core(&mx3_ipu_data); 255 imx35_add_ipu_core(&mx3_ipu_data);
273 imx35_add_mx3_sdc_fb(&mx3fb_pdata); 256 imx35_add_mx3_sdc_fb(&mx3fb_pdata);
diff --git a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
index c2766ae02b4f..428459fbca4b 100644
--- a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
+++ b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
@@ -263,6 +263,7 @@ static void __init visstrim_m10_board_init(void)
263 imx27_add_fec(NULL); 263 imx27_add_fec(NULL);
264 imx_add_gpio_keys(&visstrim_gpio_keys_platform_data); 264 imx_add_gpio_keys(&visstrim_gpio_keys_platform_data);
265 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); 265 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
266 imx_add_platform_device("mx27vis", 0, NULL, 0, NULL, 0);
266} 267}
267 268
268static void __init visstrim_m10_timer_init(void) 269static void __init visstrim_m10_timer_init(void)
diff --git a/arch/arm/mach-imx/mach-pca100.c b/arch/arm/mach-imx/mach-pca100.c
index d3b9c6b5edde..541152e450c4 100644
--- a/arch/arm/mach-imx/mach-pca100.c
+++ b/arch/arm/mach-imx/mach-pca100.c
@@ -36,7 +36,6 @@
36#include <mach/hardware.h> 36#include <mach/hardware.h>
37#include <mach/iomux-mx27.h> 37#include <mach/iomux-mx27.h>
38#include <asm/mach/time.h> 38#include <asm/mach/time.h>
39#include <mach/audmux.h>
40#include <mach/irqs.h> 39#include <mach/irqs.h>
41#include <mach/ulpi.h> 40#include <mach/ulpi.h>
42 41
@@ -359,18 +358,6 @@ static void __init pca100_init(void)
359 358
360 imx27_soc_init(); 359 imx27_soc_init();
361 360
362 /* SSI unit */
363 mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
364 MXC_AUDMUX_V1_PCR_SYN | /* 4wire mode */
365 MXC_AUDMUX_V1_PCR_TFCSEL(3) |
366 MXC_AUDMUX_V1_PCR_TCLKDIR | /* clock is output */
367 MXC_AUDMUX_V1_PCR_RXDSEL(3));
368 mxc_audmux_v1_configure_port(3,
369 MXC_AUDMUX_V1_PCR_SYN | /* 4wire mode */
370 MXC_AUDMUX_V1_PCR_TFCSEL(0) |
371 MXC_AUDMUX_V1_PCR_TFSDIR |
372 MXC_AUDMUX_V1_PCR_RXDSEL(0));
373
374 ret = mxc_gpio_setup_multiple_pins(pca100_pins, 361 ret = mxc_gpio_setup_multiple_pins(pca100_pins,
375 ARRAY_SIZE(pca100_pins), "PCA100"); 362 ARRAY_SIZE(pca100_pins), "PCA100");
376 if (ret) 363 if (ret)
diff --git a/arch/arm/mach-imx/mach-pcm043.c b/arch/arm/mach-imx/mach-pcm043.c
index 06dc106519ae..237474fcca23 100644
--- a/arch/arm/mach-imx/mach-pcm043.c
+++ b/arch/arm/mach-imx/mach-pcm043.c
@@ -37,7 +37,6 @@
37#include <mach/common.h> 37#include <mach/common.h>
38#include <mach/iomux-mx35.h> 38#include <mach/iomux-mx35.h>
39#include <mach/ulpi.h> 39#include <mach/ulpi.h>
40#include <mach/audmux.h>
41 40
42#include "devices-imx35.h" 41#include "devices-imx35.h"
43 42
@@ -362,18 +361,6 @@ static void __init pcm043_init(void)
362 361
363 mxc_iomux_v3_setup_multiple_pads(pcm043_pads, ARRAY_SIZE(pcm043_pads)); 362 mxc_iomux_v3_setup_multiple_pads(pcm043_pads, ARRAY_SIZE(pcm043_pads));
364 363
365 mxc_audmux_v2_configure_port(3,
366 MXC_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
367 MXC_AUDMUX_V2_PTCR_TFSEL(0) |
368 MXC_AUDMUX_V2_PTCR_TFSDIR,
369 MXC_AUDMUX_V2_PDCR_RXDSEL(0));
370
371 mxc_audmux_v2_configure_port(0,
372 MXC_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
373 MXC_AUDMUX_V2_PTCR_TCSEL(3) |
374 MXC_AUDMUX_V2_PTCR_TCLKDIR, /* clock is output */
375 MXC_AUDMUX_V2_PDCR_RXDSEL(3));
376
377 imx35_add_fec(NULL); 364 imx35_add_fec(NULL);
378 platform_add_devices(devices, ARRAY_SIZE(devices)); 365 platform_add_devices(devices, ARRAY_SIZE(devices));
379 imx35_add_imx2_wdt(NULL); 366 imx35_add_imx2_wdt(NULL);
diff --git a/arch/arm/mach-imx/mm-imx21.c b/arch/arm/mach-imx/mm-imx21.c
index 3f05dfebacc9..14d540edfd1e 100644
--- a/arch/arm/mach-imx/mm-imx21.c
+++ b/arch/arm/mach-imx/mm-imx21.c
@@ -75,6 +75,10 @@ void __init mx21_init_irq(void)
75 mxc_init_irq(MX21_IO_ADDRESS(MX21_AVIC_BASE_ADDR)); 75 mxc_init_irq(MX21_IO_ADDRESS(MX21_AVIC_BASE_ADDR));
76} 76}
77 77
78static const struct resource imx21_audmux_res[] __initconst = {
79 DEFINE_RES_MEM(MX21_AUDMUX_BASE_ADDR, SZ_4K),
80};
81
78void __init imx21_soc_init(void) 82void __init imx21_soc_init(void)
79{ 83{
80 mxc_register_gpio("imx21-gpio", 0, MX21_GPIO1_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0); 84 mxc_register_gpio("imx21-gpio", 0, MX21_GPIO1_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
@@ -85,4 +89,6 @@ void __init imx21_soc_init(void)
85 mxc_register_gpio("imx21-gpio", 5, MX21_GPIO6_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0); 89 mxc_register_gpio("imx21-gpio", 5, MX21_GPIO6_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
86 90
87 imx_add_imx_dma(); 91 imx_add_imx_dma();
92 platform_device_register_simple("imx21-audmux", 0, imx21_audmux_res,
93 ARRAY_SIZE(imx21_audmux_res));
88} 94}
diff --git a/arch/arm/mach-imx/mm-imx25.c b/arch/arm/mach-imx/mm-imx25.c
index cc4d152bd9bd..153b457acdc0 100644
--- a/arch/arm/mach-imx/mm-imx25.c
+++ b/arch/arm/mach-imx/mm-imx25.c
@@ -83,6 +83,10 @@ static struct sdma_platform_data imx25_sdma_pdata __initdata = {
83 .script_addrs = &imx25_sdma_script, 83 .script_addrs = &imx25_sdma_script,
84}; 84};
85 85
86static const struct resource imx25_audmux_res[] __initconst = {
87 DEFINE_RES_MEM(MX25_AUDMUX_BASE_ADDR, SZ_16K),
88};
89
86void __init imx25_soc_init(void) 90void __init imx25_soc_init(void)
87{ 91{
88 /* i.mx25 has the i.mx31 type gpio */ 92 /* i.mx25 has the i.mx31 type gpio */
@@ -93,4 +97,7 @@ void __init imx25_soc_init(void)
93 97
94 /* i.mx25 has the i.mx35 type sdma */ 98 /* i.mx25 has the i.mx35 type sdma */
95 imx_add_imx_sdma("imx35-sdma", MX25_SDMA_BASE_ADDR, MX25_INT_SDMA, &imx25_sdma_pdata); 99 imx_add_imx_sdma("imx35-sdma", MX25_SDMA_BASE_ADDR, MX25_INT_SDMA, &imx25_sdma_pdata);
100 /* i.mx25 has the i.mx31 type audmux */
101 platform_device_register_simple("imx31-audmux", 0, imx25_audmux_res,
102 ARRAY_SIZE(imx25_audmux_res));
96} 103}
diff --git a/arch/arm/mach-imx/mm-imx27.c b/arch/arm/mach-imx/mm-imx27.c
index 96dd1f5ea7bd..8cb3f5e3e569 100644
--- a/arch/arm/mach-imx/mm-imx27.c
+++ b/arch/arm/mach-imx/mm-imx27.c
@@ -75,6 +75,10 @@ void __init mx27_init_irq(void)
75 mxc_init_irq(MX27_IO_ADDRESS(MX27_AVIC_BASE_ADDR)); 75 mxc_init_irq(MX27_IO_ADDRESS(MX27_AVIC_BASE_ADDR));
76} 76}
77 77
78static const struct resource imx27_audmux_res[] __initconst = {
79 DEFINE_RES_MEM(MX27_AUDMUX_BASE_ADDR, SZ_4K),
80};
81
78void __init imx27_soc_init(void) 82void __init imx27_soc_init(void)
79{ 83{
80 /* i.mx27 has the i.mx21 type gpio */ 84 /* i.mx27 has the i.mx21 type gpio */
@@ -86,4 +90,7 @@ void __init imx27_soc_init(void)
86 mxc_register_gpio("imx21-gpio", 5, MX27_GPIO6_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0); 90 mxc_register_gpio("imx21-gpio", 5, MX27_GPIO6_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
87 91
88 imx_add_imx_dma(); 92 imx_add_imx_dma();
93 /* imx27 has the imx21 type audmux */
94 platform_device_register_simple("imx21-audmux", 0, imx27_audmux_res,
95 ARRAY_SIZE(imx27_audmux_res));
89} 96}
diff --git a/arch/arm/mach-imx/mm-imx3.c b/arch/arm/mach-imx/mm-imx3.c
index 31807d2a8b7b..2530c151b7b3 100644
--- a/arch/arm/mach-imx/mm-imx3.c
+++ b/arch/arm/mach-imx/mm-imx3.c
@@ -158,6 +158,10 @@ static struct sdma_platform_data imx31_sdma_pdata __initdata = {
158 .script_addrs = &imx31_to2_sdma_script, 158 .script_addrs = &imx31_to2_sdma_script,
159}; 159};
160 160
161static const struct resource imx31_audmux_res[] __initconst = {
162 DEFINE_RES_MEM(MX31_AUDMUX_BASE_ADDR, SZ_16K),
163};
164
161void __init imx31_soc_init(void) 165void __init imx31_soc_init(void)
162{ 166{
163 int to_version = mx31_revision() >> 4; 167 int to_version = mx31_revision() >> 4;
@@ -175,6 +179,8 @@ void __init imx31_soc_init(void)
175 } 179 }
176 180
177 imx_add_imx_sdma("imx31-sdma", MX31_SDMA_BASE_ADDR, MX31_INT_SDMA, &imx31_sdma_pdata); 181 imx_add_imx_sdma("imx31-sdma", MX31_SDMA_BASE_ADDR, MX31_INT_SDMA, &imx31_sdma_pdata);
182 platform_device_register_simple("imx31-audmux", 0, imx31_audmux_res,
183 ARRAY_SIZE(imx31_audmux_res));
178} 184}
179#endif /* ifdef CONFIG_SOC_IMX31 */ 185#endif /* ifdef CONFIG_SOC_IMX31 */
180 186
@@ -241,6 +247,10 @@ static struct sdma_platform_data imx35_sdma_pdata __initdata = {
241 .script_addrs = &imx35_to2_sdma_script, 247 .script_addrs = &imx35_to2_sdma_script,
242}; 248};
243 249
250static const struct resource imx35_audmux_res[] __initconst = {
251 DEFINE_RES_MEM(MX35_AUDMUX_BASE_ADDR, SZ_16K),
252};
253
244void __init imx35_soc_init(void) 254void __init imx35_soc_init(void)
245{ 255{
246 int to_version = mx35_revision() >> 4; 256 int to_version = mx35_revision() >> 4;
@@ -259,5 +269,8 @@ void __init imx35_soc_init(void)
259 } 269 }
260 270
261 imx_add_imx_sdma("imx35-sdma", MX35_SDMA_BASE_ADDR, MX35_INT_SDMA, &imx35_sdma_pdata); 271 imx_add_imx_sdma("imx35-sdma", MX35_SDMA_BASE_ADDR, MX35_INT_SDMA, &imx35_sdma_pdata);
272 /* i.mx35 has the i.mx31 type audmux */
273 platform_device_register_simple("imx31-audmux", 0, imx35_audmux_res,
274 ARRAY_SIZE(imx35_audmux_res));
262} 275}
263#endif /* ifdef CONFIG_SOC_IMX35 */ 276#endif /* ifdef CONFIG_SOC_IMX35 */
diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c
index bc17dfea3817..90d7880bb372 100644
--- a/arch/arm/mach-imx/mm-imx5.c
+++ b/arch/arm/mach-imx/mm-imx5.c
@@ -170,6 +170,18 @@ static struct sdma_platform_data imx53_sdma_pdata __initdata = {
170 .script_addrs = &imx53_sdma_script, 170 .script_addrs = &imx53_sdma_script,
171}; 171};
172 172
173static const struct resource imx50_audmux_res[] __initconst = {
174 DEFINE_RES_MEM(MX50_AUDMUX_BASE_ADDR, SZ_16K),
175};
176
177static const struct resource imx51_audmux_res[] __initconst = {
178 DEFINE_RES_MEM(MX51_AUDMUX_BASE_ADDR, SZ_16K),
179};
180
181static const struct resource imx53_audmux_res[] __initconst = {
182 DEFINE_RES_MEM(MX53_AUDMUX_BASE_ADDR, SZ_16K),
183};
184
173void __init imx50_soc_init(void) 185void __init imx50_soc_init(void)
174{ 186{
175 /* i.mx50 has the i.mx31 type gpio */ 187 /* i.mx50 has the i.mx31 type gpio */
@@ -179,6 +191,10 @@ void __init imx50_soc_init(void)
179 mxc_register_gpio("imx31-gpio", 3, MX50_GPIO4_BASE_ADDR, SZ_16K, MX50_INT_GPIO4_LOW, MX50_INT_GPIO4_HIGH); 191 mxc_register_gpio("imx31-gpio", 3, MX50_GPIO4_BASE_ADDR, SZ_16K, MX50_INT_GPIO4_LOW, MX50_INT_GPIO4_HIGH);
180 mxc_register_gpio("imx31-gpio", 4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH); 192 mxc_register_gpio("imx31-gpio", 4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH);
181 mxc_register_gpio("imx31-gpio", 5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH); 193 mxc_register_gpio("imx31-gpio", 5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH);
194
195 /* i.mx50 has the i.mx31 type audmux */
196 platform_device_register_simple("imx31-audmux", 0, imx50_audmux_res,
197 ARRAY_SIZE(imx50_audmux_res));
182} 198}
183 199
184void __init imx51_soc_init(void) 200void __init imx51_soc_init(void)
@@ -191,6 +207,9 @@ void __init imx51_soc_init(void)
191 207
192 /* i.mx51 has the i.mx35 type sdma */ 208 /* i.mx51 has the i.mx35 type sdma */
193 imx_add_imx_sdma("imx35-sdma", MX51_SDMA_BASE_ADDR, MX51_INT_SDMA, &imx51_sdma_pdata); 209 imx_add_imx_sdma("imx35-sdma", MX51_SDMA_BASE_ADDR, MX51_INT_SDMA, &imx51_sdma_pdata);
210 /* i.mx51 has the i.mx31 type audmux */
211 platform_device_register_simple("imx31-audmux", 0, imx51_audmux_res,
212 ARRAY_SIZE(imx51_audmux_res));
194} 213}
195 214
196void __init imx53_soc_init(void) 215void __init imx53_soc_init(void)
@@ -206,4 +225,7 @@ void __init imx53_soc_init(void)
206 225
207 /* i.mx53 has the i.mx35 type sdma */ 226 /* i.mx53 has the i.mx35 type sdma */
208 imx_add_imx_sdma("imx35-sdma", MX53_SDMA_BASE_ADDR, MX53_INT_SDMA, &imx53_sdma_pdata); 227 imx_add_imx_sdma("imx35-sdma", MX53_SDMA_BASE_ADDR, MX53_INT_SDMA, &imx53_sdma_pdata);
228 /* i.mx53 has the i.mx31 type audmux */
229 platform_device_register_simple("imx31-audmux", 0, imx53_audmux_res,
230 ARRAY_SIZE(imx53_audmux_res));
209} 231}
diff --git a/arch/arm/mach-kirkwood/openrd-setup.c b/arch/arm/mach-kirkwood/openrd-setup.c
index 01f8c8992880..7e99c3f340fc 100644
--- a/arch/arm/mach-kirkwood/openrd-setup.c
+++ b/arch/arm/mach-kirkwood/openrd-setup.c
@@ -83,6 +83,11 @@ static struct i2c_board_info i2c_board_info[] __initdata = {
83 }, 83 },
84}; 84};
85 85
86static struct platform_device openrd_client_audio_device = {
87 .name = "openrd-client-audio",
88 .id = -1,
89};
90
86static int __initdata uart1; 91static int __initdata uart1;
87 92
88static int __init sd_uart_selection(char *str) 93static int __init sd_uart_selection(char *str)
@@ -172,6 +177,7 @@ static void __init openrd_init(void)
172 kirkwood_i2c_init(); 177 kirkwood_i2c_init();
173 178
174 if (machine_is_openrd_client() || machine_is_openrd_ultimate()) { 179 if (machine_is_openrd_client() || machine_is_openrd_ultimate()) {
180 platform_device_register(&openrd_client_audio_device);
175 i2c_register_board_info(0, i2c_board_info, 181 i2c_register_board_info(0, i2c_board_info,
176 ARRAY_SIZE(i2c_board_info)); 182 ARRAY_SIZE(i2c_board_info));
177 kirkwood_audio_init(); 183 kirkwood_audio_init();
diff --git a/arch/arm/mach-kirkwood/t5325-setup.c b/arch/arm/mach-kirkwood/t5325-setup.c
index 966b2b3bb813..f9d2a11b7f96 100644
--- a/arch/arm/mach-kirkwood/t5325-setup.c
+++ b/arch/arm/mach-kirkwood/t5325-setup.c
@@ -106,6 +106,11 @@ static struct platform_device hp_t5325_button_device = {
106 } 106 }
107}; 107};
108 108
109static struct platform_device hp_t5325_audio_device = {
110 .name = "t5325-audio",
111 .id = -1,
112};
113
109static unsigned int hp_t5325_mpp_config[] __initdata = { 114static unsigned int hp_t5325_mpp_config[] __initdata = {
110 MPP0_NF_IO2, 115 MPP0_NF_IO2,
111 MPP1_SPI_MOSI, 116 MPP1_SPI_MOSI,
@@ -179,6 +184,7 @@ static void __init hp_t5325_init(void)
179 kirkwood_sata_init(&hp_t5325_sata_data); 184 kirkwood_sata_init(&hp_t5325_sata_data);
180 kirkwood_ehci_init(); 185 kirkwood_ehci_init();
181 platform_device_register(&hp_t5325_button_device); 186 platform_device_register(&hp_t5325_button_device);
187 platform_device_register(&hp_t5325_audio_device);
182 188
183 i2c_register_board_info(0, i2c_board_info, ARRAY_SIZE(i2c_board_info)); 189 i2c_register_board_info(0, i2c_board_info, ARRAY_SIZE(i2c_board_info));
184 kirkwood_audio_init(); 190 kirkwood_audio_init();
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index 4f8d66f044e7..922ab0dc2bcd 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -37,7 +37,6 @@ comment "OMAP Board Type"
37config MACH_OMAP_INNOVATOR 37config MACH_OMAP_INNOVATOR
38 bool "TI Innovator" 38 bool "TI Innovator"
39 depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX) 39 depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX)
40 select OMAP_MCBSP
41 help 40 help
42 TI OMAP 1510 or 1610 Innovator board support. Say Y here if you 41 TI OMAP 1510 or 1610 Innovator board support. Say Y here if you
43 have such a board. 42 have such a board.
@@ -45,7 +44,6 @@ config MACH_OMAP_INNOVATOR
45config MACH_OMAP_H2 44config MACH_OMAP_H2
46 bool "TI H2 Support" 45 bool "TI H2 Support"
47 depends on ARCH_OMAP1 && ARCH_OMAP16XX 46 depends on ARCH_OMAP1 && ARCH_OMAP16XX
48 select OMAP_MCBSP
49 help 47 help
50 TI OMAP 1610/1611B H2 board support. Say Y here if you have such 48 TI OMAP 1610/1611B H2 board support. Say Y here if you have such
51 a board. 49 a board.
@@ -72,7 +70,6 @@ config MACH_HERALD
72config MACH_OMAP_OSK 70config MACH_OMAP_OSK
73 bool "TI OSK Support" 71 bool "TI OSK Support"
74 depends on ARCH_OMAP1 && ARCH_OMAP16XX 72 depends on ARCH_OMAP1 && ARCH_OMAP16XX
75 select OMAP_MCBSP
76 help 73 help
77 TI OMAP 5912 OSK (OMAP Starter Kit) board support. Say Y here 74 TI OMAP 5912 OSK (OMAP Starter Kit) board support. Say Y here
78 if you have such a board. 75 if you have such a board.
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
index 11c85cd2731a..9923f92b5450 100644
--- a/arch/arm/mach-omap1/Makefile
+++ b/arch/arm/mach-omap1/Makefile
@@ -6,7 +6,9 @@
6obj-y := io.o id.o sram.o time.o irq.o mux.o flash.o serial.o devices.o dma.o 6obj-y := io.o id.o sram.o time.o irq.o mux.o flash.o serial.o devices.o dma.o
7obj-y += clock.o clock_data.o opp_data.o reset.o pm_bus.o timer.o 7obj-y += clock.o clock_data.o opp_data.o reset.o pm_bus.o timer.o
8 8
9obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o 9ifneq ($(CONFIG_SND_OMAP_SOC_MCBSP),)
10obj-y += mcbsp.o
11endif
10 12
11obj-$(CONFIG_OMAP_32K_TIMER) += timer32k.o 13obj-$(CONFIG_OMAP_32K_TIMER) += timer32k.o
12 14
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index 1d76a63c0983..187b2fe132e9 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -28,7 +28,6 @@
28#include <plat/mux.h> 28#include <plat/mux.h>
29#include <plat/mmc.h> 29#include <plat/mmc.h>
30#include <plat/omap7xx.h> 30#include <plat/omap7xx.h>
31#include <plat/mcbsp.h>
32 31
33#include "clock.h" 32#include "clock.h"
34 33
@@ -250,16 +249,8 @@ static struct platform_device omap_pcm = {
250 .id = -1, 249 .id = -1,
251}; 250};
252 251
253OMAP_MCBSP_PLATFORM_DEVICE(1);
254OMAP_MCBSP_PLATFORM_DEVICE(2);
255OMAP_MCBSP_PLATFORM_DEVICE(3);
256
257static void omap_init_audio(void) 252static void omap_init_audio(void)
258{ 253{
259 platform_device_register(&omap_mcbsp1);
260 platform_device_register(&omap_mcbsp2);
261 if (!cpu_is_omap7xx())
262 platform_device_register(&omap_mcbsp3);
263 platform_device_register(&omap_pcm); 254 platform_device_register(&omap_pcm);
264} 255}
265 256
diff --git a/arch/arm/mach-omap1/mcbsp.c b/arch/arm/mach-omap1/mcbsp.c
index 91f9abbd3250..3e8410a99990 100644
--- a/arch/arm/mach-omap1/mcbsp.c
+++ b/arch/arm/mach-omap1/mcbsp.c
@@ -420,18 +420,6 @@ static int __init omap1_mcbsp_init(void)
420 return -ENODEV; 420 return -ENODEV;
421 421
422 if (cpu_is_omap7xx()) 422 if (cpu_is_omap7xx())
423 omap_mcbsp_count = OMAP7XX_MCBSP_COUNT;
424 else if (cpu_is_omap15xx())
425 omap_mcbsp_count = OMAP15XX_MCBSP_COUNT;
426 else if (cpu_is_omap16xx())
427 omap_mcbsp_count = OMAP16XX_MCBSP_COUNT;
428
429 mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *),
430 GFP_KERNEL);
431 if (!mcbsp_ptr)
432 return -ENOMEM;
433
434 if (cpu_is_omap7xx())
435 omap_mcbsp_register_board_cfg(omap7xx_mcbsp_res_0, 423 omap_mcbsp_register_board_cfg(omap7xx_mcbsp_res_0,
436 OMAP7XX_MCBSP_RES_SZ, 424 OMAP7XX_MCBSP_RES_SZ,
437 omap7xx_mcbsp_pdata, 425 omap7xx_mcbsp_pdata,
@@ -449,7 +437,7 @@ static int __init omap1_mcbsp_init(void)
449 omap16xx_mcbsp_pdata, 437 omap16xx_mcbsp_pdata,
450 OMAP16XX_MCBSP_COUNT); 438 OMAP16XX_MCBSP_COUNT);
451 439
452 return omap_mcbsp_init(); 440 return 0;
453} 441}
454 442
455arch_initcall(omap1_mcbsp_init); 443arch_initcall(omap1_mcbsp_init);
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index bd76394ccaf8..06326a6e460d 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -17,7 +17,9 @@ obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common)
17obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) $(secure-common) 17obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) $(secure-common)
18obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common) $(secure-common) 18obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common) $(secure-common)
19 19
20obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o 20ifneq ($(CONFIG_SND_OMAP_SOC_MCBSP),)
21obj-y += mcbsp.o
22endif
21 23
22obj-$(CONFIG_TWL4030_CORE) += omap_twl.o 24obj-$(CONFIG_TWL4030_CORE) += omap_twl.o
23 25
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 4e9071589bfb..90c76d340fb3 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -41,6 +41,7 @@
41#include <video/omap-panel-nokia-dsi.h> 41#include <video/omap-panel-nokia-dsi.h>
42#include <video/omap-panel-picodlp.h> 42#include <video/omap-panel-picodlp.h>
43#include <linux/wl12xx.h> 43#include <linux/wl12xx.h>
44#include <linux/platform_data/omap-abe-twl6040.h>
44 45
45#include "mux.h" 46#include "mux.h"
46#include "hsmmc.h" 47#include "hsmmc.h"
@@ -378,12 +379,40 @@ static struct platform_device sdp4430_dmic_codec = {
378 .id = -1, 379 .id = -1,
379}; 380};
380 381
382static struct omap_abe_twl6040_data sdp4430_abe_audio_data = {
383 .card_name = "SDP4430",
384 .has_hs = ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
385 .has_hf = ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
386 .has_ep = 1,
387 .has_aux = ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
388 .has_vibra = ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
389
390 .has_dmic = 1,
391 .has_hsmic = 1,
392 .has_mainmic = 1,
393 .has_submic = 1,
394 .has_afm = ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
395
396 .jack_detection = 1,
397 /* MCLK input is 38.4MHz */
398 .mclk_freq = 38400000,
399};
400
401static struct platform_device sdp4430_abe_audio = {
402 .name = "omap-abe-twl6040",
403 .id = -1,
404 .dev = {
405 .platform_data = &sdp4430_abe_audio_data,
406 },
407};
408
381static struct platform_device *sdp4430_devices[] __initdata = { 409static struct platform_device *sdp4430_devices[] __initdata = {
382 &sdp4430_gpio_keys_device, 410 &sdp4430_gpio_keys_device,
383 &sdp4430_leds_gpio, 411 &sdp4430_leds_gpio,
384 &sdp4430_leds_pwm, 412 &sdp4430_leds_pwm,
385 &sdp4430_vbat, 413 &sdp4430_vbat,
386 &sdp4430_dmic_codec, 414 &sdp4430_dmic_codec,
415 &sdp4430_abe_audio,
387}; 416};
388 417
389static struct omap_musb_board_data musb_board_data = { 418static struct omap_musb_board_data musb_board_data = {
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 28fc271f7031..e4415917693f 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -28,6 +28,7 @@
28#include <linux/regulator/machine.h> 28#include <linux/regulator/machine.h>
29#include <linux/regulator/fixed.h> 29#include <linux/regulator/fixed.h>
30#include <linux/wl12xx.h> 30#include <linux/wl12xx.h>
31#include <linux/platform_data/omap-abe-twl6040.h>
31 32
32#include <mach/hardware.h> 33#include <mach/hardware.h>
33#include <asm/hardware/gic.h> 34#include <asm/hardware/gic.h>
@@ -91,9 +92,34 @@ static struct platform_device leds_gpio = {
91 }, 92 },
92}; 93};
93 94
95static struct omap_abe_twl6040_data panda_abe_audio_data = {
96 /* Audio out */
97 .has_hs = ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
98 /* HandsFree through expasion connector */
99 .has_hf = ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
100 /* PandaBoard: FM TX, PandaBoardES: can be connected to audio out */
101 .has_aux = ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
102 /* PandaBoard: FM RX, PandaBoardES: audio in */
103 .has_afm = ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
104 /* No jack detection. */
105 .jack_detection = 0,
106 /* MCLK input is 38.4MHz */
107 .mclk_freq = 38400000,
108
109};
110
111static struct platform_device panda_abe_audio = {
112 .name = "omap-abe-twl6040",
113 .id = -1,
114 .dev = {
115 .platform_data = &panda_abe_audio_data,
116 },
117};
118
94static struct platform_device *panda_devices[] __initdata = { 119static struct platform_device *panda_devices[] __initdata = {
95 &leds_gpio, 120 &leds_gpio,
96 &wl1271_device, 121 &wl1271_device,
122 &panda_abe_audio,
97}; 123};
98 124
99static const struct usbhs_omap_board_data usbhs_bdata __initconst = { 125static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
@@ -252,8 +278,25 @@ static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
252 return 0; 278 return 0;
253} 279}
254 280
281static struct twl4030_codec_data twl6040_codec = {
282 /* single-step ramp for headset and handsfree */
283 .hs_left_step = 0x0f,
284 .hs_right_step = 0x0f,
285 .hf_left_step = 0x1d,
286 .hf_right_step = 0x1d,
287};
288
289static struct twl4030_audio_data twl6040_audio = {
290 .codec = &twl6040_codec,
291 .audpwron_gpio = 127,
292 .naudint_irq = OMAP44XX_IRQ_SYS_2N,
293 .irq_base = TWL6040_CODEC_IRQ_BASE,
294};
295
255/* Panda board uses the common PMIC configuration */ 296/* Panda board uses the common PMIC configuration */
256static struct twl4030_platform_data omap4_panda_twldata; 297static struct twl4030_platform_data omap4_panda_twldata = {
298 .audio = &twl6040_audio,
299};
257 300
258/* 301/*
259 * Display monitor features are burnt in their EEPROM as EDID data. The EEPROM 302 * Display monitor features are burnt in their EEPROM as EDID data. The EEPROM
@@ -485,6 +528,20 @@ void omap4_panda_display_init(void)
485 omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN); 528 omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN);
486} 529}
487 530
531static void omap4_panda_init_rev(void)
532{
533 if (cpu_is_omap443x()) {
534 /* PandaBoard 4430 */
535 /* ASoC audio configuration */
536 panda_abe_audio_data.card_name = "PandaBoard";
537 panda_abe_audio_data.has_hsmic = 1;
538 } else {
539 /* PandaBoard ES */
540 /* ASoC audio configuration */
541 panda_abe_audio_data.card_name = "PandaBoardES";
542 }
543}
544
488static void __init omap4_panda_init(void) 545static void __init omap4_panda_init(void)
489{ 546{
490 int package = OMAP_PACKAGE_CBS; 547 int package = OMAP_PACKAGE_CBS;
@@ -498,6 +555,7 @@ static void __init omap4_panda_init(void)
498 if (ret) 555 if (ret)
499 pr_err("error setting wl12xx data: %d\n", ret); 556 pr_err("error setting wl12xx data: %d\n", ret);
500 557
558 omap4_panda_init_rev();
501 omap4_panda_i2c_init(); 559 omap4_panda_i2c_init();
502 platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices)); 560 platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
503 platform_device_register(&omap_vwlan_device); 561 platform_device_register(&omap_vwlan_device);
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 283d11eae693..e9fae652cd04 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -26,7 +26,6 @@
26 26
27#include <plat/tc.h> 27#include <plat/tc.h>
28#include <plat/board.h> 28#include <plat/board.h>
29#include <plat/mcbsp.h>
30#include <plat/mmc.h> 29#include <plat/mmc.h>
31#include <plat/dma.h> 30#include <plat/dma.h>
32#include <plat/omap_hwmod.h> 31#include <plat/omap_hwmod.h>
@@ -304,29 +303,8 @@ static struct platform_device omap_pcm = {
304 .id = -1, 303 .id = -1,
305}; 304};
306 305
307/*
308 * OMAP2420 has 2 McBSP ports
309 * OMAP2430 has 5 McBSP ports
310 * OMAP3 has 5 McBSP ports
311 * OMAP4 has 4 McBSP ports
312 */
313OMAP_MCBSP_PLATFORM_DEVICE(1);
314OMAP_MCBSP_PLATFORM_DEVICE(2);
315OMAP_MCBSP_PLATFORM_DEVICE(3);
316OMAP_MCBSP_PLATFORM_DEVICE(4);
317OMAP_MCBSP_PLATFORM_DEVICE(5);
318
319static void omap_init_audio(void) 306static void omap_init_audio(void)
320{ 307{
321 platform_device_register(&omap_mcbsp1);
322 platform_device_register(&omap_mcbsp2);
323 if (cpu_is_omap243x() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
324 platform_device_register(&omap_mcbsp3);
325 platform_device_register(&omap_mcbsp4);
326 }
327 if (cpu_is_omap243x() || cpu_is_omap34xx())
328 platform_device_register(&omap_mcbsp5);
329
330 platform_device_register(&omap_pcm); 308 platform_device_register(&omap_pcm);
331} 309}
332 310
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
index fb4bcf81a183..ecc039e794db 100644
--- a/arch/arm/mach-omap2/mcbsp.c
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -34,7 +34,7 @@
34#include "cm2xxx_3xxx.h" 34#include "cm2xxx_3xxx.h"
35#include "cm-regbits-34xx.h" 35#include "cm-regbits-34xx.h"
36 36
37/* McBSP internal signal muxing function */ 37/* McBSP1 internal signal muxing function for OMAP2/3 */
38static int omap2_mcbsp1_mux_rx_clk(struct device *dev, const char *signal, 38static int omap2_mcbsp1_mux_rx_clk(struct device *dev, const char *signal,
39 const char *src) 39 const char *src)
40{ 40{
@@ -65,6 +65,42 @@ static int omap2_mcbsp1_mux_rx_clk(struct device *dev, const char *signal,
65 return 0; 65 return 0;
66} 66}
67 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)
71static 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
68/* McBSP CLKS source switching function */ 104/* McBSP CLKS source switching function */
69static int omap2_mcbsp_set_clk_src(struct device *dev, struct clk *clk, 105static int omap2_mcbsp_set_clk_src(struct device *dev, struct clk *clk,
70 const char *src) 106 const char *src)
@@ -146,9 +182,15 @@ static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused)
146 pdata->has_ccr = true; 182 pdata->has_ccr = true;
147 } 183 }
148 pdata->set_clk_src = omap2_mcbsp_set_clk_src; 184 pdata->set_clk_src = omap2_mcbsp_set_clk_src;
149 if (id == 1) 185
186 /* On OMAP2/3 the McBSP1 port has 6 pin configuration */
187 if (id == 1 && oh->class->rev < MCBSP_CONFIG_TYPE4)
150 pdata->mux_signal = omap2_mcbsp1_mux_rx_clk; 188 pdata->mux_signal = omap2_mcbsp1_mux_rx_clk;
151 189
190 /* On OMAP4 the McBSP4 port has 6 pin configuration */
191 if (id == 4 && oh->class->rev == MCBSP_CONFIG_TYPE4)
192 pdata->mux_signal = omap4_mcbsp4_mux_rx_clk;
193
152 if (oh->class->rev == MCBSP_CONFIG_TYPE3) { 194 if (oh->class->rev == MCBSP_CONFIG_TYPE3) {
153 if (id == 2) 195 if (id == 2)
154 /* The FIFO has 1024 + 256 locations */ 196 /* The FIFO has 1024 + 256 locations */
@@ -180,7 +222,6 @@ static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused)
180 name, oh->name); 222 name, oh->name);
181 return PTR_ERR(pdev); 223 return PTR_ERR(pdev);
182 } 224 }
183 omap_mcbsp_count++;
184 return 0; 225 return 0;
185} 226}
186 227
@@ -188,11 +229,6 @@ static int __init omap2_mcbsp_init(void)
188{ 229{
189 omap_hwmod_for_each_by_class("mcbsp", omap_init_mcbsp, NULL); 230 omap_hwmod_for_each_by_class("mcbsp", omap_init_mcbsp, NULL);
190 231
191 mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *), 232 return 0;
192 GFP_KERNEL);
193 if (!mcbsp_ptr)
194 return -ENOMEM;
195
196 return omap_mcbsp_init();
197} 233}
198arch_initcall(omap2_mcbsp_init); 234arch_initcall(omap2_mcbsp_init);
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
index cd3c97e2ee75..32a30f38ba0c 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
@@ -102,6 +102,7 @@ static struct wm8962_pdata wm8962_pdata __initdata = {
102 0x8000 | WM8962_GPIO_FN_DMICDAT, 102 0x8000 | WM8962_GPIO_FN_DMICDAT,
103 WM8962_GPIO_FN_IRQ, /* Open drain mode */ 103 WM8962_GPIO_FN_IRQ, /* Open drain mode */
104 }, 104 },
105 .in4_dc_measure = true,
105}; 106};
106 107
107static struct wm9081_pdata wm9081_pdata __initdata = { 108static struct wm9081_pdata wm9081_pdata __initdata = {
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index b4718b00e827..8f6da7f134b3 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -737,26 +737,18 @@ fsi_set_rate_end:
737 return ret; 737 return ret;
738} 738}
739 739
740static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
741{
742 int ret;
743
744 if (is_porta)
745 ret = fsi_ak4642_set_rate(dev, rate, enable);
746 else
747 ret = fsi_hdmi_set_rate(dev, rate, enable);
748
749 return ret;
750}
751
752static struct sh_fsi_platform_info fsi_info = { 740static struct sh_fsi_platform_info fsi_info = {
753 .porta_flags = SH_FSI_BRS_INV, 741 .port_a = {
754 742 .flags = SH_FSI_BRS_INV,
755 .portb_flags = SH_FSI_BRS_INV | 743 .set_rate = fsi_ak4642_set_rate,
756 SH_FSI_BRM_INV | 744 },
757 SH_FSI_LRS_INV | 745 .port_b = {
758 SH_FSI_FMT_SPDIF, 746 .flags = SH_FSI_BRS_INV |
759 .set_rate = fsi_set_rate, 747 SH_FSI_BRM_INV |
748 SH_FSI_LRS_INV |
749 SH_FSI_FMT_SPDIF,
750 .set_rate = fsi_hdmi_set_rate,
751 },
760}; 752};
761 753
762static struct resource fsi_resources[] = { 754static struct resource fsi_resources[] = {
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 7b53cda41851..d99e780dffca 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -860,7 +860,7 @@ static int __fsi_set_round_rate(struct clk *clk, long rate, int enable)
860 return clk_enable(clk); 860 return clk_enable(clk);
861} 861}
862 862
863static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable) 863static int fsi_b_set_rate(struct device *dev, int rate, int enable)
864{ 864{
865 struct clk *fsib_clk; 865 struct clk *fsib_clk;
866 struct clk *fdiv_clk = &sh7372_fsidivb_clk; 866 struct clk *fdiv_clk = &sh7372_fsidivb_clk;
@@ -869,10 +869,6 @@ static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
869 int ackmd_bpfmd; 869 int ackmd_bpfmd;
870 int ret; 870 int ret;
871 871
872 /* FSIA is slave mode. nothing to do here */
873 if (is_porta)
874 return 0;
875
876 /* clock start */ 872 /* clock start */
877 switch (rate) { 873 switch (rate) {
878 case 44100: 874 case 44100:
@@ -916,14 +912,16 @@ fsi_set_rate_end:
916} 912}
917 913
918static struct sh_fsi_platform_info fsi_info = { 914static struct sh_fsi_platform_info fsi_info = {
919 .porta_flags = SH_FSI_BRS_INV, 915 .port_a = {
920 916 .flags = SH_FSI_BRS_INV,
921 .portb_flags = SH_FSI_BRS_INV | 917 },
918 .port_b = {
919 .flags = SH_FSI_BRS_INV |
922 SH_FSI_BRM_INV | 920 SH_FSI_BRM_INV |
923 SH_FSI_LRS_INV | 921 SH_FSI_LRS_INV |
924 SH_FSI_FMT_SPDIF, 922 SH_FSI_FMT_SPDIF,
925 923 .set_rate = fsi_b_set_rate,
926 .set_rate = fsi_set_rate, 924 }
927}; 925};
928 926
929static struct resource fsi_resources[] = { 927static struct resource fsi_resources[] = {
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
index dcebb1230f7f..c722f9ce6918 100644
--- a/arch/arm/plat-mxc/Kconfig
+++ b/arch/arm/plat-mxc/Kconfig
@@ -88,12 +88,6 @@ config IMX_HAVE_IOMUX_V1
88config ARCH_MXC_IOMUX_V3 88config ARCH_MXC_IOMUX_V3
89 bool 89 bool
90 90
91config ARCH_MXC_AUDMUX_V1
92 bool
93
94config ARCH_MXC_AUDMUX_V2
95 bool
96
97config IRAM_ALLOC 91config IRAM_ALLOC
98 bool 92 bool
99 select GENERIC_ALLOCATOR 93 select GENERIC_ALLOCATOR
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index 076db84f3e31..e81290c27c65 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -14,8 +14,6 @@ obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o
14obj-$(CONFIG_MXC_PWM) += pwm.o 14obj-$(CONFIG_MXC_PWM) += pwm.o
15obj-$(CONFIG_MXC_ULPI) += ulpi.o 15obj-$(CONFIG_MXC_ULPI) += ulpi.o
16obj-$(CONFIG_MXC_USE_EPIT) += epit.o 16obj-$(CONFIG_MXC_USE_EPIT) += epit.o
17obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o
18obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o
19obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o 17obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
20obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o 18obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o
21ifdef CONFIG_SND_IMX_SOC 19ifdef CONFIG_SND_IMX_SOC
diff --git a/arch/arm/plat-mxc/audmux-v1.c b/arch/arm/plat-mxc/audmux-v1.c
deleted file mode 100644
index 1180bef7664b..000000000000
--- a/arch/arm/plat-mxc/audmux-v1.c
+++ /dev/null
@@ -1,64 +0,0 @@
1/*
2 * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
3 *
4 * Initial development of this code was funded by
5 * Phytec Messtechnik GmbH, http://www.phytec.de
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <linux/module.h>
19#include <linux/err.h>
20#include <linux/io.h>
21#include <linux/clk.h>
22#include <mach/audmux.h>
23#include <mach/hardware.h>
24
25static void __iomem *audmux_base;
26
27static unsigned char port_mapping[] = {
28 0x0, 0x4, 0x8, 0x10, 0x14, 0x1c,
29};
30
31int mxc_audmux_v1_configure_port(unsigned int port, unsigned int pcr)
32{
33 if (!audmux_base) {
34 printk("%s: not configured\n", __func__);
35 return -ENOSYS;
36 }
37
38 if (port >= ARRAY_SIZE(port_mapping))
39 return -EINVAL;
40
41 writel(pcr, audmux_base + port_mapping[port]);
42
43 return 0;
44}
45EXPORT_SYMBOL_GPL(mxc_audmux_v1_configure_port);
46
47static int mxc_audmux_v1_init(void)
48{
49#ifdef CONFIG_MACH_MX21
50 if (cpu_is_mx21())
51 audmux_base = MX21_IO_ADDRESS(MX21_AUDMUX_BASE_ADDR);
52 else
53#endif
54#ifdef CONFIG_MACH_MX27
55 if (cpu_is_mx27())
56 audmux_base = MX27_IO_ADDRESS(MX27_AUDMUX_BASE_ADDR);
57 else
58#endif
59 (void)0;
60
61 return 0;
62}
63
64postcore_initcall(mxc_audmux_v1_init);
diff --git a/arch/arm/plat-mxc/audmux-v2.c b/arch/arm/plat-mxc/audmux-v2.c
deleted file mode 100644
index 8cced35009bd..000000000000
--- a/arch/arm/plat-mxc/audmux-v2.c
+++ /dev/null
@@ -1,219 +0,0 @@
1/*
2 * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
3 *
4 * Initial development of this code was funded by
5 * Phytec Messtechnik GmbH, http://www.phytec.de
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <linux/module.h>
19#include <linux/err.h>
20#include <linux/io.h>
21#include <linux/clk.h>
22#include <linux/debugfs.h>
23#include <linux/slab.h>
24#include <mach/audmux.h>
25#include <mach/hardware.h>
26
27static struct clk *audmux_clk;
28static void __iomem *audmux_base;
29
30#define MXC_AUDMUX_V2_PTCR(x) ((x) * 8)
31#define MXC_AUDMUX_V2_PDCR(x) ((x) * 8 + 4)
32
33#ifdef CONFIG_DEBUG_FS
34static struct dentry *audmux_debugfs_root;
35
36static int audmux_open_file(struct inode *inode, struct file *file)
37{
38 file->private_data = inode->i_private;
39 return 0;
40}
41
42/* There is an annoying discontinuity in the SSI numbering with regard
43 * to the Linux number of the devices */
44static const char *audmux_port_string(int port)
45{
46 switch (port) {
47 case MX31_AUDMUX_PORT1_SSI0:
48 return "imx-ssi.0";
49 case MX31_AUDMUX_PORT2_SSI1:
50 return "imx-ssi.1";
51 case MX31_AUDMUX_PORT3_SSI_PINS_3:
52 return "SSI3";
53 case MX31_AUDMUX_PORT4_SSI_PINS_4:
54 return "SSI4";
55 case MX31_AUDMUX_PORT5_SSI_PINS_5:
56 return "SSI5";
57 case MX31_AUDMUX_PORT6_SSI_PINS_6:
58 return "SSI6";
59 default:
60 return "UNKNOWN";
61 }
62}
63
64static ssize_t audmux_read_file(struct file *file, char __user *user_buf,
65 size_t count, loff_t *ppos)
66{
67 ssize_t ret;
68 char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
69 int port = (int)file->private_data;
70 u32 pdcr, ptcr;
71
72 if (!buf)
73 return -ENOMEM;
74
75 if (audmux_clk)
76 clk_enable(audmux_clk);
77
78 ptcr = readl(audmux_base + MXC_AUDMUX_V2_PTCR(port));
79 pdcr = readl(audmux_base + MXC_AUDMUX_V2_PDCR(port));
80
81 if (audmux_clk)
82 clk_disable(audmux_clk);
83
84 ret = snprintf(buf, PAGE_SIZE, "PDCR: %08x\nPTCR: %08x\n",
85 pdcr, ptcr);
86
87 if (ptcr & MXC_AUDMUX_V2_PTCR_TFSDIR)
88 ret += snprintf(buf + ret, PAGE_SIZE - ret,
89 "TxFS output from %s, ",
90 audmux_port_string((ptcr >> 27) & 0x7));
91 else
92 ret += snprintf(buf + ret, PAGE_SIZE - ret,
93 "TxFS input, ");
94
95 if (ptcr & MXC_AUDMUX_V2_PTCR_TCLKDIR)
96 ret += snprintf(buf + ret, PAGE_SIZE - ret,
97 "TxClk output from %s",
98 audmux_port_string((ptcr >> 22) & 0x7));
99 else
100 ret += snprintf(buf + ret, PAGE_SIZE - ret,
101 "TxClk input");
102
103 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
104
105 if (ptcr & MXC_AUDMUX_V2_PTCR_SYN) {
106 ret += snprintf(buf + ret, PAGE_SIZE - ret,
107 "Port is symmetric");
108 } else {
109 if (ptcr & MXC_AUDMUX_V2_PTCR_RFSDIR)
110 ret += snprintf(buf + ret, PAGE_SIZE - ret,
111 "RxFS output from %s, ",
112 audmux_port_string((ptcr >> 17) & 0x7));
113 else
114 ret += snprintf(buf + ret, PAGE_SIZE - ret,
115 "RxFS input, ");
116
117 if (ptcr & MXC_AUDMUX_V2_PTCR_RCLKDIR)
118 ret += snprintf(buf + ret, PAGE_SIZE - ret,
119 "RxClk output from %s",
120 audmux_port_string((ptcr >> 12) & 0x7));
121 else
122 ret += snprintf(buf + ret, PAGE_SIZE - ret,
123 "RxClk input");
124 }
125
126 ret += snprintf(buf + ret, PAGE_SIZE - ret,
127 "\nData received from %s\n",
128 audmux_port_string((pdcr >> 13) & 0x7));
129
130 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
131
132 kfree(buf);
133
134 return ret;
135}
136
137static const struct file_operations audmux_debugfs_fops = {
138 .open = audmux_open_file,
139 .read = audmux_read_file,
140 .llseek = default_llseek,
141};
142
143static void audmux_debugfs_init(void)
144{
145 int i;
146 char buf[20];
147
148 audmux_debugfs_root = debugfs_create_dir("audmux", NULL);
149 if (!audmux_debugfs_root) {
150 pr_warning("Failed to create AUDMUX debugfs root\n");
151 return;
152 }
153
154 for (i = 1; i < 8; i++) {
155 snprintf(buf, sizeof(buf), "ssi%d", i);
156 if (!debugfs_create_file(buf, 0444, audmux_debugfs_root,
157 (void *)i, &audmux_debugfs_fops))
158 pr_warning("Failed to create AUDMUX port %d debugfs file\n",
159 i);
160 }
161}
162#else
163static inline void audmux_debugfs_init(void)
164{
165}
166#endif
167
168int mxc_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
169 unsigned int pdcr)
170{
171 if (!audmux_base)
172 return -ENOSYS;
173
174 if (audmux_clk)
175 clk_enable(audmux_clk);
176
177 writel(ptcr, audmux_base + MXC_AUDMUX_V2_PTCR(port));
178 writel(pdcr, audmux_base + MXC_AUDMUX_V2_PDCR(port));
179
180 if (audmux_clk)
181 clk_disable(audmux_clk);
182
183 return 0;
184}
185EXPORT_SYMBOL_GPL(mxc_audmux_v2_configure_port);
186
187static int mxc_audmux_v2_init(void)
188{
189 int ret;
190 if (cpu_is_mx51()) {
191 audmux_base = MX51_IO_ADDRESS(MX51_AUDMUX_BASE_ADDR);
192 } else if (cpu_is_mx31()) {
193 audmux_base = MX31_IO_ADDRESS(MX31_AUDMUX_BASE_ADDR);
194 } else if (cpu_is_mx35()) {
195 audmux_clk = clk_get(NULL, "audmux");
196 if (IS_ERR(audmux_clk)) {
197 ret = PTR_ERR(audmux_clk);
198 printk(KERN_ERR "%s: cannot get clock: %d\n", __func__,
199 ret);
200 return ret;
201 }
202 audmux_base = MX35_IO_ADDRESS(MX35_AUDMUX_BASE_ADDR);
203 } else if (cpu_is_mx25()) {
204 audmux_clk = clk_get(NULL, "audmux");
205 if (IS_ERR(audmux_clk)) {
206 ret = PTR_ERR(audmux_clk);
207 printk(KERN_ERR "%s: cannot get clock: %d\n", __func__,
208 ret);
209 return ret;
210 }
211 audmux_base = MX25_IO_ADDRESS(MX25_AUDMUX_BASE_ADDR);
212 }
213
214 audmux_debugfs_init();
215
216 return 0;
217}
218
219postcore_initcall(mxc_audmux_v2_init);
diff --git a/arch/arm/plat-mxc/include/mach/audmux.h b/arch/arm/plat-mxc/include/mach/audmux.h
deleted file mode 100644
index 6fda788ed0e9..000000000000
--- a/arch/arm/plat-mxc/include/mach/audmux.h
+++ /dev/null
@@ -1,60 +0,0 @@
1#ifndef __MACH_AUDMUX_H
2#define __MACH_AUDMUX_H
3
4#define MX27_AUDMUX_HPCR1_SSI0 0
5#define MX27_AUDMUX_HPCR2_SSI1 1
6#define MX27_AUDMUX_HPCR3_SSI_PINS_4 2
7#define MX27_AUDMUX_PPCR1_SSI_PINS_1 3
8#define MX27_AUDMUX_PPCR2_SSI_PINS_2 4
9#define MX27_AUDMUX_PPCR3_SSI_PINS_3 5
10
11#define MX31_AUDMUX_PORT1_SSI0 0
12#define MX31_AUDMUX_PORT2_SSI1 1
13#define MX31_AUDMUX_PORT3_SSI_PINS_3 2
14#define MX31_AUDMUX_PORT4_SSI_PINS_4 3
15#define MX31_AUDMUX_PORT5_SSI_PINS_5 4
16#define MX31_AUDMUX_PORT6_SSI_PINS_6 5
17
18#define MX51_AUDMUX_PORT1_SSI0 0
19#define MX51_AUDMUX_PORT2_SSI1 1
20#define MX51_AUDMUX_PORT3 2
21#define MX51_AUDMUX_PORT4 3
22#define MX51_AUDMUX_PORT5 4
23#define MX51_AUDMUX_PORT6 5
24#define MX51_AUDMUX_PORT7 6
25
26/* Register definitions for the i.MX21/27 Digital Audio Multiplexer */
27#define MXC_AUDMUX_V1_PCR_INMMASK(x) ((x) & 0xff)
28#define MXC_AUDMUX_V1_PCR_INMEN (1 << 8)
29#define MXC_AUDMUX_V1_PCR_TXRXEN (1 << 10)
30#define MXC_AUDMUX_V1_PCR_SYN (1 << 12)
31#define MXC_AUDMUX_V1_PCR_RXDSEL(x) (((x) & 0x7) << 13)
32#define MXC_AUDMUX_V1_PCR_RFCSEL(x) (((x) & 0xf) << 20)
33#define MXC_AUDMUX_V1_PCR_RCLKDIR (1 << 24)
34#define MXC_AUDMUX_V1_PCR_RFSDIR (1 << 25)
35#define MXC_AUDMUX_V1_PCR_TFCSEL(x) (((x) & 0xf) << 26)
36#define MXC_AUDMUX_V1_PCR_TCLKDIR (1 << 30)
37#define MXC_AUDMUX_V1_PCR_TFSDIR (1 << 31)
38
39/* Register definitions for the i.MX25/31/35/51 Digital Audio Multiplexer */
40#define MXC_AUDMUX_V2_PTCR_TFSDIR (1 << 31)
41#define MXC_AUDMUX_V2_PTCR_TFSEL(x) (((x) & 0xf) << 27)
42#define MXC_AUDMUX_V2_PTCR_TCLKDIR (1 << 26)
43#define MXC_AUDMUX_V2_PTCR_TCSEL(x) (((x) & 0xf) << 22)
44#define MXC_AUDMUX_V2_PTCR_RFSDIR (1 << 21)
45#define MXC_AUDMUX_V2_PTCR_RFSEL(x) (((x) & 0xf) << 17)
46#define MXC_AUDMUX_V2_PTCR_RCLKDIR (1 << 16)
47#define MXC_AUDMUX_V2_PTCR_RCSEL(x) (((x) & 0xf) << 12)
48#define MXC_AUDMUX_V2_PTCR_SYN (1 << 11)
49
50#define MXC_AUDMUX_V2_PDCR_RXDSEL(x) (((x) & 0x7) << 13)
51#define MXC_AUDMUX_V2_PDCR_TXRXEN (1 << 12)
52#define MXC_AUDMUX_V2_PDCR_MODE(x) (((x) & 0x3) << 8)
53#define MXC_AUDMUX_V2_PDCR_INMMASK(x) ((x) & 0xff)
54
55int mxc_audmux_v1_configure_port(unsigned int port, unsigned int pcr);
56
57int mxc_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
58 unsigned int pdcr);
59
60#endif /* __MACH_AUDMUX_H */
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index aa59f4247dc5..8f81503a4df7 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -110,14 +110,6 @@ config OMAP_MUX_WARNINGS
110 to change the pin multiplexing setup. When there are no warnings 110 to change the pin multiplexing setup. When there are no warnings
111 printed, it's safe to deselect OMAP_MUX for your product. 111 printed, it's safe to deselect OMAP_MUX for your product.
112 112
113config OMAP_MCBSP
114 bool "McBSP support"
115 depends on ARCH_OMAP
116 default y
117 help
118 Say Y here if you want support for the OMAP Multichannel
119 Buffered Serial Port.
120
121config OMAP_MBOX_FWK 113config OMAP_MBOX_FWK
122 tristate "Mailbox framework support" 114 tristate "Mailbox framework support"
123 depends on ARCH_OMAP 115 depends on ARCH_OMAP
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 9a584614e7e6..c0fe2757b695 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -17,8 +17,6 @@ obj-$(CONFIG_ARCH_OMAP2) += omap_device.o
17obj-$(CONFIG_ARCH_OMAP3) += omap_device.o 17obj-$(CONFIG_ARCH_OMAP3) += omap_device.o
18obj-$(CONFIG_ARCH_OMAP4) += omap_device.o 18obj-$(CONFIG_ARCH_OMAP4) += omap_device.o
19 19
20obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
21
22obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o 20obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
23obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o 21obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o
24obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o 22obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
diff --git a/arch/arm/plat-omap/include/plat/mcbsp.h b/arch/arm/plat-omap/include/plat/mcbsp.h
index 8fa74e2c9d6e..18814127809a 100644
--- a/arch/arm/plat-omap/include/plat/mcbsp.h
+++ b/arch/arm/plat-omap/include/plat/mcbsp.h
@@ -27,271 +27,10 @@
27#include <linux/spinlock.h> 27#include <linux/spinlock.h>
28#include <linux/clk.h> 28#include <linux/clk.h>
29 29
30/* macro for building platform_device for McBSP ports */
31#define OMAP_MCBSP_PLATFORM_DEVICE(port_nr) \
32static struct platform_device omap_mcbsp##port_nr = { \
33 .name = "omap-mcbsp-dai", \
34 .id = port_nr - 1, \
35}
36
37#define MCBSP_CONFIG_TYPE2 0x2 30#define MCBSP_CONFIG_TYPE2 0x2
38#define MCBSP_CONFIG_TYPE3 0x3 31#define MCBSP_CONFIG_TYPE3 0x3
39#define MCBSP_CONFIG_TYPE4 0x4 32#define MCBSP_CONFIG_TYPE4 0x4
40 33
41/* McBSP register numbers. Register address offset = num * reg_step */
42enum {
43 /* Common registers */
44 OMAP_MCBSP_REG_SPCR2 = 4,
45 OMAP_MCBSP_REG_SPCR1,
46 OMAP_MCBSP_REG_RCR2,
47 OMAP_MCBSP_REG_RCR1,
48 OMAP_MCBSP_REG_XCR2,
49 OMAP_MCBSP_REG_XCR1,
50 OMAP_MCBSP_REG_SRGR2,
51 OMAP_MCBSP_REG_SRGR1,
52 OMAP_MCBSP_REG_MCR2,
53 OMAP_MCBSP_REG_MCR1,
54 OMAP_MCBSP_REG_RCERA,
55 OMAP_MCBSP_REG_RCERB,
56 OMAP_MCBSP_REG_XCERA,
57 OMAP_MCBSP_REG_XCERB,
58 OMAP_MCBSP_REG_PCR0,
59 OMAP_MCBSP_REG_RCERC,
60 OMAP_MCBSP_REG_RCERD,
61 OMAP_MCBSP_REG_XCERC,
62 OMAP_MCBSP_REG_XCERD,
63 OMAP_MCBSP_REG_RCERE,
64 OMAP_MCBSP_REG_RCERF,
65 OMAP_MCBSP_REG_XCERE,
66 OMAP_MCBSP_REG_XCERF,
67 OMAP_MCBSP_REG_RCERG,
68 OMAP_MCBSP_REG_RCERH,
69 OMAP_MCBSP_REG_XCERG,
70 OMAP_MCBSP_REG_XCERH,
71
72 /* OMAP1-OMAP2420 registers */
73 OMAP_MCBSP_REG_DRR2 = 0,
74 OMAP_MCBSP_REG_DRR1,
75 OMAP_MCBSP_REG_DXR2,
76 OMAP_MCBSP_REG_DXR1,
77
78 /* OMAP2430 and onwards */
79 OMAP_MCBSP_REG_DRR = 0,
80 OMAP_MCBSP_REG_DXR = 2,
81 OMAP_MCBSP_REG_SYSCON = 35,
82 OMAP_MCBSP_REG_THRSH2,
83 OMAP_MCBSP_REG_THRSH1,
84 OMAP_MCBSP_REG_IRQST = 40,
85 OMAP_MCBSP_REG_IRQEN,
86 OMAP_MCBSP_REG_WAKEUPEN,
87 OMAP_MCBSP_REG_XCCR,
88 OMAP_MCBSP_REG_RCCR,
89 OMAP_MCBSP_REG_XBUFFSTAT,
90 OMAP_MCBSP_REG_RBUFFSTAT,
91 OMAP_MCBSP_REG_SSELCR,
92};
93
94/* OMAP3 sidetone control registers */
95#define OMAP_ST_REG_REV 0x00
96#define OMAP_ST_REG_SYSCONFIG 0x10
97#define OMAP_ST_REG_IRQSTATUS 0x18
98#define OMAP_ST_REG_IRQENABLE 0x1C
99#define OMAP_ST_REG_SGAINCR 0x24
100#define OMAP_ST_REG_SFIRCR 0x28
101#define OMAP_ST_REG_SSELCR 0x2C
102
103/************************** McBSP SPCR1 bit definitions ***********************/
104#define RRST 0x0001
105#define RRDY 0x0002
106#define RFULL 0x0004
107#define RSYNC_ERR 0x0008
108#define RINTM(value) ((value)<<4) /* bits 4:5 */
109#define ABIS 0x0040
110#define DXENA 0x0080
111#define CLKSTP(value) ((value)<<11) /* bits 11:12 */
112#define RJUST(value) ((value)<<13) /* bits 13:14 */
113#define ALB 0x8000
114#define DLB 0x8000
115
116/************************** McBSP SPCR2 bit definitions ***********************/
117#define XRST 0x0001
118#define XRDY 0x0002
119#define XEMPTY 0x0004
120#define XSYNC_ERR 0x0008
121#define XINTM(value) ((value)<<4) /* bits 4:5 */
122#define GRST 0x0040
123#define FRST 0x0080
124#define SOFT 0x0100
125#define FREE 0x0200
126
127/************************** McBSP PCR bit definitions *************************/
128#define CLKRP 0x0001
129#define CLKXP 0x0002
130#define FSRP 0x0004
131#define FSXP 0x0008
132#define DR_STAT 0x0010
133#define DX_STAT 0x0020
134#define CLKS_STAT 0x0040
135#define SCLKME 0x0080
136#define CLKRM 0x0100
137#define CLKXM 0x0200
138#define FSRM 0x0400
139#define FSXM 0x0800
140#define RIOEN 0x1000
141#define XIOEN 0x2000
142#define IDLE_EN 0x4000
143
144/************************** McBSP RCR1 bit definitions ************************/
145#define RWDLEN1(value) ((value)<<5) /* Bits 5:7 */
146#define RFRLEN1(value) ((value)<<8) /* Bits 8:14 */
147
148/************************** McBSP XCR1 bit definitions ************************/
149#define XWDLEN1(value) ((value)<<5) /* Bits 5:7 */
150#define XFRLEN1(value) ((value)<<8) /* Bits 8:14 */
151
152/*************************** McBSP RCR2 bit definitions ***********************/
153#define RDATDLY(value) (value) /* Bits 0:1 */
154#define RFIG 0x0004
155#define RCOMPAND(value) ((value)<<3) /* Bits 3:4 */
156#define RWDLEN2(value) ((value)<<5) /* Bits 5:7 */
157#define RFRLEN2(value) ((value)<<8) /* Bits 8:14 */
158#define RPHASE 0x8000
159
160/*************************** McBSP XCR2 bit definitions ***********************/
161#define XDATDLY(value) (value) /* Bits 0:1 */
162#define XFIG 0x0004
163#define XCOMPAND(value) ((value)<<3) /* Bits 3:4 */
164#define XWDLEN2(value) ((value)<<5) /* Bits 5:7 */
165#define XFRLEN2(value) ((value)<<8) /* Bits 8:14 */
166#define XPHASE 0x8000
167
168/************************* McBSP SRGR1 bit definitions ************************/
169#define CLKGDV(value) (value) /* Bits 0:7 */
170#define FWID(value) ((value)<<8) /* Bits 8:15 */
171
172/************************* McBSP SRGR2 bit definitions ************************/
173#define FPER(value) (value) /* Bits 0:11 */
174#define FSGM 0x1000
175#define CLKSM 0x2000
176#define CLKSP 0x4000
177#define GSYNC 0x8000
178
179/************************* McBSP MCR1 bit definitions *************************/
180#define RMCM 0x0001
181#define RCBLK(value) ((value)<<2) /* Bits 2:4 */
182#define RPABLK(value) ((value)<<5) /* Bits 5:6 */
183#define RPBBLK(value) ((value)<<7) /* Bits 7:8 */
184
185/************************* McBSP MCR2 bit definitions *************************/
186#define XMCM(value) (value) /* Bits 0:1 */
187#define XCBLK(value) ((value)<<2) /* Bits 2:4 */
188#define XPABLK(value) ((value)<<5) /* Bits 5:6 */
189#define XPBBLK(value) ((value)<<7) /* Bits 7:8 */
190
191/*********************** McBSP XCCR bit definitions *************************/
192#define EXTCLKGATE 0x8000
193#define PPCONNECT 0x4000
194#define DXENDLY(value) ((value)<<12) /* Bits 12:13 */
195#define XFULL_CYCLE 0x0800
196#define DILB 0x0020
197#define XDMAEN 0x0008
198#define XDISABLE 0x0001
199
200/********************** McBSP RCCR bit definitions *************************/
201#define RFULL_CYCLE 0x0800
202#define RDMAEN 0x0008
203#define RDISABLE 0x0001
204
205/********************** McBSP SYSCONFIG bit definitions ********************/
206#define CLOCKACTIVITY(value) ((value)<<8)
207#define SIDLEMODE(value) ((value)<<3)
208#define ENAWAKEUP 0x0004
209#define SOFTRST 0x0002
210
211/********************** McBSP SSELCR bit definitions ***********************/
212#define SIDETONEEN 0x0400
213
214/********************** McBSP Sidetone SYSCONFIG bit definitions ***********/
215#define ST_AUTOIDLE 0x0001
216
217/********************** McBSP Sidetone SGAINCR bit definitions *************/
218#define ST_CH1GAIN(value) ((value<<16)) /* Bits 16:31 */
219#define ST_CH0GAIN(value) (value) /* Bits 0:15 */
220
221/********************** McBSP Sidetone SFIRCR bit definitions **************/
222#define ST_FIRCOEFF(value) (value) /* Bits 0:15 */
223
224/********************** McBSP Sidetone SSELCR bit definitions **************/
225#define ST_COEFFWRDONE 0x0004
226#define ST_COEFFWREN 0x0002
227#define ST_SIDETONEEN 0x0001
228
229/********************** McBSP DMA operating modes **************************/
230#define MCBSP_DMA_MODE_ELEMENT 0
231#define MCBSP_DMA_MODE_THRESHOLD 1
232#define MCBSP_DMA_MODE_FRAME 2
233
234/********************** McBSP WAKEUPEN bit definitions *********************/
235#define XEMPTYEOFEN 0x4000
236#define XRDYEN 0x0400
237#define XEOFEN 0x0200
238#define XFSXEN 0x0100
239#define XSYNCERREN 0x0080
240#define RRDYEN 0x0008
241#define REOFEN 0x0004
242#define RFSREN 0x0002
243#define RSYNCERREN 0x0001
244
245/* CLKR signal muxing options */
246#define CLKR_SRC_CLKR 0
247#define CLKR_SRC_CLKX 1
248
249/* FSR signal muxing options */
250#define FSR_SRC_FSR 0
251#define FSR_SRC_FSX 1
252
253/* McBSP functional clock sources */
254#define MCBSP_CLKS_PRCM_SRC 0
255#define MCBSP_CLKS_PAD_SRC 1
256
257/* we don't do multichannel for now */
258struct omap_mcbsp_reg_cfg {
259 u16 spcr2;
260 u16 spcr1;
261 u16 rcr2;
262 u16 rcr1;
263 u16 xcr2;
264 u16 xcr1;
265 u16 srgr2;
266 u16 srgr1;
267 u16 mcr2;
268 u16 mcr1;
269 u16 pcr0;
270 u16 rcerc;
271 u16 rcerd;
272 u16 xcerc;
273 u16 xcerd;
274 u16 rcere;
275 u16 rcerf;
276 u16 xcere;
277 u16 xcerf;
278 u16 rcerg;
279 u16 rcerh;
280 u16 xcerg;
281 u16 xcerh;
282 u16 xccr;
283 u16 rccr;
284};
285
286typedef enum {
287 OMAP_MCBSP_WORD_8 = 0,
288 OMAP_MCBSP_WORD_12,
289 OMAP_MCBSP_WORD_16,
290 OMAP_MCBSP_WORD_20,
291 OMAP_MCBSP_WORD_24,
292 OMAP_MCBSP_WORD_32,
293} omap_mcbsp_word_length;
294
295/* Platform specific configuration */ 34/* Platform specific configuration */
296struct omap_mcbsp_ops { 35struct omap_mcbsp_ops {
297 void (*request)(unsigned int); 36 void (*request)(unsigned int);
@@ -312,43 +51,6 @@ struct omap_mcbsp_platform_data {
312 int (*mux_signal)(struct device *dev, const char *signal, const char *src); 51 int (*mux_signal)(struct device *dev, const char *signal, const char *src);
313}; 52};
314 53
315struct omap_mcbsp_st_data {
316 void __iomem *io_base_st;
317 bool running;
318 bool enabled;
319 s16 taps[128]; /* Sidetone filter coefficients */
320 int nr_taps; /* Number of filter coefficients in use */
321 s16 ch0gain;
322 s16 ch1gain;
323};
324
325struct omap_mcbsp {
326 struct device *dev;
327 unsigned long phys_base;
328 unsigned long phys_dma_base;
329 void __iomem *io_base;
330 u8 id;
331 u8 free;
332
333 int rx_irq;
334 int tx_irq;
335
336 /* DMA stuff */
337 u8 dma_rx_sync;
338 u8 dma_tx_sync;
339
340 /* Protect the field .free, while checking if the mcbsp is in use */
341 spinlock_t lock;
342 struct omap_mcbsp_platform_data *pdata;
343 struct clk *fclk;
344 struct omap_mcbsp_st_data *st_data;
345 int dma_op_mode;
346 u16 max_tx_thres;
347 u16 max_rx_thres;
348 void *reg_cache;
349 int reg_cache_size;
350};
351
352/** 54/**
353 * omap_mcbsp_dev_attr - OMAP McBSP device attributes for omap_hwmod 55 * omap_mcbsp_dev_attr - OMAP McBSP device attributes for omap_hwmod
354 * @sidetone: name of the sidetone device 56 * @sidetone: name of the sidetone device
@@ -357,39 +59,4 @@ struct omap_mcbsp_dev_attr {
357 const char *sidetone; 59 const char *sidetone;
358}; 60};
359 61
360extern struct omap_mcbsp **mcbsp_ptr;
361extern int omap_mcbsp_count;
362
363int omap_mcbsp_init(void);
364void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config);
365void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold);
366void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold);
367u16 omap_mcbsp_get_max_tx_threshold(unsigned int id);
368u16 omap_mcbsp_get_max_rx_threshold(unsigned int id);
369u16 omap_mcbsp_get_fifo_size(unsigned int id);
370u16 omap_mcbsp_get_tx_delay(unsigned int id);
371u16 omap_mcbsp_get_rx_delay(unsigned int id);
372int omap_mcbsp_get_dma_op_mode(unsigned int id);
373int omap_mcbsp_request(unsigned int id);
374void omap_mcbsp_free(unsigned int id);
375void omap_mcbsp_start(unsigned int id, int tx, int rx);
376void omap_mcbsp_stop(unsigned int id, int tx, int rx);
377
378/* McBSP functional clock source changing function */
379extern int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id);
380
381/* McBSP signal muxing API */
382void omap2_mcbsp1_mux_clkr_src(u8 mux);
383void omap2_mcbsp1_mux_fsr_src(u8 mux);
384
385int omap_mcbsp_dma_ch_params(unsigned int id, unsigned int stream);
386int omap_mcbsp_dma_reg_params(unsigned int id, unsigned int stream);
387
388/* Sidetone specific API */
389int omap_st_set_chgain(unsigned int id, int channel, s16 chgain);
390int omap_st_get_chgain(unsigned int id, int channel, s16 *chgain);
391int omap_st_enable(unsigned int id);
392int omap_st_disable(unsigned int id);
393int omap_st_is_enabled(unsigned int id);
394
395#endif 62#endif
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
deleted file mode 100644
index 4b15cd7926d7..000000000000
--- a/arch/arm/plat-omap/mcbsp.c
+++ /dev/null
@@ -1,1361 +0,0 @@
1/*
2 * linux/arch/arm/plat-omap/mcbsp.c
3 *
4 * Copyright (C) 2004 Nokia Corporation
5 * Author: Samuel Ortiz <samuel.ortiz@nokia.com>
6 *
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * Multichannel mode not supported.
13 */
14
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/device.h>
18#include <linux/platform_device.h>
19#include <linux/interrupt.h>
20#include <linux/err.h>
21#include <linux/clk.h>
22#include <linux/delay.h>
23#include <linux/io.h>
24#include <linux/slab.h>
25
26#include <plat/mcbsp.h>
27#include <linux/pm_runtime.h>
28
29struct omap_mcbsp **mcbsp_ptr;
30int omap_mcbsp_count;
31
32#define omap_mcbsp_check_valid_id(id) (id < omap_mcbsp_count)
33#define id_to_mcbsp_ptr(id) mcbsp_ptr[id];
34
35static void omap_mcbsp_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
36{
37 void __iomem *addr = mcbsp->io_base + reg * mcbsp->pdata->reg_step;
38
39 if (mcbsp->pdata->reg_size == 2) {
40 ((u16 *)mcbsp->reg_cache)[reg] = (u16)val;
41 __raw_writew((u16)val, addr);
42 } else {
43 ((u32 *)mcbsp->reg_cache)[reg] = val;
44 __raw_writel(val, addr);
45 }
46}
47
48static int omap_mcbsp_read(struct omap_mcbsp *mcbsp, u16 reg, bool from_cache)
49{
50 void __iomem *addr = mcbsp->io_base + reg * mcbsp->pdata->reg_step;
51
52 if (mcbsp->pdata->reg_size == 2) {
53 return !from_cache ? __raw_readw(addr) :
54 ((u16 *)mcbsp->reg_cache)[reg];
55 } else {
56 return !from_cache ? __raw_readl(addr) :
57 ((u32 *)mcbsp->reg_cache)[reg];
58 }
59}
60
61static void omap_mcbsp_st_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
62{
63 __raw_writel(val, mcbsp->st_data->io_base_st + reg);
64}
65
66static int omap_mcbsp_st_read(struct omap_mcbsp *mcbsp, u16 reg)
67{
68 return __raw_readl(mcbsp->st_data->io_base_st + reg);
69}
70
71#define MCBSP_READ(mcbsp, reg) \
72 omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 0)
73#define MCBSP_WRITE(mcbsp, reg, val) \
74 omap_mcbsp_write(mcbsp, OMAP_MCBSP_REG_##reg, val)
75#define MCBSP_READ_CACHE(mcbsp, reg) \
76 omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 1)
77
78#define MCBSP_ST_READ(mcbsp, reg) \
79 omap_mcbsp_st_read(mcbsp, OMAP_ST_REG_##reg)
80#define MCBSP_ST_WRITE(mcbsp, reg, val) \
81 omap_mcbsp_st_write(mcbsp, OMAP_ST_REG_##reg, val)
82
83static void omap_mcbsp_dump_reg(u8 id)
84{
85 struct omap_mcbsp *mcbsp = id_to_mcbsp_ptr(id);
86
87 dev_dbg(mcbsp->dev, "**** McBSP%d regs ****\n", mcbsp->id);
88 dev_dbg(mcbsp->dev, "DRR2: 0x%04x\n",
89 MCBSP_READ(mcbsp, DRR2));
90 dev_dbg(mcbsp->dev, "DRR1: 0x%04x\n",
91 MCBSP_READ(mcbsp, DRR1));
92 dev_dbg(mcbsp->dev, "DXR2: 0x%04x\n",
93 MCBSP_READ(mcbsp, DXR2));
94 dev_dbg(mcbsp->dev, "DXR1: 0x%04x\n",
95 MCBSP_READ(mcbsp, DXR1));
96 dev_dbg(mcbsp->dev, "SPCR2: 0x%04x\n",
97 MCBSP_READ(mcbsp, SPCR2));
98 dev_dbg(mcbsp->dev, "SPCR1: 0x%04x\n",
99 MCBSP_READ(mcbsp, SPCR1));
100 dev_dbg(mcbsp->dev, "RCR2: 0x%04x\n",
101 MCBSP_READ(mcbsp, RCR2));
102 dev_dbg(mcbsp->dev, "RCR1: 0x%04x\n",
103 MCBSP_READ(mcbsp, RCR1));
104 dev_dbg(mcbsp->dev, "XCR2: 0x%04x\n",
105 MCBSP_READ(mcbsp, XCR2));
106 dev_dbg(mcbsp->dev, "XCR1: 0x%04x\n",
107 MCBSP_READ(mcbsp, XCR1));
108 dev_dbg(mcbsp->dev, "SRGR2: 0x%04x\n",
109 MCBSP_READ(mcbsp, SRGR2));
110 dev_dbg(mcbsp->dev, "SRGR1: 0x%04x\n",
111 MCBSP_READ(mcbsp, SRGR1));
112 dev_dbg(mcbsp->dev, "PCR0: 0x%04x\n",
113 MCBSP_READ(mcbsp, PCR0));
114 dev_dbg(mcbsp->dev, "***********************\n");
115}
116
117static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
118{
119 struct omap_mcbsp *mcbsp_tx = dev_id;
120 u16 irqst_spcr2;
121
122 irqst_spcr2 = MCBSP_READ(mcbsp_tx, SPCR2);
123 dev_dbg(mcbsp_tx->dev, "TX IRQ callback : 0x%x\n", irqst_spcr2);
124
125 if (irqst_spcr2 & XSYNC_ERR) {
126 dev_err(mcbsp_tx->dev, "TX Frame Sync Error! : 0x%x\n",
127 irqst_spcr2);
128 /* Writing zero to XSYNC_ERR clears the IRQ */
129 MCBSP_WRITE(mcbsp_tx, SPCR2, MCBSP_READ_CACHE(mcbsp_tx, SPCR2));
130 }
131
132 return IRQ_HANDLED;
133}
134
135static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
136{
137 struct omap_mcbsp *mcbsp_rx = dev_id;
138 u16 irqst_spcr1;
139
140 irqst_spcr1 = MCBSP_READ(mcbsp_rx, SPCR1);
141 dev_dbg(mcbsp_rx->dev, "RX IRQ callback : 0x%x\n", irqst_spcr1);
142
143 if (irqst_spcr1 & RSYNC_ERR) {
144 dev_err(mcbsp_rx->dev, "RX Frame Sync Error! : 0x%x\n",
145 irqst_spcr1);
146 /* Writing zero to RSYNC_ERR clears the IRQ */
147 MCBSP_WRITE(mcbsp_rx, SPCR1, MCBSP_READ_CACHE(mcbsp_rx, SPCR1));
148 }
149
150 return IRQ_HANDLED;
151}
152
153/*
154 * omap_mcbsp_config simply write a config to the
155 * appropriate McBSP.
156 * You either call this function or set the McBSP registers
157 * by yourself before calling omap_mcbsp_start().
158 */
159void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)
160{
161 struct omap_mcbsp *mcbsp;
162
163 if (!omap_mcbsp_check_valid_id(id)) {
164 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
165 return;
166 }
167 mcbsp = id_to_mcbsp_ptr(id);
168
169 dev_dbg(mcbsp->dev, "Configuring McBSP%d phys_base: 0x%08lx\n",
170 mcbsp->id, mcbsp->phys_base);
171
172 /* We write the given config */
173 MCBSP_WRITE(mcbsp, SPCR2, config->spcr2);
174 MCBSP_WRITE(mcbsp, SPCR1, config->spcr1);
175 MCBSP_WRITE(mcbsp, RCR2, config->rcr2);
176 MCBSP_WRITE(mcbsp, RCR1, config->rcr1);
177 MCBSP_WRITE(mcbsp, XCR2, config->xcr2);
178 MCBSP_WRITE(mcbsp, XCR1, config->xcr1);
179 MCBSP_WRITE(mcbsp, SRGR2, config->srgr2);
180 MCBSP_WRITE(mcbsp, SRGR1, config->srgr1);
181 MCBSP_WRITE(mcbsp, MCR2, config->mcr2);
182 MCBSP_WRITE(mcbsp, MCR1, config->mcr1);
183 MCBSP_WRITE(mcbsp, PCR0, config->pcr0);
184 if (mcbsp->pdata->has_ccr) {
185 MCBSP_WRITE(mcbsp, XCCR, config->xccr);
186 MCBSP_WRITE(mcbsp, RCCR, config->rccr);
187 }
188}
189EXPORT_SYMBOL(omap_mcbsp_config);
190
191/**
192 * omap_mcbsp_dma_params - returns the dma channel number
193 * @id - mcbsp id
194 * @stream - indicates the direction of data flow (rx or tx)
195 *
196 * Returns the dma channel number for the rx channel or tx channel
197 * based on the value of @stream for the requested mcbsp given by @id
198 */
199int omap_mcbsp_dma_ch_params(unsigned int id, unsigned int stream)
200{
201 struct omap_mcbsp *mcbsp;
202
203 if (!omap_mcbsp_check_valid_id(id)) {
204 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
205 return -ENODEV;
206 }
207 mcbsp = id_to_mcbsp_ptr(id);
208
209 if (stream)
210 return mcbsp->dma_rx_sync;
211 else
212 return mcbsp->dma_tx_sync;
213}
214EXPORT_SYMBOL(omap_mcbsp_dma_ch_params);
215
216/**
217 * omap_mcbsp_dma_reg_params - returns the address of mcbsp data register
218 * @id - mcbsp id
219 * @stream - indicates the direction of data flow (rx or tx)
220 *
221 * Returns the address of mcbsp data transmit register or data receive register
222 * to be used by DMA for transferring/receiving data based on the value of
223 * @stream for the requested mcbsp given by @id
224 */
225int omap_mcbsp_dma_reg_params(unsigned int id, unsigned int stream)
226{
227 struct omap_mcbsp *mcbsp;
228 int data_reg;
229
230 if (!omap_mcbsp_check_valid_id(id)) {
231 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
232 return -ENODEV;
233 }
234 mcbsp = id_to_mcbsp_ptr(id);
235
236 if (mcbsp->pdata->reg_size == 2) {
237 if (stream)
238 data_reg = OMAP_MCBSP_REG_DRR1;
239 else
240 data_reg = OMAP_MCBSP_REG_DXR1;
241 } else {
242 if (stream)
243 data_reg = OMAP_MCBSP_REG_DRR;
244 else
245 data_reg = OMAP_MCBSP_REG_DXR;
246 }
247
248 return mcbsp->phys_dma_base + data_reg * mcbsp->pdata->reg_step;
249}
250EXPORT_SYMBOL(omap_mcbsp_dma_reg_params);
251
252static void omap_st_on(struct omap_mcbsp *mcbsp)
253{
254 unsigned int w;
255
256 if (mcbsp->pdata->enable_st_clock)
257 mcbsp->pdata->enable_st_clock(mcbsp->id, 1);
258
259 /* Enable McBSP Sidetone */
260 w = MCBSP_READ(mcbsp, SSELCR);
261 MCBSP_WRITE(mcbsp, SSELCR, w | SIDETONEEN);
262
263 /* Enable Sidetone from Sidetone Core */
264 w = MCBSP_ST_READ(mcbsp, SSELCR);
265 MCBSP_ST_WRITE(mcbsp, SSELCR, w | ST_SIDETONEEN);
266}
267
268static void omap_st_off(struct omap_mcbsp *mcbsp)
269{
270 unsigned int w;
271
272 w = MCBSP_ST_READ(mcbsp, SSELCR);
273 MCBSP_ST_WRITE(mcbsp, SSELCR, w & ~(ST_SIDETONEEN));
274
275 w = MCBSP_READ(mcbsp, SSELCR);
276 MCBSP_WRITE(mcbsp, SSELCR, w & ~(SIDETONEEN));
277
278 if (mcbsp->pdata->enable_st_clock)
279 mcbsp->pdata->enable_st_clock(mcbsp->id, 0);
280}
281
282static void omap_st_fir_write(struct omap_mcbsp *mcbsp, s16 *fir)
283{
284 u16 val, i;
285
286 val = MCBSP_ST_READ(mcbsp, SSELCR);
287
288 if (val & ST_COEFFWREN)
289 MCBSP_ST_WRITE(mcbsp, SSELCR, val & ~(ST_COEFFWREN));
290
291 MCBSP_ST_WRITE(mcbsp, SSELCR, val | ST_COEFFWREN);
292
293 for (i = 0; i < 128; i++)
294 MCBSP_ST_WRITE(mcbsp, SFIRCR, fir[i]);
295
296 i = 0;
297
298 val = MCBSP_ST_READ(mcbsp, SSELCR);
299 while (!(val & ST_COEFFWRDONE) && (++i < 1000))
300 val = MCBSP_ST_READ(mcbsp, SSELCR);
301
302 MCBSP_ST_WRITE(mcbsp, SSELCR, val & ~(ST_COEFFWREN));
303
304 if (i == 1000)
305 dev_err(mcbsp->dev, "McBSP FIR load error!\n");
306}
307
308static void omap_st_chgain(struct omap_mcbsp *mcbsp)
309{
310 u16 w;
311 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
312
313 w = MCBSP_ST_READ(mcbsp, SSELCR);
314
315 MCBSP_ST_WRITE(mcbsp, SGAINCR, ST_CH0GAIN(st_data->ch0gain) | \
316 ST_CH1GAIN(st_data->ch1gain));
317}
318
319int omap_st_set_chgain(unsigned int id, int channel, s16 chgain)
320{
321 struct omap_mcbsp *mcbsp;
322 struct omap_mcbsp_st_data *st_data;
323 int ret = 0;
324
325 if (!omap_mcbsp_check_valid_id(id)) {
326 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
327 return -ENODEV;
328 }
329
330 mcbsp = id_to_mcbsp_ptr(id);
331 st_data = mcbsp->st_data;
332
333 if (!st_data)
334 return -ENOENT;
335
336 spin_lock_irq(&mcbsp->lock);
337 if (channel == 0)
338 st_data->ch0gain = chgain;
339 else if (channel == 1)
340 st_data->ch1gain = chgain;
341 else
342 ret = -EINVAL;
343
344 if (st_data->enabled)
345 omap_st_chgain(mcbsp);
346 spin_unlock_irq(&mcbsp->lock);
347
348 return ret;
349}
350EXPORT_SYMBOL(omap_st_set_chgain);
351
352int omap_st_get_chgain(unsigned int id, int channel, s16 *chgain)
353{
354 struct omap_mcbsp *mcbsp;
355 struct omap_mcbsp_st_data *st_data;
356 int ret = 0;
357
358 if (!omap_mcbsp_check_valid_id(id)) {
359 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
360 return -ENODEV;
361 }
362
363 mcbsp = id_to_mcbsp_ptr(id);
364 st_data = mcbsp->st_data;
365
366 if (!st_data)
367 return -ENOENT;
368
369 spin_lock_irq(&mcbsp->lock);
370 if (channel == 0)
371 *chgain = st_data->ch0gain;
372 else if (channel == 1)
373 *chgain = st_data->ch1gain;
374 else
375 ret = -EINVAL;
376 spin_unlock_irq(&mcbsp->lock);
377
378 return ret;
379}
380EXPORT_SYMBOL(omap_st_get_chgain);
381
382static int omap_st_start(struct omap_mcbsp *mcbsp)
383{
384 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
385
386 if (st_data && st_data->enabled && !st_data->running) {
387 omap_st_fir_write(mcbsp, st_data->taps);
388 omap_st_chgain(mcbsp);
389
390 if (!mcbsp->free) {
391 omap_st_on(mcbsp);
392 st_data->running = 1;
393 }
394 }
395
396 return 0;
397}
398
399int omap_st_enable(unsigned int id)
400{
401 struct omap_mcbsp *mcbsp;
402 struct omap_mcbsp_st_data *st_data;
403
404 if (!omap_mcbsp_check_valid_id(id)) {
405 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
406 return -ENODEV;
407 }
408
409 mcbsp = id_to_mcbsp_ptr(id);
410 st_data = mcbsp->st_data;
411
412 if (!st_data)
413 return -ENODEV;
414
415 spin_lock_irq(&mcbsp->lock);
416 st_data->enabled = 1;
417 omap_st_start(mcbsp);
418 spin_unlock_irq(&mcbsp->lock);
419
420 return 0;
421}
422EXPORT_SYMBOL(omap_st_enable);
423
424static int omap_st_stop(struct omap_mcbsp *mcbsp)
425{
426 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
427
428 if (st_data && st_data->running) {
429 if (!mcbsp->free) {
430 omap_st_off(mcbsp);
431 st_data->running = 0;
432 }
433 }
434
435 return 0;
436}
437
438int omap_st_disable(unsigned int id)
439{
440 struct omap_mcbsp *mcbsp;
441 struct omap_mcbsp_st_data *st_data;
442 int ret = 0;
443
444 if (!omap_mcbsp_check_valid_id(id)) {
445 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
446 return -ENODEV;
447 }
448
449 mcbsp = id_to_mcbsp_ptr(id);
450 st_data = mcbsp->st_data;
451
452 if (!st_data)
453 return -ENODEV;
454
455 spin_lock_irq(&mcbsp->lock);
456 omap_st_stop(mcbsp);
457 st_data->enabled = 0;
458 spin_unlock_irq(&mcbsp->lock);
459
460 return ret;
461}
462EXPORT_SYMBOL(omap_st_disable);
463
464int omap_st_is_enabled(unsigned int id)
465{
466 struct omap_mcbsp *mcbsp;
467 struct omap_mcbsp_st_data *st_data;
468
469 if (!omap_mcbsp_check_valid_id(id)) {
470 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
471 return -ENODEV;
472 }
473
474 mcbsp = id_to_mcbsp_ptr(id);
475 st_data = mcbsp->st_data;
476
477 if (!st_data)
478 return -ENODEV;
479
480
481 return st_data->enabled;
482}
483EXPORT_SYMBOL(omap_st_is_enabled);
484
485/*
486 * omap_mcbsp_set_rx_threshold configures the transmit threshold in words.
487 * The threshold parameter is 1 based, and it is converted (threshold - 1)
488 * for the THRSH2 register.
489 */
490void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
491{
492 struct omap_mcbsp *mcbsp;
493
494 if (!omap_mcbsp_check_valid_id(id)) {
495 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
496 return;
497 }
498 mcbsp = id_to_mcbsp_ptr(id);
499 if (mcbsp->pdata->buffer_size == 0)
500 return;
501
502 if (threshold && threshold <= mcbsp->max_tx_thres)
503 MCBSP_WRITE(mcbsp, THRSH2, threshold - 1);
504}
505EXPORT_SYMBOL(omap_mcbsp_set_tx_threshold);
506
507/*
508 * omap_mcbsp_set_rx_threshold configures the receive threshold in words.
509 * The threshold parameter is 1 based, and it is converted (threshold - 1)
510 * for the THRSH1 register.
511 */
512void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
513{
514 struct omap_mcbsp *mcbsp;
515
516 if (!omap_mcbsp_check_valid_id(id)) {
517 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
518 return;
519 }
520 mcbsp = id_to_mcbsp_ptr(id);
521 if (mcbsp->pdata->buffer_size == 0)
522 return;
523
524 if (threshold && threshold <= mcbsp->max_rx_thres)
525 MCBSP_WRITE(mcbsp, THRSH1, threshold - 1);
526}
527EXPORT_SYMBOL(omap_mcbsp_set_rx_threshold);
528
529/*
530 * omap_mcbsp_get_max_tx_thres just return the current configured
531 * maximum threshold for transmission
532 */
533u16 omap_mcbsp_get_max_tx_threshold(unsigned int id)
534{
535 struct omap_mcbsp *mcbsp;
536
537 if (!omap_mcbsp_check_valid_id(id)) {
538 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
539 return -ENODEV;
540 }
541 mcbsp = id_to_mcbsp_ptr(id);
542
543 return mcbsp->max_tx_thres;
544}
545EXPORT_SYMBOL(omap_mcbsp_get_max_tx_threshold);
546
547/*
548 * omap_mcbsp_get_max_rx_thres just return the current configured
549 * maximum threshold for reception
550 */
551u16 omap_mcbsp_get_max_rx_threshold(unsigned int id)
552{
553 struct omap_mcbsp *mcbsp;
554
555 if (!omap_mcbsp_check_valid_id(id)) {
556 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
557 return -ENODEV;
558 }
559 mcbsp = id_to_mcbsp_ptr(id);
560
561 return mcbsp->max_rx_thres;
562}
563EXPORT_SYMBOL(omap_mcbsp_get_max_rx_threshold);
564
565u16 omap_mcbsp_get_fifo_size(unsigned int id)
566{
567 struct omap_mcbsp *mcbsp;
568
569 if (!omap_mcbsp_check_valid_id(id)) {
570 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
571 return -ENODEV;
572 }
573 mcbsp = id_to_mcbsp_ptr(id);
574
575 return mcbsp->pdata->buffer_size;
576}
577EXPORT_SYMBOL(omap_mcbsp_get_fifo_size);
578
579/*
580 * omap_mcbsp_get_tx_delay returns the number of used slots in the McBSP FIFO
581 */
582u16 omap_mcbsp_get_tx_delay(unsigned int id)
583{
584 struct omap_mcbsp *mcbsp;
585 u16 buffstat;
586
587 if (!omap_mcbsp_check_valid_id(id)) {
588 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
589 return -ENODEV;
590 }
591 mcbsp = id_to_mcbsp_ptr(id);
592 if (mcbsp->pdata->buffer_size == 0)
593 return 0;
594
595 /* Returns the number of free locations in the buffer */
596 buffstat = MCBSP_READ(mcbsp, XBUFFSTAT);
597
598 /* Number of slots are different in McBSP ports */
599 return mcbsp->pdata->buffer_size - buffstat;
600}
601EXPORT_SYMBOL(omap_mcbsp_get_tx_delay);
602
603/*
604 * omap_mcbsp_get_rx_delay returns the number of free slots in the McBSP FIFO
605 * to reach the threshold value (when the DMA will be triggered to read it)
606 */
607u16 omap_mcbsp_get_rx_delay(unsigned int id)
608{
609 struct omap_mcbsp *mcbsp;
610 u16 buffstat, threshold;
611
612 if (!omap_mcbsp_check_valid_id(id)) {
613 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
614 return -ENODEV;
615 }
616 mcbsp = id_to_mcbsp_ptr(id);
617 if (mcbsp->pdata->buffer_size == 0)
618 return 0;
619
620 /* Returns the number of used locations in the buffer */
621 buffstat = MCBSP_READ(mcbsp, RBUFFSTAT);
622 /* RX threshold */
623 threshold = MCBSP_READ(mcbsp, THRSH1);
624
625 /* Return the number of location till we reach the threshold limit */
626 if (threshold <= buffstat)
627 return 0;
628 else
629 return threshold - buffstat;
630}
631EXPORT_SYMBOL(omap_mcbsp_get_rx_delay);
632
633/*
634 * omap_mcbsp_get_dma_op_mode just return the current configured
635 * operating mode for the mcbsp channel
636 */
637int omap_mcbsp_get_dma_op_mode(unsigned int id)
638{
639 struct omap_mcbsp *mcbsp;
640 int dma_op_mode;
641
642 if (!omap_mcbsp_check_valid_id(id)) {
643 printk(KERN_ERR "%s: Invalid id (%u)\n", __func__, id + 1);
644 return -ENODEV;
645 }
646 mcbsp = id_to_mcbsp_ptr(id);
647
648 dma_op_mode = mcbsp->dma_op_mode;
649
650 return dma_op_mode;
651}
652EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode);
653
654int omap_mcbsp_request(unsigned int id)
655{
656 struct omap_mcbsp *mcbsp;
657 void *reg_cache;
658 int err;
659
660 if (!omap_mcbsp_check_valid_id(id)) {
661 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
662 return -ENODEV;
663 }
664 mcbsp = id_to_mcbsp_ptr(id);
665
666 reg_cache = kzalloc(mcbsp->reg_cache_size, GFP_KERNEL);
667 if (!reg_cache) {
668 return -ENOMEM;
669 }
670
671 spin_lock(&mcbsp->lock);
672 if (!mcbsp->free) {
673 dev_err(mcbsp->dev, "McBSP%d is currently in use\n",
674 mcbsp->id);
675 err = -EBUSY;
676 goto err_kfree;
677 }
678
679 mcbsp->free = false;
680 mcbsp->reg_cache = reg_cache;
681 spin_unlock(&mcbsp->lock);
682
683 if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request)
684 mcbsp->pdata->ops->request(id);
685
686 pm_runtime_get_sync(mcbsp->dev);
687
688 /* Enable wakeup behavior */
689 if (mcbsp->pdata->has_wakeup)
690 MCBSP_WRITE(mcbsp, WAKEUPEN, XRDYEN | RRDYEN);
691
692 /*
693 * Make sure that transmitter, receiver and sample-rate generator are
694 * not running before activating IRQs.
695 */
696 MCBSP_WRITE(mcbsp, SPCR1, 0);
697 MCBSP_WRITE(mcbsp, SPCR2, 0);
698
699 err = request_irq(mcbsp->tx_irq, omap_mcbsp_tx_irq_handler,
700 0, "McBSP", (void *)mcbsp);
701 if (err != 0) {
702 dev_err(mcbsp->dev, "Unable to request TX IRQ %d "
703 "for McBSP%d\n", mcbsp->tx_irq,
704 mcbsp->id);
705 goto err_clk_disable;
706 }
707
708 if (mcbsp->rx_irq) {
709 err = request_irq(mcbsp->rx_irq,
710 omap_mcbsp_rx_irq_handler,
711 0, "McBSP", (void *)mcbsp);
712 if (err != 0) {
713 dev_err(mcbsp->dev, "Unable to request RX IRQ %d "
714 "for McBSP%d\n", mcbsp->rx_irq,
715 mcbsp->id);
716 goto err_free_irq;
717 }
718 }
719
720 return 0;
721err_free_irq:
722 free_irq(mcbsp->tx_irq, (void *)mcbsp);
723err_clk_disable:
724 if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
725 mcbsp->pdata->ops->free(id);
726
727 /* Disable wakeup behavior */
728 if (mcbsp->pdata->has_wakeup)
729 MCBSP_WRITE(mcbsp, WAKEUPEN, 0);
730
731 pm_runtime_put_sync(mcbsp->dev);
732
733 spin_lock(&mcbsp->lock);
734 mcbsp->free = true;
735 mcbsp->reg_cache = NULL;
736err_kfree:
737 spin_unlock(&mcbsp->lock);
738 kfree(reg_cache);
739
740 return err;
741}
742EXPORT_SYMBOL(omap_mcbsp_request);
743
744void omap_mcbsp_free(unsigned int id)
745{
746 struct omap_mcbsp *mcbsp;
747 void *reg_cache;
748
749 if (!omap_mcbsp_check_valid_id(id)) {
750 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
751 return;
752 }
753 mcbsp = id_to_mcbsp_ptr(id);
754
755 if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
756 mcbsp->pdata->ops->free(id);
757
758 /* Disable wakeup behavior */
759 if (mcbsp->pdata->has_wakeup)
760 MCBSP_WRITE(mcbsp, WAKEUPEN, 0);
761
762 pm_runtime_put_sync(mcbsp->dev);
763
764 if (mcbsp->rx_irq)
765 free_irq(mcbsp->rx_irq, (void *)mcbsp);
766 free_irq(mcbsp->tx_irq, (void *)mcbsp);
767
768 reg_cache = mcbsp->reg_cache;
769
770 spin_lock(&mcbsp->lock);
771 if (mcbsp->free)
772 dev_err(mcbsp->dev, "McBSP%d was not reserved\n", mcbsp->id);
773 else
774 mcbsp->free = true;
775 mcbsp->reg_cache = NULL;
776 spin_unlock(&mcbsp->lock);
777
778 if (reg_cache)
779 kfree(reg_cache);
780}
781EXPORT_SYMBOL(omap_mcbsp_free);
782
783/*
784 * Here we start the McBSP, by enabling transmitter, receiver or both.
785 * If no transmitter or receiver is active prior calling, then sample-rate
786 * generator and frame sync are started.
787 */
788void omap_mcbsp_start(unsigned int id, int tx, int rx)
789{
790 struct omap_mcbsp *mcbsp;
791 int enable_srg = 0;
792 u16 w;
793
794 if (!omap_mcbsp_check_valid_id(id)) {
795 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
796 return;
797 }
798 mcbsp = id_to_mcbsp_ptr(id);
799
800 if (mcbsp->st_data)
801 omap_st_start(mcbsp);
802
803 /* Only enable SRG, if McBSP is master */
804 w = MCBSP_READ_CACHE(mcbsp, PCR0);
805 if (w & (FSXM | FSRM | CLKXM | CLKRM))
806 enable_srg = !((MCBSP_READ_CACHE(mcbsp, SPCR2) |
807 MCBSP_READ_CACHE(mcbsp, SPCR1)) & 1);
808
809 if (enable_srg) {
810 /* Start the sample generator */
811 w = MCBSP_READ_CACHE(mcbsp, SPCR2);
812 MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 6));
813 }
814
815 /* Enable transmitter and receiver */
816 tx &= 1;
817 w = MCBSP_READ_CACHE(mcbsp, SPCR2);
818 MCBSP_WRITE(mcbsp, SPCR2, w | tx);
819
820 rx &= 1;
821 w = MCBSP_READ_CACHE(mcbsp, SPCR1);
822 MCBSP_WRITE(mcbsp, SPCR1, w | rx);
823
824 /*
825 * Worst case: CLKSRG*2 = 8000khz: (1/8000) * 2 * 2 usec
826 * REVISIT: 100us may give enough time for two CLKSRG, however
827 * due to some unknown PM related, clock gating etc. reason it
828 * is now at 500us.
829 */
830 udelay(500);
831
832 if (enable_srg) {
833 /* Start frame sync */
834 w = MCBSP_READ_CACHE(mcbsp, SPCR2);
835 MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 7));
836 }
837
838 if (mcbsp->pdata->has_ccr) {
839 /* Release the transmitter and receiver */
840 w = MCBSP_READ_CACHE(mcbsp, XCCR);
841 w &= ~(tx ? XDISABLE : 0);
842 MCBSP_WRITE(mcbsp, XCCR, w);
843 w = MCBSP_READ_CACHE(mcbsp, RCCR);
844 w &= ~(rx ? RDISABLE : 0);
845 MCBSP_WRITE(mcbsp, RCCR, w);
846 }
847
848 /* Dump McBSP Regs */
849 omap_mcbsp_dump_reg(id);
850}
851EXPORT_SYMBOL(omap_mcbsp_start);
852
853void omap_mcbsp_stop(unsigned int id, int tx, int rx)
854{
855 struct omap_mcbsp *mcbsp;
856 int idle;
857 u16 w;
858
859 if (!omap_mcbsp_check_valid_id(id)) {
860 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
861 return;
862 }
863
864 mcbsp = id_to_mcbsp_ptr(id);
865
866 /* Reset transmitter */
867 tx &= 1;
868 if (mcbsp->pdata->has_ccr) {
869 w = MCBSP_READ_CACHE(mcbsp, XCCR);
870 w |= (tx ? XDISABLE : 0);
871 MCBSP_WRITE(mcbsp, XCCR, w);
872 }
873 w = MCBSP_READ_CACHE(mcbsp, SPCR2);
874 MCBSP_WRITE(mcbsp, SPCR2, w & ~tx);
875
876 /* Reset receiver */
877 rx &= 1;
878 if (mcbsp->pdata->has_ccr) {
879 w = MCBSP_READ_CACHE(mcbsp, RCCR);
880 w |= (rx ? RDISABLE : 0);
881 MCBSP_WRITE(mcbsp, RCCR, w);
882 }
883 w = MCBSP_READ_CACHE(mcbsp, SPCR1);
884 MCBSP_WRITE(mcbsp, SPCR1, w & ~rx);
885
886 idle = !((MCBSP_READ_CACHE(mcbsp, SPCR2) |
887 MCBSP_READ_CACHE(mcbsp, SPCR1)) & 1);
888
889 if (idle) {
890 /* Reset the sample rate generator */
891 w = MCBSP_READ_CACHE(mcbsp, SPCR2);
892 MCBSP_WRITE(mcbsp, SPCR2, w & ~(1 << 6));
893 }
894
895 if (mcbsp->st_data)
896 omap_st_stop(mcbsp);
897}
898EXPORT_SYMBOL(omap_mcbsp_stop);
899
900int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id)
901{
902 struct omap_mcbsp *mcbsp;
903 const char *src;
904
905 if (!omap_mcbsp_check_valid_id(id)) {
906 pr_err("%s: Invalid id (%d)\n", __func__, id + 1);
907 return -EINVAL;
908 }
909 mcbsp = id_to_mcbsp_ptr(id);
910
911 if (fck_src_id == MCBSP_CLKS_PAD_SRC)
912 src = "clks_ext";
913 else if (fck_src_id == MCBSP_CLKS_PRCM_SRC)
914 src = "clks_fclk";
915 else
916 return -EINVAL;
917
918 if (mcbsp->pdata->set_clk_src)
919 return mcbsp->pdata->set_clk_src(mcbsp->dev, mcbsp->fclk, src);
920 else
921 return -EINVAL;
922}
923EXPORT_SYMBOL(omap2_mcbsp_set_clks_src);
924
925void omap2_mcbsp1_mux_clkr_src(u8 mux)
926{
927 struct omap_mcbsp *mcbsp;
928 const char *src;
929
930 if (mux == CLKR_SRC_CLKR)
931 src = "clkr";
932 else if (mux == CLKR_SRC_CLKX)
933 src = "clkx";
934 else
935 return;
936
937 mcbsp = id_to_mcbsp_ptr(0);
938 if (mcbsp->pdata->mux_signal)
939 mcbsp->pdata->mux_signal(mcbsp->dev, "clkr", src);
940}
941EXPORT_SYMBOL(omap2_mcbsp1_mux_clkr_src);
942
943void omap2_mcbsp1_mux_fsr_src(u8 mux)
944{
945 struct omap_mcbsp *mcbsp;
946 const char *src;
947
948 if (mux == FSR_SRC_FSR)
949 src = "fsr";
950 else if (mux == FSR_SRC_FSX)
951 src = "fsx";
952 else
953 return;
954
955 mcbsp = id_to_mcbsp_ptr(0);
956 if (mcbsp->pdata->mux_signal)
957 mcbsp->pdata->mux_signal(mcbsp->dev, "fsr", src);
958}
959EXPORT_SYMBOL(omap2_mcbsp1_mux_fsr_src);
960
961#define max_thres(m) (mcbsp->pdata->buffer_size)
962#define valid_threshold(m, val) ((val) <= max_thres(m))
963#define THRESHOLD_PROP_BUILDER(prop) \
964static ssize_t prop##_show(struct device *dev, \
965 struct device_attribute *attr, char *buf) \
966{ \
967 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); \
968 \
969 return sprintf(buf, "%u\n", mcbsp->prop); \
970} \
971 \
972static ssize_t prop##_store(struct device *dev, \
973 struct device_attribute *attr, \
974 const char *buf, size_t size) \
975{ \
976 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); \
977 unsigned long val; \
978 int status; \
979 \
980 status = strict_strtoul(buf, 0, &val); \
981 if (status) \
982 return status; \
983 \
984 if (!valid_threshold(mcbsp, val)) \
985 return -EDOM; \
986 \
987 mcbsp->prop = val; \
988 return size; \
989} \
990 \
991static DEVICE_ATTR(prop, 0644, prop##_show, prop##_store);
992
993THRESHOLD_PROP_BUILDER(max_tx_thres);
994THRESHOLD_PROP_BUILDER(max_rx_thres);
995
996static const char *dma_op_modes[] = {
997 "element", "threshold", "frame",
998};
999
1000static ssize_t dma_op_mode_show(struct device *dev,
1001 struct device_attribute *attr, char *buf)
1002{
1003 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
1004 int dma_op_mode, i = 0;
1005 ssize_t len = 0;
1006 const char * const *s;
1007
1008 dma_op_mode = mcbsp->dma_op_mode;
1009
1010 for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++) {
1011 if (dma_op_mode == i)
1012 len += sprintf(buf + len, "[%s] ", *s);
1013 else
1014 len += sprintf(buf + len, "%s ", *s);
1015 }
1016 len += sprintf(buf + len, "\n");
1017
1018 return len;
1019}
1020
1021static ssize_t dma_op_mode_store(struct device *dev,
1022 struct device_attribute *attr,
1023 const char *buf, size_t size)
1024{
1025 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
1026 const char * const *s;
1027 int i = 0;
1028
1029 for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++)
1030 if (sysfs_streq(buf, *s))
1031 break;
1032
1033 if (i == ARRAY_SIZE(dma_op_modes))
1034 return -EINVAL;
1035
1036 spin_lock_irq(&mcbsp->lock);
1037 if (!mcbsp->free) {
1038 size = -EBUSY;
1039 goto unlock;
1040 }
1041 mcbsp->dma_op_mode = i;
1042
1043unlock:
1044 spin_unlock_irq(&mcbsp->lock);
1045
1046 return size;
1047}
1048
1049static DEVICE_ATTR(dma_op_mode, 0644, dma_op_mode_show, dma_op_mode_store);
1050
1051static const struct attribute *additional_attrs[] = {
1052 &dev_attr_max_tx_thres.attr,
1053 &dev_attr_max_rx_thres.attr,
1054 &dev_attr_dma_op_mode.attr,
1055 NULL,
1056};
1057
1058static const struct attribute_group additional_attr_group = {
1059 .attrs = (struct attribute **)additional_attrs,
1060};
1061
1062static ssize_t st_taps_show(struct device *dev,
1063 struct device_attribute *attr, char *buf)
1064{
1065 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
1066 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
1067 ssize_t status = 0;
1068 int i;
1069
1070 spin_lock_irq(&mcbsp->lock);
1071 for (i = 0; i < st_data->nr_taps; i++)
1072 status += sprintf(&buf[status], (i ? ", %d" : "%d"),
1073 st_data->taps[i]);
1074 if (i)
1075 status += sprintf(&buf[status], "\n");
1076 spin_unlock_irq(&mcbsp->lock);
1077
1078 return status;
1079}
1080
1081static ssize_t st_taps_store(struct device *dev,
1082 struct device_attribute *attr,
1083 const char *buf, size_t size)
1084{
1085 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
1086 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
1087 int val, tmp, status, i = 0;
1088
1089 spin_lock_irq(&mcbsp->lock);
1090 memset(st_data->taps, 0, sizeof(st_data->taps));
1091 st_data->nr_taps = 0;
1092
1093 do {
1094 status = sscanf(buf, "%d%n", &val, &tmp);
1095 if (status < 0 || status == 0) {
1096 size = -EINVAL;
1097 goto out;
1098 }
1099 if (val < -32768 || val > 32767) {
1100 size = -EINVAL;
1101 goto out;
1102 }
1103 st_data->taps[i++] = val;
1104 buf += tmp;
1105 if (*buf != ',')
1106 break;
1107 buf++;
1108 } while (1);
1109
1110 st_data->nr_taps = i;
1111
1112out:
1113 spin_unlock_irq(&mcbsp->lock);
1114
1115 return size;
1116}
1117
1118static DEVICE_ATTR(st_taps, 0644, st_taps_show, st_taps_store);
1119
1120static const struct attribute *sidetone_attrs[] = {
1121 &dev_attr_st_taps.attr,
1122 NULL,
1123};
1124
1125static const struct attribute_group sidetone_attr_group = {
1126 .attrs = (struct attribute **)sidetone_attrs,
1127};
1128
1129static int __devinit omap_st_add(struct omap_mcbsp *mcbsp,
1130 struct resource *res)
1131{
1132 struct omap_mcbsp_st_data *st_data;
1133 int err;
1134
1135 st_data = kzalloc(sizeof(*mcbsp->st_data), GFP_KERNEL);
1136 if (!st_data) {
1137 err = -ENOMEM;
1138 goto err1;
1139 }
1140
1141 st_data->io_base_st = ioremap(res->start, resource_size(res));
1142 if (!st_data->io_base_st) {
1143 err = -ENOMEM;
1144 goto err2;
1145 }
1146
1147 err = sysfs_create_group(&mcbsp->dev->kobj, &sidetone_attr_group);
1148 if (err)
1149 goto err3;
1150
1151 mcbsp->st_data = st_data;
1152 return 0;
1153
1154err3:
1155 iounmap(st_data->io_base_st);
1156err2:
1157 kfree(st_data);
1158err1:
1159 return err;
1160
1161}
1162
1163static void __devexit omap_st_remove(struct omap_mcbsp *mcbsp)
1164{
1165 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
1166
1167 sysfs_remove_group(&mcbsp->dev->kobj, &sidetone_attr_group);
1168 iounmap(st_data->io_base_st);
1169 kfree(st_data);
1170}
1171
1172/*
1173 * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
1174 * 730 has only 2 McBSP, and both of them are MPU peripherals.
1175 */
1176static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
1177{
1178 struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data;
1179 struct omap_mcbsp *mcbsp;
1180 int id = pdev->id - 1;
1181 struct resource *res;
1182 int ret = 0;
1183
1184 if (!pdata) {
1185 dev_err(&pdev->dev, "McBSP device initialized without"
1186 "platform data\n");
1187 ret = -EINVAL;
1188 goto exit;
1189 }
1190
1191 dev_dbg(&pdev->dev, "Initializing OMAP McBSP (%d).\n", pdev->id);
1192
1193 if (id >= omap_mcbsp_count) {
1194 dev_err(&pdev->dev, "Invalid McBSP device id (%d)\n", id);
1195 ret = -EINVAL;
1196 goto exit;
1197 }
1198
1199 mcbsp = kzalloc(sizeof(struct omap_mcbsp), GFP_KERNEL);
1200 if (!mcbsp) {
1201 ret = -ENOMEM;
1202 goto exit;
1203 }
1204
1205 spin_lock_init(&mcbsp->lock);
1206 mcbsp->id = id + 1;
1207 mcbsp->free = true;
1208
1209 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
1210 if (!res) {
1211 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1212 if (!res) {
1213 dev_err(&pdev->dev, "%s:mcbsp%d has invalid memory"
1214 "resource\n", __func__, pdev->id);
1215 ret = -ENOMEM;
1216 goto exit;
1217 }
1218 }
1219 mcbsp->phys_base = res->start;
1220 mcbsp->reg_cache_size = resource_size(res);
1221 mcbsp->io_base = ioremap(res->start, resource_size(res));
1222 if (!mcbsp->io_base) {
1223 ret = -ENOMEM;
1224 goto err_ioremap;
1225 }
1226
1227 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dma");
1228 if (!res)
1229 mcbsp->phys_dma_base = mcbsp->phys_base;
1230 else
1231 mcbsp->phys_dma_base = res->start;
1232
1233 mcbsp->tx_irq = platform_get_irq_byname(pdev, "tx");
1234 mcbsp->rx_irq = platform_get_irq_byname(pdev, "rx");
1235
1236 /* From OMAP4 there will be a single irq line */
1237 if (mcbsp->tx_irq == -ENXIO)
1238 mcbsp->tx_irq = platform_get_irq(pdev, 0);
1239
1240 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
1241 if (!res) {
1242 dev_err(&pdev->dev, "%s:mcbsp%d has invalid rx DMA channel\n",
1243 __func__, pdev->id);
1244 ret = -ENODEV;
1245 goto err_res;
1246 }
1247 mcbsp->dma_rx_sync = res->start;
1248
1249 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
1250 if (!res) {
1251 dev_err(&pdev->dev, "%s:mcbsp%d has invalid tx DMA channel\n",
1252 __func__, pdev->id);
1253 ret = -ENODEV;
1254 goto err_res;
1255 }
1256 mcbsp->dma_tx_sync = res->start;
1257
1258 mcbsp->fclk = clk_get(&pdev->dev, "fck");
1259 if (IS_ERR(mcbsp->fclk)) {
1260 ret = PTR_ERR(mcbsp->fclk);
1261 dev_err(&pdev->dev, "unable to get fck: %d\n", ret);
1262 goto err_res;
1263 }
1264
1265 mcbsp->pdata = pdata;
1266 mcbsp->dev = &pdev->dev;
1267 mcbsp_ptr[id] = mcbsp;
1268 platform_set_drvdata(pdev, mcbsp);
1269 pm_runtime_enable(mcbsp->dev);
1270
1271 mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
1272 if (mcbsp->pdata->buffer_size) {
1273 /*
1274 * Initially configure the maximum thresholds to a safe value.
1275 * The McBSP FIFO usage with these values should not go under
1276 * 16 locations.
1277 * If the whole FIFO without safety buffer is used, than there
1278 * is a possibility that the DMA will be not able to push the
1279 * new data on time, causing channel shifts in runtime.
1280 */
1281 mcbsp->max_tx_thres = max_thres(mcbsp) - 0x10;
1282 mcbsp->max_rx_thres = max_thres(mcbsp) - 0x10;
1283
1284 ret = sysfs_create_group(&mcbsp->dev->kobj,
1285 &additional_attr_group);
1286 if (ret) {
1287 dev_err(mcbsp->dev,
1288 "Unable to create additional controls\n");
1289 goto err_thres;
1290 }
1291 } else {
1292 mcbsp->max_tx_thres = -EINVAL;
1293 mcbsp->max_rx_thres = -EINVAL;
1294 }
1295
1296 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sidetone");
1297 if (res) {
1298 ret = omap_st_add(mcbsp, res);
1299 if (ret) {
1300 dev_err(mcbsp->dev,
1301 "Unable to create sidetone controls\n");
1302 goto err_st;
1303 }
1304 }
1305
1306 return 0;
1307
1308err_st:
1309 if (mcbsp->pdata->buffer_size)
1310 sysfs_remove_group(&mcbsp->dev->kobj,
1311 &additional_attr_group);
1312err_thres:
1313 clk_put(mcbsp->fclk);
1314err_res:
1315 iounmap(mcbsp->io_base);
1316err_ioremap:
1317 kfree(mcbsp);
1318exit:
1319 return ret;
1320}
1321
1322static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
1323{
1324 struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
1325
1326 platform_set_drvdata(pdev, NULL);
1327 if (mcbsp) {
1328
1329 if (mcbsp->pdata && mcbsp->pdata->ops &&
1330 mcbsp->pdata->ops->free)
1331 mcbsp->pdata->ops->free(mcbsp->id);
1332
1333 if (mcbsp->pdata->buffer_size)
1334 sysfs_remove_group(&mcbsp->dev->kobj,
1335 &additional_attr_group);
1336
1337 if (mcbsp->st_data)
1338 omap_st_remove(mcbsp);
1339
1340 clk_put(mcbsp->fclk);
1341
1342 iounmap(mcbsp->io_base);
1343 kfree(mcbsp);
1344 }
1345
1346 return 0;
1347}
1348
1349static struct platform_driver omap_mcbsp_driver = {
1350 .probe = omap_mcbsp_probe,
1351 .remove = __devexit_p(omap_mcbsp_remove),
1352 .driver = {
1353 .name = "omap-mcbsp",
1354 },
1355};
1356
1357int __init omap_mcbsp_init(void)
1358{
1359 /* Register the McBSP driver */
1360 return platform_driver_register(&omap_mcbsp_driver);
1361}