mirror of
https://github.com/genesi/linux-legacy.git
synced 2026-09-24 23:54:24 +00:00
bypass bit set to wrong possition. So ssp alays use xtal. mmc use ssp module divider instead of ssp clock source Signed-off-by: Frank Li <Frank.Li@freescale.com>
1016 lines
23 KiB
C
1016 lines
23 KiB
C
/*
|
|
* Copyright (C) 2009-2010 Freescale Semiconductor, Inc. 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.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*/
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/init.h>
|
|
#include <linux/irq.h>
|
|
#include <linux/clk.h>
|
|
#include <linux/err.h>
|
|
#include <linux/io.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/input.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/mmc/host.h>
|
|
#include <linux/phy.h>
|
|
#include <linux/fec.h>
|
|
#include <linux/gpmi-nfc.h>
|
|
|
|
#include <asm/mach/map.h>
|
|
|
|
#include <mach/hardware.h>
|
|
#include <mach/regs-timrot.h>
|
|
#include <mach/regs-lradc.h>
|
|
#include <mach/device.h>
|
|
#include <mach/dma.h>
|
|
#include <mach/irqs.h>
|
|
#include <mach/lradc.h>
|
|
#include <mach/lcdif.h>
|
|
#include <mach/ddi_bc.h>
|
|
|
|
#include "device.h"
|
|
#include "mx23_pins.h"
|
|
#include "mx23evk.h"
|
|
#include "mach/mx23.h"
|
|
|
|
#if defined(CONFIG_SERIAL_MXS_DUART) || \
|
|
defined(CONFIG_SERIAL_MXS_DUART_MODULE)
|
|
static struct resource duart_resource[] = {
|
|
{
|
|
.flags = IORESOURCE_MEM,
|
|
.start = DUART_PHYS_ADDR,
|
|
.end = DUART_PHYS_ADDR + 0x1000 - 1,
|
|
},
|
|
{
|
|
.flags = IORESOURCE_IRQ,
|
|
.start = IRQ_DEBUG_UART ,
|
|
.end = IRQ_DEBUG_UART ,
|
|
},
|
|
};
|
|
|
|
static void __init mx23_init_duart(void)
|
|
{
|
|
struct platform_device *pdev;
|
|
pdev = mxs_get_device("mxs-duart", 0);
|
|
if (pdev == NULL || IS_ERR(pdev))
|
|
return;
|
|
pdev->resource = duart_resource;
|
|
pdev->num_resources = ARRAY_SIZE(duart_resource);
|
|
mxs_add_device(pdev, 3);
|
|
}
|
|
#else
|
|
static void mx23_init_duart(void)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
#if defined(CONFIG_MXS_DMA_ENGINE)
|
|
static struct resource mxs_ahb_apbh_res = {
|
|
.flags = IORESOURCE_MEM,
|
|
.start = APBH_DMA_PHYS_ADDR,
|
|
.end = APBH_DMA_PHYS_ADDR + 0x2000 - 1,
|
|
};
|
|
|
|
static struct mxs_dma_plat_data mxs_ahb_apbh_data = {
|
|
.chan_base = MXS_DMA_CHANNEL_AHB_APBH,
|
|
.chan_num = 8,
|
|
};
|
|
|
|
static struct resource mxs_ahb_apbx_res = {
|
|
.flags = IORESOURCE_MEM,
|
|
.start = APBX_DMA_PHYS_ADDR,
|
|
.end = APBX_DMA_PHYS_ADDR + 0x2000 - 1,
|
|
};
|
|
|
|
static struct mxs_dma_plat_data mxs_ahb_apbx_data = {
|
|
.chan_base = MXS_DMA_CHANNEL_AHB_APBX,
|
|
.chan_num = 16,
|
|
};
|
|
|
|
static void __init mx23_init_dma(void)
|
|
{
|
|
int i;
|
|
struct mxs_dev_lookup *lookup;
|
|
struct platform_device *pdev;
|
|
lookup = mxs_get_devices("mxs-dma");
|
|
if (lookup == NULL || IS_ERR(lookup))
|
|
return;
|
|
for (i = 0; i < lookup->size; i++) {
|
|
pdev = lookup->pdev + i;
|
|
if (!strcmp(pdev->name, "mxs-dma-apbh")) {
|
|
pdev->resource = &mxs_ahb_apbh_res;
|
|
pdev->dev.platform_data = &mxs_ahb_apbh_data;
|
|
} else if (!strcmp(pdev->name, "mxs-dma-apbx")) {
|
|
pdev->resource = &mxs_ahb_apbx_res;
|
|
pdev->dev.platform_data = &mxs_ahb_apbx_data;
|
|
} else
|
|
continue;
|
|
pdev->num_resources = 1;
|
|
mxs_add_device(pdev, 0);
|
|
}
|
|
}
|
|
#else
|
|
static void mx23_init_dma(void)
|
|
{
|
|
;
|
|
}
|
|
#endif
|
|
|
|
#if defined(CONFIG_FB_MXS) || defined(CONFIG_FB_MXS_MODULE)
|
|
static struct resource framebuffer_resource[] = {
|
|
{
|
|
.flags = IORESOURCE_MEM,
|
|
.start = LCDIF_PHYS_ADDR,
|
|
.end = LCDIF_PHYS_ADDR + 0x2000 - 1,
|
|
},
|
|
{
|
|
.flags = IORESOURCE_IRQ,
|
|
.start = IRQ_LCDIF_ERROR,
|
|
.end = IRQ_LCDIF_ERROR,
|
|
},
|
|
};
|
|
|
|
static struct mxs_platform_fb_data mxs_framebuffer_pdata = {
|
|
.list = LIST_HEAD_INIT(mxs_framebuffer_pdata.list),
|
|
};
|
|
|
|
static void __init mx23_init_lcdif(void)
|
|
{
|
|
struct platform_device *pdev;
|
|
pdev = mxs_get_device("mxs-fb", 0);
|
|
if (pdev == NULL || IS_ERR(pdev))
|
|
return;
|
|
pdev->resource = framebuffer_resource;
|
|
pdev->num_resources = ARRAY_SIZE(framebuffer_resource);
|
|
pdev->dev.platform_data = &mxs_framebuffer_pdata;
|
|
mxs_add_device(pdev, 3);
|
|
}
|
|
#else
|
|
static void __init mx23_init_lcdif(void)
|
|
{
|
|
;
|
|
}
|
|
#endif
|
|
|
|
#if defined(CONFIG_VIDEO_MXS_PXP) || \
|
|
defined(CONFIG_VIDEO_MXS_PXP_MODULE)
|
|
static struct resource pxp_resource[] = {
|
|
{
|
|
.flags = IORESOURCE_MEM,
|
|
.start = (unsigned int)IO_ADDRESS(PXP_PHYS_ADDR),
|
|
.end = (unsigned int)IO_ADDRESS(PXP_PHYS_ADDR) + 0x2000 - 1,
|
|
}, {
|
|
.flags = IORESOURCE_IRQ,
|
|
.start = IRQ_PXP,
|
|
.end = IRQ_PXP,
|
|
},
|
|
};
|
|
static void __init mx23_init_pxp(void)
|
|
{
|
|
struct platform_device *pdev;
|
|
pdev = mxs_get_device("mxs-pxp", 0);
|
|
if (pdev == NULL || IS_ERR(pdev))
|
|
return;
|
|
pdev->resource = pxp_resource;
|
|
pdev->num_resources = ARRAY_SIZE(pxp_resource);
|
|
mxs_add_device(pdev, 3);
|
|
}
|
|
#else
|
|
static void __init mx23_init_pxp(void)
|
|
{
|
|
;
|
|
}
|
|
#endif
|
|
|
|
#if defined(CONFIG_MXS_VIIM) || defined(CONFIG_MXS_VIIM_MODULE)
|
|
struct resource viim_resources[] = {
|
|
[0] = {
|
|
.start = DIGCTL_PHYS_ADDR,
|
|
.end = DIGCTL_PHYS_ADDR + PAGE_SIZE - 1,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
[1] = {
|
|
.start = OCOTP_PHYS_ADDR,
|
|
.end = OCOTP_PHYS_ADDR + PAGE_SIZE - 1,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
};
|
|
static void __init mx23_init_viim(void)
|
|
{
|
|
struct platform_device *pdev;
|
|
|
|
pdev = mxs_get_device("mxs_viim", 0);
|
|
if (pdev == NULL || IS_ERR(pdev))
|
|
return;
|
|
|
|
pdev->resource = viim_resources;
|
|
pdev->num_resources = ARRAY_SIZE(viim_resources);
|
|
|
|
mxs_add_device(pdev, 2);
|
|
}
|
|
#else
|
|
static void __init mx23_init_viim(void)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
#if defined(CONFIG_I2C_MXS) || \
|
|
defined(CONFIG_I2C_MXS_MODULE)
|
|
static struct resource i2c_resource[] = {
|
|
{
|
|
.flags = IORESOURCE_MEM,
|
|
.start = I2C0_PHYS_ADDR,
|
|
.end = I2C0_PHYS_ADDR + 0x2000 - 1,
|
|
},
|
|
{
|
|
.flags = IORESOURCE_DMA,
|
|
.start = MXS_DMA_CHANNEL_AHB_APBX_I2C,
|
|
.end = MXS_DMA_CHANNEL_AHB_APBX_I2C,
|
|
},
|
|
{
|
|
.flags = IORESOURCE_IRQ,
|
|
.start = IRQ_I2C_ERROR,
|
|
.end = IRQ_I2C_ERROR,
|
|
},
|
|
{
|
|
.flags = IORESOURCE_IRQ,
|
|
.start = IRQ_I2C_DMA,
|
|
.end = IRQ_I2C_DMA,
|
|
},
|
|
};
|
|
|
|
static struct mxs_i2c_plat_data i2c_platdata = {
|
|
#ifdef CONFIG_I2C_MXS_SELECT0_PIOQUEUE_MODE
|
|
.pioqueue_mode = 0,
|
|
#endif
|
|
};
|
|
|
|
static void __init mx23_init_i2c(void)
|
|
{
|
|
struct platform_device *pdev;
|
|
|
|
pdev = mxs_get_device("mxs-i2c", 0);
|
|
if (pdev == NULL || IS_ERR(pdev))
|
|
return;
|
|
|
|
pdev->resource = i2c_resource;
|
|
pdev->num_resources = ARRAY_SIZE(i2c_resource);
|
|
pdev->dev.platform_data = &i2c_platdata;
|
|
|
|
mxs_add_device(pdev, 2);
|
|
}
|
|
#else
|
|
static void __init mx23_init_i2c(void)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
#if defined(CONFIG_MXS_WATCHDOG) || defined(CONFIG_MXS_WATCHDOG_MODULE)
|
|
static struct resource mx23_wdt_res = {
|
|
.flags = IORESOURCE_MEM,
|
|
.start = RTC_PHYS_ADDR,
|
|
.end = RTC_PHYS_ADDR + 0x2000 - 1,
|
|
};
|
|
|
|
static void __init mx23_init_wdt(void)
|
|
{
|
|
struct platform_device *pdev;
|
|
pdev = mxs_get_device("mxs-wdt", 0);
|
|
if (pdev == NULL || IS_ERR(pdev))
|
|
return;
|
|
pdev->resource = &mx23_wdt_res;
|
|
pdev->num_resources = 1;
|
|
mxs_add_device(pdev, 3);
|
|
}
|
|
#else
|
|
static void __init mx23_init_wdt(void)
|
|
{
|
|
;
|
|
}
|
|
#endif
|
|
|
|
#if defined(CONFIG_RTC_DRV_MXS) || defined(CONFIG_RTC_DRV_MXS_MODULE)
|
|
static struct resource mx23_rtc_res[] = {
|
|
{
|
|
.flags = IORESOURCE_MEM,
|
|
.start = RTC_PHYS_ADDR,
|
|
.end = RTC_PHYS_ADDR + 0x2000 - 1,
|
|
},
|
|
{
|
|
.flags = IORESOURCE_IRQ,
|
|
.start = IRQ_RTC_ALARM,
|
|
.end = IRQ_RTC_ALARM,
|
|
},
|
|
{
|
|
.flags = IORESOURCE_IRQ,
|
|
.start = IRQ_RTC_1MSEC,
|
|
.end = IRQ_RTC_1MSEC,
|
|
},
|
|
};
|
|
|
|
static void __init mx23_init_rtc(void)
|
|
{
|
|
struct platform_device *pdev;
|
|
|
|
pdev = mxs_get_device("mxs-rtc", 0);
|
|
if (pdev == NULL || IS_ERR(pdev))
|
|
return;
|
|
pdev->resource = mx23_rtc_res;
|
|
pdev->num_resources = ARRAY_SIZE(mx23_rtc_res);
|
|
mxs_add_device(pdev, 3);
|
|
}
|
|
#else
|
|
static void __init mx23_init_rtc(void)
|
|
{
|
|
;
|
|
}
|
|
#endif
|
|
|
|
#ifdef CONFIG_MXS_LRADC
|
|
struct mxs_lradc_plat_data mx23_lradc_data = {
|
|
.vddio_voltage = BV_LRADC_CTRL4_LRADC6SELECT__CHANNEL6,
|
|
.battery_voltage = BV_LRADC_CTRL4_LRADC7SELECT__CHANNEL7,
|
|
};
|
|
|
|
static struct resource mx23_lradc_res[] = {
|
|
{
|
|
.flags = IORESOURCE_MEM,
|
|
.start = LRADC_PHYS_ADDR,
|
|
.end = LRADC_PHYS_ADDR + 0x2000 - 1,
|
|
},
|
|
};
|
|
|
|
static void __init mx23_init_lradc(void)
|
|
{
|
|
struct platform_device *pdev;
|
|
|
|
pdev = mxs_get_device("mxs-lradc", 0);
|
|
if (pdev == NULL || IS_ERR(pdev))
|
|
return;
|
|
pdev->resource = mx23_lradc_res;
|
|
pdev->num_resources = ARRAY_SIZE(mx23_lradc_res);
|
|
pdev->dev.platform_data = &mx23_lradc_data;
|
|
mxs_add_device(pdev, 0);
|
|
}
|
|
#else
|
|
static void __init mx23_init_lradc(void)
|
|
{
|
|
;
|
|
}
|
|
#endif
|
|
|
|
#if defined(CONFIG_KEYBOARD_MXS) || defined(CONFIG_KEYBOARD_MXS_MODULE)
|
|
static struct mxskbd_keypair keyboard_data[] = {
|
|
{ 100, KEY_F1 },
|
|
{ 306, KEY_RIGHT},
|
|
{ 626, KEY_F2},
|
|
{ 932, KEY_LEFT },
|
|
{ 1584, KEY_UP },
|
|
{ 2207, KEY_DOWN },
|
|
{ 1907, KEY_F3 },
|
|
{ 2831, KEY_SELECT },
|
|
{ -1, 0 },
|
|
};
|
|
|
|
static struct mxs_kbd_plat_data mxs_kbd_data = {
|
|
.keypair = keyboard_data,
|
|
.channel = LRADC_CH0,
|
|
};
|
|
|
|
static struct resource mx23_kbd_res[] = {
|
|
{
|
|
.flags = IORESOURCE_MEM,
|
|
.start = LRADC_PHYS_ADDR,
|
|
.end = LRADC_PHYS_ADDR + 0x2000 - 1,
|
|
},
|
|
{
|
|
.flags = IORESOURCE_IRQ,
|
|
.start = IRQ_LRADC_CH0,
|
|
.end = IRQ_LRADC_CH0,
|
|
},
|
|
};
|
|
|
|
static void __init mx23_init_kbd(void)
|
|
{
|
|
struct platform_device *pdev;
|
|
pdev = mxs_get_device("mxs-kbd", 0);
|
|
if (pdev == NULL || IS_ERR(pdev))
|
|
return;
|
|
pdev->resource = mx23_kbd_res;
|
|
pdev->num_resources = ARRAY_SIZE(mx23_kbd_res);
|
|
pdev->dev.platform_data = &mxs_kbd_data;
|
|
mxs_add_device(pdev, 3);
|
|
}
|
|
#else
|
|
static void __init mx23_init_kbd(void)
|
|
{
|
|
;
|
|
}
|
|
#endif
|
|
|
|
#if defined(CONFIG_TOUCHSCREEN_MXS) || defined(CONFIG_TOUCHSCREEN_MXS_MODULE)
|
|
static struct mxs_touchscreen_plat_data mx23_ts_data = {
|
|
.x_plus_chan = LRADC_TOUCH_X_PLUS,
|
|
.x_minus_chan = LRADC_TOUCH_X_MINUS,
|
|
.y_plus_chan = LRADC_TOUCH_Y_PLUS,
|
|
.y_minus_chan = LRADC_TOUCH_Y_MINUS,
|
|
.x_plus_val = BM_LRADC_CTRL0_XPLUS_ENABLE,
|
|
.x_minus_val = BM_LRADC_CTRL0_XMINUS_ENABLE,
|
|
.y_plus_val = BM_LRADC_CTRL0_YPLUS_ENABLE,
|
|
.y_minus_val = BM_LRADC_CTRL0_YMINUS_ENABLE,
|
|
.x_plus_mask = BM_LRADC_CTRL0_XPLUS_ENABLE,
|
|
.x_minus_mask = BM_LRADC_CTRL0_XMINUS_ENABLE,
|
|
.y_plus_mask = BM_LRADC_CTRL0_YPLUS_ENABLE,
|
|
.y_minus_mask = BM_LRADC_CTRL0_YMINUS_ENABLE,
|
|
};
|
|
|
|
static struct resource mx23_ts_res[] = {
|
|
{
|
|
.flags = IORESOURCE_MEM,
|
|
.start = LRADC_PHYS_ADDR,
|
|
.end = LRADC_PHYS_ADDR + 0x2000 - 1,
|
|
},
|
|
{
|
|
.flags = IORESOURCE_IRQ,
|
|
.start = IRQ_TOUCH_DETECT,
|
|
.end = IRQ_TOUCH_DETECT,
|
|
},
|
|
{
|
|
.flags = IORESOURCE_IRQ,
|
|
.start = IRQ_LRADC_CH5,
|
|
.end = IRQ_LRADC_CH5,
|
|
},
|
|
};
|
|
|
|
static void __init mx23_init_ts(void)
|
|
{
|
|
struct platform_device *pdev;
|
|
|
|
pdev = mxs_get_device("mxs-ts", 0);
|
|
if (pdev == NULL || IS_ERR(pdev))
|
|
return;
|
|
pdev->resource = mx23_ts_res;
|
|
pdev->num_resources = ARRAY_SIZE(mx23_ts_res);
|
|
pdev->dev.platform_data = &mx23_ts_data;
|
|
mxs_add_device(pdev, 3);
|
|
}
|
|
#else
|
|
static void __init mx23_init_ts(void)
|
|
{
|
|
;
|
|
}
|
|
#endif
|
|
|
|
#if defined(CONFIG_CRYPTO_DEV_DCP)
|
|
|
|
static struct resource dcp_resources[] = {
|
|
|
|
{
|
|
.flags = IORESOURCE_MEM,
|
|
.start = DCP_PHYS_ADDR,
|
|
.end = DCP_PHYS_ADDR + 0x2000 - 1,
|
|
}, {
|
|
.flags = IORESOURCE_IRQ,
|
|
.start = IRQ_DCP_VMI,
|
|
.end = IRQ_DCP_VMI,
|
|
}, {
|
|
.flags = IORESOURCE_IRQ,
|
|
.start = IRQ_DCP,
|
|
.end = IRQ_DCP,
|
|
},
|
|
};
|
|
|
|
static void __init mx23_init_dcp(void)
|
|
{
|
|
struct platform_device *pdev;
|
|
|
|
pdev = mxs_get_device("dcp", 0);
|
|
if (pdev == NULL || IS_ERR(pdev))
|
|
return;
|
|
pdev->resource = dcp_resources;
|
|
pdev->num_resources = ARRAY_SIZE(dcp_resources);
|
|
mxs_add_device(pdev, 3);
|
|
}
|
|
#else
|
|
static void __init mx23_init_dcp(void)
|
|
{
|
|
;
|
|
}
|
|
#endif
|
|
|
|
#if defined(CONFIG_MTD_NAND_GPMI_NFC)
|
|
|
|
static int gpmi_nfc_platform_init(unsigned int max_chip_count)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static void gpmi_nfc_platform_exit(unsigned int max_chip_count)
|
|
{
|
|
}
|
|
|
|
static const char *gpmi_nfc_partition_source_types[] = { "cmdlinepart", 0 };
|
|
|
|
static struct gpmi_nfc_platform_data gpmi_nfc_platform_data = {
|
|
.nfc_version = 0,
|
|
.boot_rom_version = 0,
|
|
.clock_name = "gpmi",
|
|
.platform_init = gpmi_nfc_platform_init,
|
|
.platform_exit = gpmi_nfc_platform_exit,
|
|
.min_prop_delay_in_ns = 5,
|
|
.max_prop_delay_in_ns = 9,
|
|
.max_chip_count = 2,
|
|
.boot_area_size_in_bytes = 20 * SZ_1M,
|
|
.partition_source_types = gpmi_nfc_partition_source_types,
|
|
.partitions = 0,
|
|
.partition_count = 0,
|
|
};
|
|
|
|
static struct resource gpmi_nfc_resources[] = {
|
|
{
|
|
.name = GPMI_NFC_GPMI_REGS_ADDR_RES_NAME,
|
|
.flags = IORESOURCE_MEM,
|
|
.start = GPMI_PHYS_ADDR,
|
|
.end = GPMI_PHYS_ADDR + SZ_8K - 1,
|
|
},
|
|
{
|
|
.name = GPMI_NFC_GPMI_INTERRUPT_RES_NAME,
|
|
.flags = IORESOURCE_IRQ,
|
|
.start = IRQ_GPMI_ATTENTION,
|
|
.end = IRQ_GPMI_ATTENTION,
|
|
},
|
|
{
|
|
.name = GPMI_NFC_BCH_REGS_ADDR_RES_NAME,
|
|
.flags = IORESOURCE_MEM,
|
|
.start = BCH_PHYS_ADDR,
|
|
.end = BCH_PHYS_ADDR + SZ_8K - 1,
|
|
},
|
|
{
|
|
.name = GPMI_NFC_BCH_INTERRUPT_RES_NAME,
|
|
.flags = IORESOURCE_IRQ,
|
|
.start = IRQ_BCH,
|
|
.end = IRQ_BCH,
|
|
},
|
|
{
|
|
.name = GPMI_NFC_DMA_CHANNELS_RES_NAME,
|
|
.flags = IORESOURCE_DMA,
|
|
.start = MXS_DMA_CHANNEL_AHB_APBH_GPMI0,
|
|
.end = MXS_DMA_CHANNEL_AHB_APBH_GPMI3,
|
|
},
|
|
{
|
|
.name = GPMI_NFC_DMA_INTERRUPT_RES_NAME,
|
|
.flags = IORESOURCE_IRQ,
|
|
.start = IRQ_GPMI_DMA,
|
|
.end = IRQ_GPMI_DMA,
|
|
},
|
|
};
|
|
|
|
static void __init mx23_init_gpmi_nfc(void)
|
|
{
|
|
struct platform_device *pdev;
|
|
|
|
pdev = mxs_get_device(GPMI_NFC_DRIVER_NAME, 0);
|
|
if (pdev == NULL || IS_ERR(pdev))
|
|
return;
|
|
pdev->dev.platform_data = &gpmi_nfc_platform_data;
|
|
pdev->resource = gpmi_nfc_resources;
|
|
pdev->num_resources = ARRAY_SIZE(gpmi_nfc_resources);
|
|
mxs_add_device(pdev, 1);
|
|
}
|
|
#else
|
|
static void mx23_init_gpmi_nfc(void)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
#if defined(CONFIG_MMC_MXS) || defined(CONFIG_MMC_MXS_MODULE)
|
|
static unsigned long mxs_mmc_setclock_mmc0(unsigned long hz)
|
|
{
|
|
struct clk *ssp = clk_get(NULL, "ssp.0");
|
|
|
|
clk_set_rate(ssp, 2 * hz);
|
|
clk_put(ssp);
|
|
|
|
return hz;
|
|
}
|
|
|
|
static struct mxs_mmc_platform_data mx23_mmc0_data = {
|
|
.hw_init = mxs_mmc_hw_init_mmc0,
|
|
.hw_release = mxs_mmc_hw_release_mmc0,
|
|
.get_wp = mxs_mmc_get_wp_mmc0,
|
|
.cmd_pullup = mxs_mmc_cmd_pullup_mmc0,
|
|
/*
|
|
Don't change ssp clock because ssp1 and ssp2 share one ssp clock source
|
|
ssp module have own divider.
|
|
.setclock = mxs_mmc_setclock_mmc0,
|
|
*/
|
|
.caps = MMC_CAP_4_BIT_DATA,
|
|
.min_clk = 400000,
|
|
.max_clk = 48000000,
|
|
.read_uA = 50000,
|
|
.write_uA = 70000,
|
|
.clock_mmc = "ssp.0",
|
|
.power_mmc = NULL,
|
|
};
|
|
|
|
static struct resource mx23_mmc0_resource[] = {
|
|
{
|
|
.flags = IORESOURCE_MEM,
|
|
.start = SSP1_PHYS_ADDR,
|
|
.end = SSP1_PHYS_ADDR + 0x2000 - 1,
|
|
},
|
|
{
|
|
.flags = IORESOURCE_DMA,
|
|
.start = MXS_DMA_CHANNEL_AHB_APBH_SSP1,
|
|
.end = MXS_DMA_CHANNEL_AHB_APBH_SSP1,
|
|
},
|
|
{
|
|
.flags = IORESOURCE_IRQ,
|
|
.start = IRQ_SSP1_DMA,
|
|
.end = IRQ_SSP1_DMA,
|
|
},
|
|
{
|
|
.flags = IORESOURCE_IRQ,
|
|
.start = IRQ_SSP_ERROR,
|
|
.end = IRQ_SSP_ERROR,
|
|
},
|
|
};
|
|
|
|
static void __init mx23_init_mmc(void)
|
|
{
|
|
struct platform_device *pdev;
|
|
|
|
pdev = mxs_get_device("mxs-mmc", 0);
|
|
if (pdev == NULL || IS_ERR(pdev))
|
|
return;
|
|
pdev->resource = mx23_mmc0_resource;
|
|
pdev->num_resources = ARRAY_SIZE(mx23_mmc0_resource);
|
|
pdev->dev.platform_data = &mx23_mmc0_data;
|
|
|
|
mxs_add_device(pdev, 2);
|
|
}
|
|
#else
|
|
static void mx23_init_mmc(void)
|
|
{
|
|
;
|
|
}
|
|
#endif
|
|
|
|
#if defined(CONFIG_SPI_MXS) || defined(CONFIG_SPI_MXS_MODULE)
|
|
static struct resource ssp1_resources[] = {
|
|
{
|
|
.start = SSP1_PHYS_ADDR,
|
|
.end = SSP1_PHYS_ADDR + 0x1FFF,
|
|
.flags = IORESOURCE_MEM,
|
|
}, {
|
|
.start = IRQ_SSP1_DMA,
|
|
.end = IRQ_SSP1_DMA,
|
|
.flags = IORESOURCE_IRQ,
|
|
}, {
|
|
.start = IRQ_SSP_ERROR,
|
|
.end = IRQ_SSP_ERROR,
|
|
.flags = IORESOURCE_IRQ,
|
|
}, {
|
|
.start = MXS_DMA_CHANNEL_AHB_APBH_SSP1,
|
|
.end = MXS_DMA_CHANNEL_AHB_APBH_SSP1,
|
|
.flags = IORESOURCE_DMA,
|
|
},
|
|
};
|
|
|
|
static void __init mx23_init_spi1(void)
|
|
{
|
|
struct platform_device *pdev;
|
|
|
|
pdev = mxs_get_device("mxs-spi", 0);
|
|
if (pdev == NULL || IS_ERR(pdev))
|
|
return;
|
|
pdev->resource = ssp1_resources;
|
|
pdev->num_resources = ARRAY_SIZE(ssp1_resources);
|
|
|
|
mxs_add_device(pdev, 3);
|
|
}
|
|
#else
|
|
static void mx23_init_spi1(void)
|
|
{
|
|
;
|
|
}
|
|
#endif
|
|
|
|
#define CMDLINE_DEVICE_CHOOSE(name, dev1, dev2) \
|
|
static char *cmdline_device_##name; \
|
|
static int cmdline_device_##name##_setup(char *dev) \
|
|
{ \
|
|
cmdline_device_##name = dev + 1; \
|
|
return 0; \
|
|
} \
|
|
__setup(#name, cmdline_device_##name##_setup); \
|
|
void mx23_init_##name(void) \
|
|
{ \
|
|
if (!cmdline_device_##name || \
|
|
!strcmp(cmdline_device_##name, #dev1)) \
|
|
mx23_init_##dev1(); \
|
|
else if (!strcmp(cmdline_device_##name, #dev2)) \
|
|
mx23_init_##dev2(); \
|
|
else \
|
|
pr_err("Unknown %s assignment '%s'.\n", \
|
|
#name, cmdline_device_##name); \
|
|
}
|
|
|
|
CMDLINE_DEVICE_CHOOSE(ssp1, mmc, spi1)
|
|
|
|
#if defined(CONFIG_BATTERY_MXS)
|
|
/* battery info data */
|
|
static ddi_bc_Cfg_t battery_data = {
|
|
.u32StateMachinePeriod = 100, /* ms */
|
|
.u16CurrentRampSlope = 75, /* mA/s */
|
|
.u16ConditioningThresholdVoltage = 2900, /* mV */
|
|
.u16ConditioningMaxVoltage = 3000, /* mV */
|
|
.u16ConditioningCurrent = 60, /* mA */
|
|
.u32ConditioningTimeout = 4*60*60*1000, /* ms (4 hours) */
|
|
.u16ChargingVoltage = 4200, /* mV */
|
|
/* FIXME: the current comparator could have h/w bugs in current
|
|
* detection through POWER_STS.CHRGSTS bit */
|
|
.u16ChargingCurrent = 600, /* mA 600 */
|
|
.u16ChargingThresholdCurrent = 60, /* mA 60 */
|
|
.u32ChargingTimeout = 4*60*60*1000,/* ms (4 hours) */
|
|
.u32TopOffPeriod = 30*60*1000, /* ms (30 minutes) */
|
|
.monitorDieTemp = 1, /* Monitor the die */
|
|
.u8DieTempHigh = 75, /* deg centigrade */
|
|
.u8DieTempLow = 65, /* deg centigrade */
|
|
.u16DieTempSafeCurrent = 0, /* mA */
|
|
.monitorBatteryTemp = 0, /* Monitor the battery*/
|
|
.u8BatteryTempChannel = 1, /* LRADC 1 */
|
|
.u16BatteryTempHigh = 642, /* Unknown units */
|
|
.u16BatteryTempLow = 497, /* Unknown units */
|
|
.u16BatteryTempSafeCurrent = 0, /* mA */
|
|
};
|
|
|
|
static struct resource battery_resource[] = {
|
|
{/* 0 */
|
|
.flags = IORESOURCE_IRQ,
|
|
.start = IRQ_VDD5V,
|
|
.end = IRQ_VDD5V,
|
|
},
|
|
{/* 1 */
|
|
.flags = IORESOURCE_IRQ,
|
|
.start = IRQ_DCDC4P2_BO,
|
|
.end = IRQ_DCDC4P2_BO,
|
|
},
|
|
{/* 2 */
|
|
.flags = IORESOURCE_IRQ,
|
|
.start = IRQ_BATT_BRNOUT,
|
|
.end = IRQ_BATT_BRNOUT,
|
|
},
|
|
{/* 3 */
|
|
.flags = IORESOURCE_IRQ,
|
|
.start = IRQ_VDDD_BRNOUT,
|
|
.end = IRQ_VDDD_BRNOUT,
|
|
},
|
|
{/* 4 */
|
|
.flags = IORESOURCE_IRQ,
|
|
.start = IRQ_VDD18_BRNOUT,
|
|
.end = IRQ_VDD18_BRNOUT,
|
|
},
|
|
{/* 5 */
|
|
.flags = IORESOURCE_IRQ,
|
|
.start = IRQ_VDDIO_BRNOUT,
|
|
.end = IRQ_VDDIO_BRNOUT,
|
|
},
|
|
{/* 6 */
|
|
.flags = IORESOURCE_IRQ,
|
|
.start = IRQ_VDD5V_DROOP,
|
|
.end = IRQ_VDD5V_DROOP,
|
|
},
|
|
};
|
|
|
|
static void mx23_init_battery(void)
|
|
{
|
|
struct platform_device *pdev;
|
|
pdev = mxs_get_device("mxs-battery", 0);
|
|
if (pdev == NULL || IS_ERR(pdev))
|
|
return;
|
|
pdev->resource = battery_resource,
|
|
pdev->num_resources = ARRAY_SIZE(battery_resource),
|
|
pdev->dev.platform_data = &battery_data;
|
|
mxs_add_device(pdev, 3);
|
|
|
|
}
|
|
#else
|
|
static void mx23_init_battery(void)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
#if defined(CONFIG_SND_SOC_MXS_SPDIF) || \
|
|
defined(CONFIG_SND_SOC_MXS_SPDIF_MODULE)
|
|
void __init mx23_init_spdif(void)
|
|
{ struct platform_device *pdev;
|
|
pdev = mxs_get_device("mxs-spdif", 0);
|
|
if (pdev == NULL || IS_ERR(pdev))
|
|
return;
|
|
mxs_add_device(pdev, 3);
|
|
}
|
|
#else
|
|
static inline void mx23_init_spdif(void)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
#if defined(CONFIG_MXS_PERSISTENT)
|
|
static const struct mxs_persistent_bit_config
|
|
mx23_persistent_bit_config[] = {
|
|
{ .reg = 0, .start = 0, .width = 1,
|
|
.name = "CLOCKSOURCE" },
|
|
{ .reg = 0, .start = 1, .width = 1,
|
|
.name = "ALARM_WAKE_EN" },
|
|
{ .reg = 0, .start = 2, .width = 1,
|
|
.name = "ALARM_EN" },
|
|
{ .reg = 0, .start = 3, .width = 1,
|
|
.name = "CLK_SECS" },
|
|
{ .reg = 0, .start = 4, .width = 1,
|
|
.name = "XTAL24MHZ_PWRUP" },
|
|
{ .reg = 0, .start = 5, .width = 1,
|
|
.name = "XTAL32MHZ_PWRUP" },
|
|
{ .reg = 0, .start = 6, .width = 1,
|
|
.name = "XTAL32_FREQ" },
|
|
{ .reg = 0, .start = 7, .width = 1,
|
|
.name = "ALARM_WAKE" },
|
|
{ .reg = 0, .start = 8, .width = 5,
|
|
.name = "MSEC_RES" },
|
|
{ .reg = 0, .start = 13, .width = 1,
|
|
.name = "DISABLE_XTALOK" },
|
|
{ .reg = 0, .start = 14, .width = 2,
|
|
.name = "LOWERBIAS" },
|
|
{ .reg = 0, .start = 16, .width = 1,
|
|
.name = "DISABLE_PSWITCH" },
|
|
{ .reg = 0, .start = 17, .width = 1,
|
|
.name = "AUTO_RESTART" },
|
|
{ .reg = 0, .start = 18, .width = 14,
|
|
.name = "SPARE_ANALOG" },
|
|
|
|
{ .reg = 1, .start = 0, .width = 1,
|
|
.name = "FORCE_RECOVERY" },
|
|
{ .reg = 1, .start = 1, .width = 1,
|
|
.name = "NAND_SECONDARY_BOOT" },
|
|
{ .reg = 1, .start = 2, .width = 1,
|
|
.name = "NAND_SDK_BLOCK_REWRITE" },
|
|
{ .reg = 1, .start = 3, .width = 1,
|
|
.name = "SD_SPEED_ENABLE" },
|
|
{ .reg = 1, .start = 4, .width = 1,
|
|
.name = "SD_INIT_SEQ_1_DISABLE" },
|
|
{ .reg = 1, .start = 5, .width = 1,
|
|
.name = "SD_CMD0_DISABLE" },
|
|
{ .reg = 1, .start = 6, .width = 1,
|
|
.name = "SD_INIT_SEQ_2_ENABLE" },
|
|
{ .reg = 1, .start = 7, .width = 1,
|
|
.name = "OTG_ATL_ROLE_BIT" },
|
|
{ .reg = 1, .start = 8, .width = 1,
|
|
.name = "OTG_HNP_BIT" },
|
|
{ .reg = 1, .start = 9, .width = 1,
|
|
.name = "USB_LOW_POWER_MODE" },
|
|
{ .reg = 1, .start = 10, .width = 1,
|
|
.name = "SKIP_CHECKDISK" },
|
|
{ .reg = 1, .start = 11, .width = 1,
|
|
.name = "USB_BOOT_PLAYER_MODE" },
|
|
{ .reg = 1, .start = 12, .width = 1,
|
|
.name = "ENUMERATE_500MA_TWICE" },
|
|
{ .reg = 1, .start = 13, .width = 19,
|
|
.name = "SPARE_GENERAL" },
|
|
|
|
{ .reg = 2, .start = 0, .width = 32,
|
|
.name = "SPARE_2" },
|
|
{ .reg = 3, .start = 0, .width = 32,
|
|
.name = "SPARE_3" },
|
|
{ .reg = 4, .start = 0, .width = 32,
|
|
.name = "SPARE_4" },
|
|
{ .reg = 5, .start = 0, .width = 32,
|
|
.name = "SPARE_5" },
|
|
};
|
|
|
|
static struct mxs_platform_persistent_data mx23_persistent_data = {
|
|
.bit_config_tab = mx23_persistent_bit_config,
|
|
.bit_config_cnt = ARRAY_SIZE(mx23_persistent_bit_config),
|
|
};
|
|
|
|
static struct resource mx23_persistent_res[] = {
|
|
{
|
|
.flags = IORESOURCE_MEM,
|
|
.start = RTC_PHYS_ADDR,
|
|
.end = RTC_PHYS_ADDR + 0x2000 - 1,
|
|
},
|
|
};
|
|
|
|
static void mx23_init_persistent(void)
|
|
{
|
|
struct platform_device *pdev;
|
|
pdev = mxs_get_device("mxs-persistent", 0);
|
|
if (pdev == NULL || IS_ERR(pdev))
|
|
return;
|
|
pdev->dev.platform_data = &mx23_persistent_data;
|
|
pdev->resource = mx23_persistent_res,
|
|
pdev->num_resources = ARRAY_SIZE(mx23_persistent_res),
|
|
mxs_add_device(pdev, 3);
|
|
}
|
|
#else
|
|
static void mx23_init_persistent()
|
|
{
|
|
}
|
|
#endif
|
|
|
|
int __init mx23_device_init(void)
|
|
{
|
|
mx23_init_dma();
|
|
mx23_init_viim();
|
|
mx23_init_duart();
|
|
mx23_init_auart();
|
|
mx23_init_lradc();
|
|
mx23_init_i2c();
|
|
mx23_init_kbd();
|
|
mx23_init_wdt();
|
|
mx23_init_ts();
|
|
mx23_init_rtc();
|
|
mx23_init_dcp();
|
|
mx23_init_ssp1();
|
|
mx23_init_gpmi_nfc();
|
|
mx23_init_spdif();
|
|
mx23_init_lcdif();
|
|
mx23_init_pxp();
|
|
mx23_init_battery();
|
|
mx23_init_persistent();
|
|
|
|
return 0;
|
|
}
|
|
|
|
static struct __initdata map_desc mx23_io_desc[] = {
|
|
{
|
|
.virtual = MX23_SOC_IO_VIRT_BASE,
|
|
.pfn = __phys_to_pfn(MX23_SOC_IO_PHYS_BASE),
|
|
.length = MX23_SOC_IO_AREA_SIZE,
|
|
.type = MT_DEVICE,
|
|
},
|
|
{
|
|
.virtual = MX23_OCRAM_BASE,
|
|
.pfn = __phys_to_pfn(MX23_OCRAM_PHBASE),
|
|
.length = MX23_OCRAM_SIZE,
|
|
.type = MT_DEVICE,
|
|
},
|
|
};
|
|
|
|
void __init mx23_map_io(void)
|
|
{
|
|
iotable_init(mx23_io_desc, ARRAY_SIZE(mx23_io_desc));
|
|
}
|
|
|
|
void __init mx23_irq_init(void)
|
|
{
|
|
avic_init_irq(IO_ADDRESS(ICOLL_PHYS_ADDR), ARCH_NR_IRQS);
|
|
}
|
|
|
|
static void mx23_timer_init(void)
|
|
{
|
|
int i, reg;
|
|
mx23_clock_init();
|
|
|
|
mx23_timer.clk = clk_get(NULL, "clk_32k");
|
|
if (mx23_timer.clk == NULL || IS_ERR(mx23_timer.clk))
|
|
return;
|
|
__raw_writel(BM_TIMROT_ROTCTRL_SFTRST,
|
|
mx23_timer.base + HW_TIMROT_ROTCTRL_CLR);
|
|
for (i = 0; i < 10000; i++) {
|
|
reg = __raw_readl(mx23_timer.base + HW_TIMROT_ROTCTRL);
|
|
if (!(reg & BM_TIMROT_ROTCTRL_SFTRST))
|
|
break;
|
|
udelay(2);
|
|
}
|
|
if (i >= 10000)
|
|
return;
|
|
__raw_writel(BM_TIMROT_ROTCTRL_CLKGATE,
|
|
mx23_timer.base + HW_TIMROT_ROTCTRL_CLR);
|
|
|
|
reg = __raw_readl(mx23_timer.base + HW_TIMROT_ROTCTRL);
|
|
|
|
mxs_nomatch_timer_init(&mx23_timer);
|
|
}
|
|
|
|
struct mxs_sys_timer mx23_timer = {
|
|
.timer = {
|
|
.init = mx23_timer_init,
|
|
},
|
|
.clk_sel = BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL,
|
|
.base = IO_ADDRESS(TIMROT_PHYS_ADDR),
|
|
};
|