aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2010-02-09 05:04:36 -0500
committerSascha Hauer <s.hauer@pengutronix.de>2010-02-10 05:05:23 -0500
commitd2831d1f543489ef97a20e6e65f625e195b521bf (patch)
tree707886f8f8b764d5fbed12f00a216d25a8831aad /arch
parentc8a6885f2153087668b64d4ee25f78a7dda1dadb (diff)
i.MX pcm043: Add AC97 sound support
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-mx3/mach-pcm043.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/arch/arm/mach-mx3/mach-pcm043.c b/arch/arm/mach-mx3/mach-pcm043.c
index a9741c2b379f..1bf1ec2eef5e 100644
--- a/arch/arm/mach-mx3/mach-pcm043.c
+++ b/arch/arm/mach-mx3/mach-pcm043.c
@@ -26,6 +26,7 @@
26#include <linux/gpio.h> 26#include <linux/gpio.h>
27#include <linux/smc911x.h> 27#include <linux/smc911x.h>
28#include <linux/interrupt.h> 28#include <linux/interrupt.h>
29#include <linux/delay.h>
29#include <linux/i2c.h> 30#include <linux/i2c.h>
30#include <linux/i2c/at24.h> 31#include <linux/i2c/at24.h>
31#include <linux/usb/otg.h> 32#include <linux/usb/otg.h>
@@ -49,6 +50,8 @@
49#include <mach/mxc_nand.h> 50#include <mach/mxc_nand.h>
50#include <mach/mxc_ehci.h> 51#include <mach/mxc_ehci.h>
51#include <mach/ulpi.h> 52#include <mach/ulpi.h>
53#include <mach/audmux.h>
54#include <mach/ssi.h>
52 55
53#include "devices.h" 56#include "devices.h"
54 57
@@ -213,6 +216,91 @@ static struct pad_desc pcm043_pads[] = {
213 /* USB host */ 216 /* USB host */
214 MX35_PAD_I2C2_CLK__USB_TOP_USBH2_PWR, 217 MX35_PAD_I2C2_CLK__USB_TOP_USBH2_PWR,
215 MX35_PAD_I2C2_DAT__USB_TOP_USBH2_OC, 218 MX35_PAD_I2C2_DAT__USB_TOP_USBH2_OC,
219 /* SSI */
220 MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS,
221 MX35_PAD_STXD4__AUDMUX_AUD4_TXD,
222 MX35_PAD_SRXD4__AUDMUX_AUD4_RXD,
223 MX35_PAD_SCK4__AUDMUX_AUD4_TXC,
224};
225
226#define AC97_GPIO_TXFS (1 * 32 + 31)
227#define AC97_GPIO_TXD (1 * 32 + 28)
228#define AC97_GPIO_RESET (1 * 32 + 0)
229
230static void pcm043_ac97_warm_reset(struct snd_ac97 *ac97)
231{
232 struct pad_desc txfs_gpio = MX35_PAD_STXFS4__GPIO2_31;
233 struct pad_desc txfs = MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS;
234 int ret;
235
236 ret = gpio_request(AC97_GPIO_TXFS, "SSI");
237 if (ret) {
238 printk("failed to get GPIO_TXFS: %d\n", ret);
239 return;
240 }
241
242 mxc_iomux_v3_setup_pad(&txfs_gpio);
243
244 /* warm reset */
245 gpio_direction_output(AC97_GPIO_TXFS, 1);
246 udelay(2);
247 gpio_set_value(AC97_GPIO_TXFS, 0);
248
249 gpio_free(AC97_GPIO_TXFS);
250 mxc_iomux_v3_setup_pad(&txfs);
251}
252
253static void pcm043_ac97_cold_reset(struct snd_ac97 *ac97)
254{
255 struct pad_desc txfs_gpio = MX35_PAD_STXFS4__GPIO2_31;
256 struct pad_desc txfs = MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS;
257 struct pad_desc txd_gpio = MX35_PAD_STXD4__GPIO2_28;
258 struct pad_desc txd = MX35_PAD_STXD4__AUDMUX_AUD4_TXD;
259 struct pad_desc reset_gpio = MX35_PAD_SD2_CMD__GPIO2_0;
260 int ret;
261
262 ret = gpio_request(AC97_GPIO_TXFS, "SSI");
263 if (ret)
264 goto err1;
265
266 ret = gpio_request(AC97_GPIO_TXD, "SSI");
267 if (ret)
268 goto err2;
269
270 ret = gpio_request(AC97_GPIO_RESET, "SSI");
271 if (ret)
272 goto err3;
273
274 mxc_iomux_v3_setup_pad(&txfs_gpio);
275 mxc_iomux_v3_setup_pad(&txd_gpio);
276 mxc_iomux_v3_setup_pad(&reset_gpio);
277
278 gpio_direction_output(AC97_GPIO_TXFS, 0);
279 gpio_direction_output(AC97_GPIO_TXD, 0);
280
281 /* cold reset */
282 gpio_direction_output(AC97_GPIO_RESET, 0);
283 udelay(10);
284 gpio_direction_output(AC97_GPIO_RESET, 1);
285
286 mxc_iomux_v3_setup_pad(&txd);
287 mxc_iomux_v3_setup_pad(&txfs);
288
289 gpio_free(AC97_GPIO_RESET);
290err3:
291 gpio_free(AC97_GPIO_TXD);
292err2:
293 gpio_free(AC97_GPIO_TXFS);
294err1:
295 if (ret)
296 printk("%s failed with %d\n", __func__, ret);
297 mdelay(1);
298}
299
300static struct imx_ssi_platform_data pcm043_ssi_pdata = {
301 .ac97_reset = pcm043_ac97_cold_reset,
302 .ac97_warm_reset = pcm043_ac97_warm_reset,
303 .flags = IMX_SSI_USE_AC97,
216}; 304};
217 305
218static struct mxc_nand_platform_data pcm037_nand_board_info = { 306static struct mxc_nand_platform_data pcm037_nand_board_info = {
@@ -258,10 +346,23 @@ static void __init mxc_board_init(void)
258{ 346{
259 mxc_iomux_v3_setup_multiple_pads(pcm043_pads, ARRAY_SIZE(pcm043_pads)); 347 mxc_iomux_v3_setup_multiple_pads(pcm043_pads, ARRAY_SIZE(pcm043_pads));
260 348
349 mxc_audmux_v2_configure_port(3,
350 MXC_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
351 MXC_AUDMUX_V2_PTCR_TFSEL(0) |
352 MXC_AUDMUX_V2_PTCR_TFSDIR,
353 MXC_AUDMUX_V2_PDCR_RXDSEL(0));
354
355 mxc_audmux_v2_configure_port(0,
356 MXC_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
357 MXC_AUDMUX_V2_PTCR_TCSEL(3) |
358 MXC_AUDMUX_V2_PTCR_TCLKDIR, /* clock is output */
359 MXC_AUDMUX_V2_PDCR_RXDSEL(3));
360
261 platform_add_devices(devices, ARRAY_SIZE(devices)); 361 platform_add_devices(devices, ARRAY_SIZE(devices));
262 362
263 mxc_register_device(&mxc_uart_device0, &uart_pdata); 363 mxc_register_device(&mxc_uart_device0, &uart_pdata);
264 mxc_register_device(&mxc_nand_device, &pcm037_nand_board_info); 364 mxc_register_device(&mxc_nand_device, &pcm037_nand_board_info);
365 mxc_register_device(&imx_ssi_device0, &pcm043_ssi_pdata);
265 366
266 mxc_register_device(&mxc_uart_device1, &uart_pdata); 367 mxc_register_device(&mxc_uart_device1, &uart_pdata);
267 368