summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-mx51/devices.c3
-rw-r--r--arch/arm/mach-mx51/dummy_gpio.c12
-rw-r--r--arch/arm/mach-mx51/mx51_ccwmx51js.c167
-rw-r--r--arch/arm/mach-mx51/mx51_ccwmx51js_gpio.c203
-rw-r--r--arch/arm/plat-mxc/dvfs_core.c3
-rw-r--r--drivers/i2c/busses/mxc_i2c.c4
-rw-r--r--drivers/usb/core/hcd.c5
-rw-r--r--sound/soc/imx/Kconfig9
-rw-r--r--sound/soc/imx/Makefile3
-rw-r--r--sound/soc/imx/imx-ccwmx51js-wm8753.c342
10 files changed, 660 insertions, 91 deletions
diff --git a/arch/arm/mach-mx51/devices.c b/arch/arm/mach-mx51/devices.c
index 3496580d807f..9f015d43640f 100644
--- a/arch/arm/mach-mx51/devices.c
+++ b/arch/arm/mach-mx51/devices.c
@@ -596,6 +596,7 @@ extern void mx51_babbage_gpio_spi_chipselect_active(int cspi_mode, int status,
int chipselect);
extern void mx51_babbage_gpio_spi_chipselect_inactive(int cspi_mode, int status,
int chipselect);
+
/*! Platform Data for MXC CSPI1 */
static struct mxc_spi_master mxcspi1_data = {
.maxchipselect = 4,
@@ -693,7 +694,7 @@ void __init mxc_init_spi(void)
/* SPBA configuration for CSPI2 - MCU is set */
spba_take_ownership(SPBA_CSPI1, SPBA_MASTER_A);
#ifdef CONFIG_SPI_MXC_SELECT1
- if (machine_is_mx51_babbage()) {
+ if (machine_is_ccwmx51() || machine_is_mx51_babbage()) {
mxcspi1_data.chipselect_active =
mx51_babbage_gpio_spi_chipselect_active;
mxcspi1_data.chipselect_inactive =
diff --git a/arch/arm/mach-mx51/dummy_gpio.c b/arch/arm/mach-mx51/dummy_gpio.c
index bf21862908ac..57bddb92cafe 100644
--- a/arch/arm/mach-mx51/dummy_gpio.c
+++ b/arch/arm/mach-mx51/dummy_gpio.c
@@ -23,12 +23,6 @@ EXPORT_SYMBOL(gpio_gps_inactive);
void config_uartdma_event(int port) {}
EXPORT_SYMBOL(config_uartdma_event);
-void gpio_spi_active(int cspi_mod) {}
-EXPORT_SYMBOL(gpio_spi_active);
-
-void gpio_spi_inactive(int cspi_mod) {}
-EXPORT_SYMBOL(gpio_spi_inactive);
-
void gpio_owire_active(void) {}
EXPORT_SYMBOL(gpio_owire_active);
@@ -73,12 +67,6 @@ EXPORT_SYMBOL(gpio_ata_active);
void gpio_ata_inactive(void) {}
EXPORT_SYMBOL(gpio_ata_inactive);
-void gpio_nand_active(void) {}
-EXPORT_SYMBOL(gpio_nand_active);
-
-void gpio_nand_inactive(void) {}
-EXPORT_SYMBOL(gpio_nand_inactive);
-
void gpio_keypad_active(void) {}
EXPORT_SYMBOL(gpio_keypad_active);
diff --git a/arch/arm/mach-mx51/mx51_ccwmx51js.c b/arch/arm/mach-mx51/mx51_ccwmx51js.c
index 2d603bb3655e..f538fa0e4bfc 100644
--- a/arch/arm/mach-mx51/mx51_ccwmx51js.c
+++ b/arch/arm/mach-mx51/mx51_ccwmx51js.c
@@ -1,6 +1,7 @@
/*
* Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright 2009 Digi International, Inc. All Rights Reserved.
+ * Copyright 2010 Timesys Corporation. All Rights Reserved.
*/
/*
@@ -111,53 +112,6 @@ static void mxc_nop_release(struct device *dev)
/* Nothing */
}
-/* MTD NAND flash */
-#if defined(CONFIG_MTD_NAND_MXC) \
- || defined(CONFIG_MTD_NAND_MXC_MODULE) \
- || defined(CONFIG_MTD_NAND_MXC_V2) \
- || defined(CONFIG_MTD_NAND_MXC_V2_MODULE) \
- || defined(CONFIG_MTD_NAND_MXC_V3) \
- || defined(CONFIG_MTD_NAND_MXC_V3_MODULE)
-
-extern void gpio_nand_active(void);
-extern void gpio_nand_inactive(void);
-
-static int nand_init(void)
-{
- /* Configure the pins */
- gpio_nand_active();
- return 0;
-}
-
-static void nand_exit(void)
-{
- /* Free the pins */
- gpio_nand_inactive();
-}
-
-static struct flash_platform_data mxc_nand_data = {
- .width = 1,
- .init = nand_init,
- .exit = nand_exit,
-};
-
-static struct platform_device mxc_nandv2_mtd_device = {
- .name = "mxc_nandv2_flash",
- .id = 0,
- .dev = {
- .release = mxc_nop_release,
- .platform_data = &mxc_nand_data,
- },
-};
-
-static void ccwmx51_init_nand_mtd(void)
-{
- (void)platform_device_register(&mxc_nandv2_mtd_device);
-}
-#else
-static inline void ccwmx51_init_nand_mtd(void) { }
-#endif
-
#if defined(CONFIG_SMSC9118)
static struct resource smsc911x_device_resources[] = {
[0] = {
@@ -226,7 +180,7 @@ static void ccwmx51_init_ext_eth_mac(void)
(void)platform_device_register(&smsc911x_device);
}
#else
-static void ccwmx51_init_ext_eth_mac(void) { }
+//static void ccwmx51_init_ext_eth_mac(void) { }
#endif
@@ -364,11 +318,33 @@ static inline void ccwmx51_init_mmc(void) {}
#if defined(CONFIG_FB_MXC_SYNC_PANEL) || \
defined(CONFIG_FB_MXC_SYNC_PANEL_MODULE)
+static struct fb_videomode wvga_video_mode =
+{
+ .name = "Digi LCD",
+ .xres = 800,
+ .yres = 480,
+ .refresh = 60,
+ .pixclock = 30062,
+ .left_margin = 64,
+ .right_margin = 64,
+ .lower_margin = 10,
+ .upper_margin = 30,
+ .hsync_len = 128,
+ .vsync_len = 5,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = FB_MODE_IS_DETAILED,
+// Digi says that inverting the clock is necessary
+// to avoid problems with video.
+// .sync = FB_SYNC_CLK_LAT_FALL,
+
+};
+
+
static struct mxc_fb_platform_data fb_data_vga = {
.interface_pix_fmt = IPU_PIX_FMT_RGB24,
- .mode_str = "1024x768M-16@60", /* Default */
};
+
static struct platform_device mxc_fb_device[] = {
{
.name = "mxc_sdc_fb",
@@ -376,7 +352,7 @@ static struct platform_device mxc_fb_device[] = {
.dev = {
.release = mxc_nop_release,
.coherent_dma_mask = 0xFFFFFFFF,
- .platform_data = &fb_data_vga,
+ .platform_data = &fb_data_vga
},
}, {
.name = "mxc_sdc_fb",
@@ -384,7 +360,6 @@ static struct platform_device mxc_fb_device[] = {
.dev = {
.release = mxc_nop_release,
.coherent_dma_mask = 0xFFFFFFFF,
- .platform_data = NULL,
},
}, {
.name = "mxc_sdc_fb",
@@ -396,41 +371,64 @@ static struct platform_device mxc_fb_device[] = {
},
};
+extern void gpio_lcd_active(void);
+
+
+// We let the user specify e.g. 800x600x24, but pay attention
+// only to the 800x600 part, and use 24-bit color regardless.
+static int video_matches(char *user, char *template)
+{
+ return !strncasecmp(user, template, strlen(template));
+}
+
static int __init ccwmx51_init_fb(void)
{
char *options = NULL, *p;
if (fb_get_options("displayfb", &options))
- pr_warning("no display information available in commnad line\n");
+ pr_warning("no display information available in command line\n");
if (!options)
return -ENODEV;
if (!strncasecmp(options, "VGA", 3)) {
pr_info("VGA interface is primary\n");
+
+ fb_data_vga.mode = 0; // Do not use LCD timings.
+ fb_data_vga.mode_str = "1024x768M-16@60"; /* Default */
/* Get the desired configuration provided by the bootloader */
if (options[3] != '@') {
- pr_info("Video resolution for VGA interface not provided, using default\n");
- /* TODO set default video here */
+ pr_info("Video resolution for VGA interface not provided, using '%s'\n",
+ fb_data_vga.mode_str);
} else {
options = &options[4];
if (((p = strsep (&options, "@")) != NULL) && *p) {
- if (!strcmp(p, "640x480x16")) {
- strcpy(fb_data_vga.mode_str, "640x480M-16@60");
- } else if (!strcmp(p, "800x600x16")) {
- strcpy(fb_data_vga.mode_str, "800x600M-16@60");
- } else if (!strcmp(p, "1024x768x16")) {
- strcpy(fb_data_vga.mode_str, "1024x768M-16@60");
- } else if (!strcmp(p, "1280x1024x16")) {
- strcpy(fb_data_vga.mode_str, "1280x1024M-16@60");
- } else if (!strcmp(p, "1280x1024x16")) {
- strcpy(fb_data_vga.mode_str, "1280x1024M-16@60");
+ if (video_matches(p, "640x480") ){
+ fb_data_vga.mode_str = "640x480M-16@60";
+ } else if (video_matches(p, "800x600")) {
+ fb_data_vga.mode_str = "800x600M-16@60";
+ } else if (video_matches(p, "1024x768")) {
+ fb_data_vga.mode_str = "1024x768M-16@60";
+ } else if (video_matches(p, "1280x1024")) {
+ fb_data_vga.mode_str = "1280x1024M-16@60";
+ } else if (video_matches(p, "1280x1024")) {
+ fb_data_vga.mode_str = "1280x1024M-16@60";
+ } else if (video_matches(p, "1280x768")) {
+ fb_data_vga.mode_str = "1280x768M-16@60";
} else
- pr_warning("Unsuported video resolution: %s, using default\n", p);
+ pr_warning("Unsupported video resolution: %s, using default '%s'\n",
+ p, fb_data_vga.mode_str);
}
}
- (void)platform_device_register(&mxc_fb_device[0]); /* VGA */
+ platform_device_register(&mxc_fb_device[0]); /* VGA */
+
+ } else if (!strncasecmp(options, "LCD", 3)){
+ gpio_lcd_active();
+ fb_data_vga.mode = &wvga_video_mode; // Use timings for Digi LCD.
+ fb_data_vga.mode_str = "800x480-16@60", // 16-bit color more compatible with Factory apps
+ pr_info("Using LDC wvga video timings and mode %s\n", fb_data_vga.mode_str);
+ platform_device_register(&mxc_fb_device[0]); /* LCD */
}
return 0;
@@ -503,19 +501,47 @@ static void mxc_power_off(void)
static struct i2c_board_info ccwmx51_i2c_devices[] __initdata = {
#if defined(CONFIG_INPUT_MMA7455L)
+ // accelerometer, unsupported at present.
{
I2C_BOARD_INFO("mma7455l", 0x1d),
.irq = IOMUX_TO_IRQ(MX51_PIN_GPIO1_7),
},
#endif
+
+
+
+
};
-int __init ccwmx51_init_mma7455l(void)
+
+int __init ccwmx51_i2c_setup(void)
{
return i2c_register_board_info(1, ccwmx51_i2c_devices , ARRAY_SIZE(ccwmx51_i2c_devices) );
}
+static struct mxc_audio_platform_data wm8753_data = {
+ .ssi_num = 1,
+ .src_port = 2,
+ .ext_port = 3,
+ .sysclk = 11289600, // So we can do 44.1 kHz
+};
+
+static struct platform_device mxc_wm8753_device = {
+ .name = "imx-ccwmx51js-wm8753",
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &wm8753_data,
+ },
+};
+
+
+static void mxc_init_wm8753(void)
+{
+ platform_device_register(&mxc_wm8753_device);
+}
+
+
/*!
* Board specific initialization.
*/
@@ -528,10 +554,11 @@ static void __init mxc_board_init(void)
mxc_init_devices();
ccwmx51_init_mmc();
- ccwmx51_init_nand_mtd();
-// ccwmx51_init_ext_eth_mac();
- ccwmx51_init_mma7455l();
+
+ ccwmx51_i2c_setup();
ccwmx51_init_mc13892();
+ mxc_init_wm8753();
+
pm_power_off = mxc_power_off;
}
diff --git a/arch/arm/mach-mx51/mx51_ccwmx51js_gpio.c b/arch/arm/mach-mx51/mx51_ccwmx51js_gpio.c
index 3458935cd8cf..0745c89c0625 100644
--- a/arch/arm/mach-mx51/mx51_ccwmx51js_gpio.c
+++ b/arch/arm/mach-mx51/mx51_ccwmx51js_gpio.c
@@ -207,6 +207,12 @@ static struct mxc_iomux_pin_cfg __initdata ccwmx51_iomux_usbh1_pins[] = {
#if defined(CONFIG_FB_MXC_SYNC_PANEL) || defined(CONFIG_FB_MXC_SYNC_PANEL_MODULE)
static struct mxc_iomux_pin_cfg __initdata ccwmx51_iomux_video1_pins[] = {
+ // This pin is necessary to enable the Digi LCD panel on the P1
+ // connector.
+ {
+ MX51_PIN_DI1_PIN11, IOMUX_CONFIG_ALT4,
+ (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST),
+ },
{ /* DISP1 DAT0 */
MX51_PIN_DISP1_DAT0, IOMUX_CONFIG_ALT0,
(PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST),
@@ -359,6 +365,32 @@ static struct mxc_iomux_pin_cfg __initdata ccwmx51_iomux_mma7455l_pins[] = {
#endif //defined(CONFIG_I2C_MXC) || defined(CONFIG_I2C_MXC_MODULE)
static struct mxc_iomux_pin_cfg __initdata ccwmx51_iomux_devices_pins[] = {
+ {
+ MX51_PIN_AUD3_BB_TXD, IOMUX_CONFIG_ALT0,
+ (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_100K_PU | PAD_CTL_HYS_NONE | PAD_CTL_DDR_INPUT_CMOS |
+ PAD_CTL_DRV_VOT_LOW),
+ },
+ {
+ MX51_PIN_AUD3_BB_RXD, IOMUX_CONFIG_ALT0,
+ (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_100K_PU | PAD_CTL_HYS_NONE | PAD_CTL_DDR_INPUT_CMOS |
+ PAD_CTL_DRV_VOT_LOW),
+ },
+ {
+ MX51_PIN_AUD3_BB_CK, IOMUX_CONFIG_ALT0,
+ (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_100K_PU | PAD_CTL_HYS_NONE | PAD_CTL_DDR_INPUT_CMOS |
+ PAD_CTL_DRV_VOT_LOW),
+ },
+ {
+ MX51_PIN_AUD3_BB_FS, IOMUX_CONFIG_ALT0,
+ (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_100K_PU | PAD_CTL_HYS_NONE | PAD_CTL_DDR_INPUT_CMOS |
+ PAD_CTL_DRV_VOT_LOW),
+ },
+
+
{ /* PMIC interrupt line */
MX51_PIN_GPIO1_5, IOMUX_CONFIG_GPIO | IOMUX_CONFIG_SION,
(PAD_CTL_SRE_SLOW | PAD_CTL_DRV_MEDIUM | PAD_CTL_100K_PU |
@@ -422,13 +454,15 @@ void __init ccwmx51_io_init(void)
#if defined(CONFIG_FB_MXC_SYNC_PANEL) || defined(CONFIG_FB_MXC_SYNC_PANEL_MODULE)
for (i = 0; i < ARRAY_SIZE(ccwmx51_iomux_video1_pins); i++) {
mxc_request_iomux(ccwmx51_iomux_video1_pins[i].pin,
- ccwmx51_iomux_video1_pins[i].mux_mode);
+ ccwmx51_iomux_video1_pins[i].mux_mode);
if (ccwmx51_iomux_video1_pins[i].pad_cfg)
mxc_iomux_set_pad(ccwmx51_iomux_video1_pins[i].pin,
ccwmx51_iomux_video1_pins[i].pad_cfg);
+
if (ccwmx51_iomux_video1_pins[i].in_select)
mxc_iomux_set_input(ccwmx51_iomux_video1_pins[i].in_select,
ccwmx51_iomux_video1_pins[i].in_mode);
+
}
#endif
@@ -470,6 +504,15 @@ void __init ccwmx51_io_init(void)
}
+void gpio_lcd_active(void)
+{
+ gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_DI1_PIN11), 0);
+}
+
+
+EXPORT_SYMBOL(gpio_lcd_active);
+
+
#if defined(CONFIG_SERIAL_MXC) || defined(CONFIG_SERIAL_MXC_MODULE)
#define SERIAL_PORT_PAD (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | \
PAD_CTL_PUE_PULL | PAD_CTL_DRV_HIGH | \
@@ -526,3 +569,161 @@ void gpio_uart_active(int port, int no_irda) {}
void gpio_uart_inactive(int port, int no_irda) {}
EXPORT_SYMBOL(gpio_uart_active);
EXPORT_SYMBOL(gpio_uart_inactive);
+
+
+
+/*!
+ * Setup GPIO for a CSPI device to be active
+ *
+ * @param cspi_mod an CSPI device
+ */
+
+void gpio_spi_active(int cspi_mod)
+{
+ switch (cspi_mod) {
+ case 0:
+ /* SPI1 */
+ mxc_request_iomux(MX51_PIN_CSPI1_MOSI, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX51_PIN_CSPI1_MISO, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX51_PIN_CSPI1_SCLK, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX51_PIN_CSPI1_SS0, IOMUX_CONFIG_ALT0);
+
+ mxc_iomux_set_pad(MX51_PIN_CSPI1_MOSI,
+ PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE |
+ PAD_CTL_DRV_HIGH |
+ PAD_CTL_SRE_FAST
+ );
+
+ mxc_iomux_set_pad(MX51_PIN_CSPI1_MISO,
+ PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE |
+ PAD_CTL_DRV_HIGH |
+ PAD_CTL_SRE_FAST
+ );
+
+ mxc_iomux_set_pad(MX51_PIN_CSPI1_SCLK,
+ PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE |
+ PAD_CTL_DRV_HIGH |
+ PAD_CTL_SRE_FAST
+ );
+
+
+ mxc_iomux_set_pad(MX51_PIN_CSPI1_SS0,
+ PAD_CTL_SRE_FAST
+ );
+
+ break;
+ case 1:
+ /* SPI2 */
+ break;
+ default:
+ break;
+ }
+}
+
+
+EXPORT_SYMBOL(gpio_spi_active);
+
+/*!
+ * Setup GPIO for a CSPI device to be inactive
+ *
+ * @param cspi_mod a CSPI device
+ */
+void gpio_spi_inactive(int cspi_mod)
+{
+}
+
+EXPORT_SYMBOL(gpio_spi_inactive);
+
+
+/*
+ *
+ * Investigating ecSPI issue.
+ *
+ */
+
+// copied from babbage code.
+/* workaround for ecspi chipselect pin may not keep correct level when idle */
+void mx51_babbage_gpio_spi_chipselect_active(int cspi_mode, int status,
+ int chipselect)
+{
+ u32 gpio;
+ int r = 0;
+
+ switch (cspi_mode) {
+ case 1:
+ switch (chipselect) {
+ case 0x1:
+ r = mxc_request_iomux(MX51_PIN_CSPI1_SS0,
+ IOMUX_CONFIG_ALT0);
+ if (r){
+ printk("mxc_request_iomux could not get ss0\n");
+ }
+ mxc_iomux_set_pad(MX51_PIN_CSPI1_SS0,
+ PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE |
+ PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST);
+
+ break;
+ case 0x2:
+ gpio = IOMUX_TO_GPIO(MX51_PIN_CSPI1_SS0);
+ r = mxc_request_iomux(MX51_PIN_CSPI1_SS0,
+ IOMUX_CONFIG_GPIO);
+ if (r){
+ printk("mxc_request_iomux could not get ss0 in case 2\n");
+ }
+ r = gpio_request(gpio, "cspi1_ss0");
+ if (r){
+ printk("gpio_request(cspi1_ss0) failed\n");
+ }
+ r = gpio_direction_output(gpio, 0);
+ if (r){
+ printk("gpio_set_direction_output(cspi1_ss0) failed\n");
+ }
+ gpio_set_value(gpio, 1 & (~status));
+ break;
+ default:
+ break;
+ }
+ break;
+ case 2:
+ break;
+ case 3:
+ break;
+ default:
+ break;
+ }
+}
+EXPORT_SYMBOL(mx51_babbage_gpio_spi_chipselect_active);
+
+void mx51_babbage_gpio_spi_chipselect_inactive(int cspi_mode, int status,
+ int chipselect)
+{
+ switch (cspi_mode) {
+ case 1:
+ switch (chipselect) {
+ case 0x1:
+ mxc_free_iomux(MX51_PIN_CSPI1_SS0, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX51_PIN_CSPI1_SS0,
+ IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_CSPI1_SS0, IOMUX_CONFIG_GPIO);
+ break;
+ case 0x2:
+ mxc_free_iomux(MX51_PIN_CSPI1_SS0, IOMUX_CONFIG_GPIO);
+ break;
+ default:
+ break;
+ }
+ break;
+ case 2:
+ break;
+ case 3:
+ break;
+ default:
+ break;
+ }
+}
+EXPORT_SYMBOL(mx51_babbage_gpio_spi_chipselect_inactive);
+
diff --git a/arch/arm/plat-mxc/dvfs_core.c b/arch/arm/plat-mxc/dvfs_core.c
index 169c9feab697..1c09885fde30 100644
--- a/arch/arm/plat-mxc/dvfs_core.c
+++ b/arch/arm/plat-mxc/dvfs_core.c
@@ -829,8 +829,9 @@ static int __devinit mxc_dvfs_core_probe(struct platform_device *pdev)
old_wp = 0;
curr_wp = 0;
dvfs_core_resume = 0;
+#if defined(CONFIG_CPU_FREQ)
cpufreq_trig_needed = 0;
-
+#endif
return err;
err1:
diff --git a/drivers/i2c/busses/mxc_i2c.c b/drivers/i2c/busses/mxc_i2c.c
index f051419f02bc..0a43cdc88ab1 100644
--- a/drivers/i2c/busses/mxc_i2c.c
+++ b/drivers/i2c/busses/mxc_i2c.c
@@ -705,12 +705,8 @@ static int mxci2c_probe(struct platform_device *pdev)
}
}
if (mxc_i2c->clkdiv == -1) {
- i--;
mxc_i2c->clkdiv = 0x1F; /* Use max divider */
}
- dev_dbg(&pdev->dev, "i2c speed is %d/%d = %d bps, reg val = 0x%02X\n",
- clk_freq, i2c_clk_table[i].div,
- clk_freq / i2c_clk_table[i].div, mxc_i2c->clkdiv);
/*
* Set the adapter information
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 3208360664c8..5650778ef001 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -117,7 +117,7 @@ static inline int is_root_hub(struct usb_device *udev)
return (udev->parent == NULL);
}
-#if CONFIG_PM
+#ifdef CONFIG_PM
extern int usb_host_wakeup_irq(struct device *wkup_dev);
extern void usb_host_set_wakeup(struct device *wkup_dev, bool para);
#endif
@@ -1730,6 +1730,8 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd)
local_irq_save(flags);
if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
+
+#ifdef CONFIG_PM
/* if receive a remote wakeup interrrupt after suspend */
if (usb_host_wakeup_irq(hcd->self.controller)) {
/* disable remote wake up irq */
@@ -1738,6 +1740,7 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd)
hcd->driver->irq(hcd);
rc = IRQ_HANDLED;
} else
+#endif
rc = IRQ_NONE;
} else if (unlikely(hcd->state == HC_STATE_HALT)) {
rc = IRQ_NONE;
diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig
index c81f943a2e10..ddecb6ad62fe 100644
--- a/sound/soc/imx/Kconfig
+++ b/sound/soc/imx/Kconfig
@@ -37,6 +37,15 @@ config SND_SOC_IMX_3STACK_SGTL5000
Say Y if you want to add support for SoC audio on IMX 3STACK
with the SGTL5000.
+
+config SND_SOC_IMX_CCWMX51JS
+ tristate "SoC Audio support for Digi CCWMX51JS"
+ select SND_MXC_SOC_SSI
+ select SND_SOC_WM8753
+ help
+ Say Y if you want to add support for SoC audio on Digi
+ CCWMX51JS with the WM8753 codec.
+
config SND_SOC_IMX_3STACK_AK4647
tristate "SoC Audio support for IMX - AK4647"
select SND_MXC_SOC_SSI
diff --git a/sound/soc/imx/Makefile b/sound/soc/imx/Makefile
index 0460f965a85b..57c645ae7c44 100644
--- a/sound/soc/imx/Makefile
+++ b/sound/soc/imx/Makefile
@@ -20,4 +20,5 @@ snd-soc-imx-3stack-ak5702-objs := imx-3stack-ak5702.o
obj-$(CONFIG_SND_SOC_IMX_3STACK_AK5702) += snd-soc-imx-3stack-ak5702.o
snd-soc-imx-3stack-bt-objs := imx-3stack-bt.o
obj-$(CONFIG_SND_SOC_IMX_3STACK_BLUETOOTH) += snd-soc-imx-3stack-bt.o
-
+snd-soc-imx-ccwmx51js-wm8753-objs := imx-ccwmx51js-wm8753.o
+obj-$(CONFIG_SND_SOC_IMX_CCWMX51JS) += snd-soc-imx-ccwmx51js-wm8753.o
diff --git a/sound/soc/imx/imx-ccwmx51js-wm8753.c b/sound/soc/imx/imx-ccwmx51js-wm8753.c
new file mode 100644
index 000000000000..c9c4d425143f
--- /dev/null
+++ b/sound/soc/imx/imx-ccwmx51js-wm8753.c
@@ -0,0 +1,342 @@
+/*
+ * imx-ccwmx51js-wm8753.c -- i.MX Driver for Digi CCWMS51JS and the Wolfson WM8753 Codec
+ *
+ * Adapted by Timesys from sgtl5000 machine driver and other sources.
+ *
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2010 Timesys Corpotation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Based on sound/soc/imx/imx-3stack-sgtl5000.c
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+
+#include <mach/dma.h>
+#include <mach/spba.h>
+#include <mach/clock.h>
+#include <mach/mxc.h>
+#include "../codecs/wm8753.h"
+#include "imx-ssi.h"
+#include "imx-pcm.h"
+
+
+/* SSI BCLK and LRC master
+ *
+ * Set WM8753_SSI_MASTER to operate the WM8753 codec in master mode,
+ * and set to zero to operate it in slave mode.
+ */
+#define WM8753_SSI_MASTER 1
+
+
+struct ccwmx51_priv {
+ int sysclk;
+ struct platform_device *pdev;
+};
+
+static struct ccwmx51_priv machine_priv;
+
+static struct snd_soc_dai ccwmx51_cpu_dai;
+
+
+static int ccwmx51js_audio_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai_link *machine = rtd->dai;
+ struct snd_soc_dai *cpu_dai = machine->cpu_dai;
+ struct snd_soc_dai *codec_dai = machine->codec_dai;
+ struct ccwmx51_priv *priv = &machine_priv;
+ int ret = 0;
+
+ unsigned int channels = params_channels(params);
+ u32 dai_format;
+
+
+#if WM8753_SSI_MASTER
+ dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_SYNC;
+ if (channels == 2)
+ dai_format |= SND_SOC_DAIFMT_TDM;
+
+ /* set codec DAI configuration */
+ ret = snd_soc_dai_set_fmt(codec_dai, dai_format);
+ if (ret < 0)
+ return ret;
+
+ /* set cpu DAI configuration */
+ ret = snd_soc_dai_set_fmt(cpu_dai, dai_format);
+
+ if (ret < 0)
+ return ret;
+#else
+ dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_SYNC;
+ if (channels == 2)
+ dai_format |= SND_SOC_DAIFMT_TDM;
+
+ /* set codec DAI configuration */
+ ret = snd_soc_dai_set_fmt(codec_dai, dai_format);
+ if (ret < 0)
+ return ret;
+
+ /* set cpu DAI configuration */
+ ret = snd_soc_dai_set_fmt(cpu_dai, dai_format);
+
+ if (ret < 0)
+ return ret;
+#endif
+
+ snd_soc_dai_set_sysclk(codec_dai, WM8753_MCLK, priv->sysclk, 0);
+
+ /* set i.MX active slot mask */
+ snd_soc_dai_set_tdm_slot(cpu_dai,
+ channels == 1 ? 0xfffffffe : 0xfffffffc, 2);
+
+ /* set the SSI system clock as input (unused) */
+ snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0, SND_SOC_CLOCK_IN);
+
+
+ /* The WM8753 PLL on the Digi CCWMX51JS is referenced to a fixed 13-MHz
+ * oscillator. We presently operate the PLL only at 11.289600
+ * MHz output, which supports a 44.1-kHz sample rate and a few others.
+ *
+ */
+
+ // set codec BCLK division for sample rate */
+ ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_BCLKDIV, WM8753_BCLK_DIV_4);
+ if (ret < 0)
+ return ret;
+
+ // Specify input PLL frequency and desired output frequency.
+ ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 13000000, 11289600);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+
+
+ // Sets up the i.mx51 Digital Audio Multiplexer
+static void ccwmx51_init_dam(int ssi_port, int dai_port)
+{
+ unsigned int ssi_ptcr = 0;
+ unsigned int dai_ptcr = 0;
+ unsigned int ssi_pdcr = 0;
+ unsigned int dai_pdcr = 0;
+ /* i.mx51 uses SSI1 or SSI2 via AUDMUX port dai_port for audio */
+
+ /* reset port ssi_port & dai_port */
+ __raw_writel(0, DAM_PTCR(ssi_port));
+ __raw_writel(0, DAM_PTCR(dai_port));
+ __raw_writel(0, DAM_PDCR(ssi_port));
+ __raw_writel(0, DAM_PDCR(dai_port));
+
+ /* set to synchronous */
+ ssi_ptcr |= AUDMUX_PTCR_SYN;
+ dai_ptcr |= AUDMUX_PTCR_SYN;
+
+#if WM8753_SSI_MASTER
+ /* set Rx sources ssi_port <--> dai_port */
+ ssi_pdcr |= AUDMUX_PDCR_RXDSEL(dai_port);
+ dai_pdcr |= AUDMUX_PDCR_RXDSEL(ssi_port);
+
+ /* set Tx frame direction and source dai_port--> ssi_port output */
+ ssi_ptcr |= AUDMUX_PTCR_TFSDIR;
+ ssi_ptcr |= AUDMUX_PTCR_TFSSEL(AUDMUX_FROM_TXFS, dai_port);
+
+ /* set Tx Clock direction and source dai_port--> ssi_port output */
+ ssi_ptcr |= AUDMUX_PTCR_TCLKDIR;
+ ssi_ptcr |= AUDMUX_PTCR_TCSEL(AUDMUX_FROM_TXFS, dai_port);
+#else
+ /* set Rx sources ssi_port <--> dai_port */
+ ssi_pdcr |= AUDMUX_PDCR_RXDSEL(dai_port);
+ dai_pdcr |= AUDMUX_PDCR_RXDSEL(ssi_port);
+
+ /* set Tx frame direction and source ssi_port --> dai_port output */
+ dai_ptcr |= AUDMUX_PTCR_TFSDIR;
+ dai_ptcr |= AUDMUX_PTCR_TFSSEL(AUDMUX_FROM_TXFS, ssi_port);
+
+ /* set Tx Clock direction and source ssi_port--> dai_port output */
+ dai_ptcr |= AUDMUX_PTCR_TCLKDIR;
+ dai_ptcr |= AUDMUX_PTCR_TCSEL(AUDMUX_FROM_TXFS, ssi_port);
+#endif
+
+ __raw_writel(ssi_ptcr, DAM_PTCR(ssi_port));
+ __raw_writel(dai_ptcr, DAM_PTCR(dai_port));
+ __raw_writel(ssi_pdcr, DAM_PDCR(ssi_port));
+ __raw_writel(dai_pdcr, DAM_PDCR(dai_port));
+}
+
+
+
+/*
+ * Still to do: set the line out to become enabled within
+ * this driver. Currently the initial driver configuration
+ * has all outputs disabled. They can be enabled in user space
+ * by doing:
+ *
+ * amixer sset 'Left Mixer Left' unmute
+ * amixer sset 'Right Mixer Right Playback Swit' unmute
+ *
+ */
+static int ccwmx51js_startup(struct snd_pcm_substream *substream)
+{
+ return 0;
+}
+
+static void ccwmx51js_shutdown(struct snd_pcm_substream *substream)
+{
+}
+
+static struct snd_soc_ops ccwmx51js_ops = {
+ .startup = ccwmx51js_startup,
+ .shutdown = ccwmx51js_shutdown,
+ .hw_params = ccwmx51js_audio_hw_params,
+};
+
+
+ // Logic for wm8753 as connected on Digi CCWMX51JS board.
+static int ccwmx51js_wm8753_init(struct snd_soc_codec *codec)
+{
+ return 0;
+}
+
+
+/* digital audio interface glue - connects codec <--> CPU */
+static struct snd_soc_dai_link ccwmx51js_dai = {
+ .name = "CCWMX51JS WM8753",
+
+ .stream_name = "WM8753 HiFi",
+ .cpu_dai = &ccwmx51_cpu_dai,
+ .codec_dai = &wm8753_dai[WM8753_DAI_HIFI],
+ .init = ccwmx51js_wm8753_init,
+ .ops = &ccwmx51js_ops,
+};
+
+static int ccwmx51js_machine_remove(struct platform_device *pdev)
+{
+ struct ccwmx51_priv *priv = &machine_priv;
+ struct mxc_audio_platform_data *plat;
+
+ if (priv->pdev) {
+ plat = priv->pdev->dev.platform_data;
+ if (plat->finit)
+ plat->finit();
+ }
+
+ return 0;
+}
+
+/* audio machine driver */
+static struct snd_soc_machine snd_soc_machine_ccwmx51js = {
+ .name = "imx-ccwmx51js",
+ .dai_link = &ccwmx51js_dai,
+ .num_links = 1,
+ .remove = ccwmx51js_machine_remove,
+};
+
+static struct wm8753_setup_data ccwmx51_wm8753_setup = {
+ .i2c_address = 0x1a,
+ .i2c_bus = 1,
+};
+
+static struct snd_soc_device ccwmx51js_snd_devdata = {
+ .machine = &snd_soc_machine_ccwmx51js,
+ .platform = &imx_soc_platform,
+ .codec_dev = &soc_codec_dev_wm8753,
+ .codec_data = &ccwmx51_wm8753_setup,
+};
+
+static int __devinit ccwmx51js_wm8753_probe(struct platform_device *pdev)
+{
+ struct mxc_audio_platform_data *plat = pdev->dev.platform_data;
+ struct ccwmx51_priv *priv = &machine_priv;
+ int ret = 0;
+
+ priv->sysclk = plat->sysclk;
+ priv->pdev = pdev;
+
+ imx_ssi_dai_init(&ccwmx51_cpu_dai);
+ ccwmx51_cpu_dai.private_data = plat;
+
+ ccwmx51_init_dam(plat->src_port, plat->ext_port);
+
+ if (plat->src_port == 2)
+ ccwmx51_cpu_dai.name = "imx-ssi-3";
+ else
+ ccwmx51_cpu_dai.name = "imx-ssi-1";
+
+ ret = -EINVAL;
+ if (plat->init && plat->init()){
+ goto err_plat_init;
+ }
+ return 0;
+
+err_plat_init:
+ return ret;
+}
+
+static int ccwmx51js_wm8753_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static struct platform_driver ccwmx51js_wm8753_audio_driver = {
+ .probe = ccwmx51js_wm8753_probe,
+ .remove = ccwmx51js_wm8753_remove,
+ .driver = {
+ .name = "imx-ccwmx51js-wm8753",
+ },
+};
+
+static struct platform_device *ccwmx51js_snd_device;
+
+static int __init ccwmx51js_init(void)
+{
+ int ret;
+
+ ret = platform_driver_register(&ccwmx51js_wm8753_audio_driver);
+ if (ret)
+ return -ENOMEM;
+
+ ccwmx51js_snd_device = platform_device_alloc("soc-audio", -1);
+ if (!ccwmx51js_snd_device)
+ return -ENOMEM;
+
+ platform_set_drvdata(ccwmx51js_snd_device, &ccwmx51js_snd_devdata);
+ ccwmx51js_snd_devdata.dev = &ccwmx51js_snd_device->dev;
+ ret = platform_device_add(ccwmx51js_snd_device);
+
+ if (ret)
+ platform_device_put(ccwmx51js_snd_device);
+
+ return ret;
+}
+
+static void __exit ccwmx51js_exit(void)
+{
+ platform_driver_unregister(&ccwmx51js_wm8753_audio_driver);
+ platform_device_unregister(ccwmx51js_snd_device);
+}
+
+module_init(ccwmx51js_init);
+module_exit(ccwmx51js_exit);
+
+MODULE_AUTHOR("Timesys");
+MODULE_DESCRIPTION("WM8753 Driver for Digi CCWMX51JS");
+MODULE_LICENSE("GPL");