ARM: mxs/mx28evk: add flexcan devices
authorShawn Guo <shawn.guo@freescale.com>
Thu, 3 Mar 2011 14:13:38 +0000 (22:13 +0800)
committerSascha Hauer <s.hauer@pengutronix.de>
Tue, 8 Mar 2011 12:24:11 +0000 (13:24 +0100)
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
arch/arm/mach-mxs/Kconfig
arch/arm/mach-mxs/mach-mx28evk.c

index 989c08c6dd93527c3d155d268caf92eaf62a488d..5ea676af8608e3fe36f8c02ff661cf54d76dfde7 100644 (file)
@@ -34,6 +34,7 @@ config MACH_MX28EVK
        select MXS_HAVE_AMBA_DUART
        select MXS_HAVE_PLATFORM_AUART
        select MXS_HAVE_PLATFORM_FEC
+       select MXS_HAVE_PLATFORM_FLEXCAN
        select MXS_OCOTP
        default y
        help
index 987e3d54280c207c6b59c47e84e7569a96c578c9..8bb221754e4e10738440c2f8e9300b069ac56c2a 100644 (file)
@@ -28,6 +28,7 @@
 #include "devices-mx28.h"
 #include "gpio.h"
 
+#define MX28EVK_FLEXCAN_SWITCH MXS_GPIO_NR(2, 13)
 #define MX28EVK_FEC_PHY_POWER  MXS_GPIO_NR(2, 15)
 #define MX28EVK_FEC_PHY_RESET  MXS_GPIO_NR(4, 13)
 
@@ -69,6 +70,15 @@ static const iomux_cfg_t mx28evk_pads[] __initconst = {
        MX28_PAD_SSP1_DATA3__GPIO_2_15 | MXS_PAD_CTRL,
        /* phy reset line */
        MX28_PAD_ENET0_RX_CLK__GPIO_4_13 | MXS_PAD_CTRL,
+
+       /* flexcan0 */
+       MX28_PAD_GPMI_RDY2__CAN0_TX,
+       MX28_PAD_GPMI_RDY3__CAN0_RX,
+       /* flexcan1 */
+       MX28_PAD_GPMI_CE2N__CAN1_TX,
+       MX28_PAD_GPMI_CE3N__CAN1_RX,
+       /* transceiver power control */
+       MX28_PAD_SSP1_CMD__GPIO_2_13,
 };
 
 /* fec */
@@ -152,8 +162,44 @@ error:
        return -ETIMEDOUT;
 }
 
+/*
+ * MX28EVK_FLEXCAN_SWITCH is shared between both flexcan controllers
+ */
+static int flexcan0_en, flexcan1_en;
+
+static void mx28evk_flexcan_switch(void)
+{
+       if (flexcan0_en || flexcan1_en)
+               gpio_set_value(MX28EVK_FLEXCAN_SWITCH, 1);
+       else
+               gpio_set_value(MX28EVK_FLEXCAN_SWITCH, 0);
+}
+
+static void mx28evk_flexcan0_switch(int enable)
+{
+       flexcan0_en = enable;
+       mx28evk_flexcan_switch();
+}
+
+static void mx28evk_flexcan1_switch(int enable)
+{
+       flexcan1_en = enable;
+       mx28evk_flexcan_switch();
+}
+
+static const struct flexcan_platform_data
+               mx28evk_flexcan_pdata[] __initconst = {
+       {
+               .transceiver_switch = mx28evk_flexcan0_switch,
+       }, {
+               .transceiver_switch = mx28evk_flexcan1_switch,
+       }
+};
+
 static void __init mx28evk_init(void)
 {
+       int ret;
+
        mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
 
        mx28_add_duart();
@@ -166,6 +212,15 @@ static void __init mx28evk_init(void)
        mx28evk_fec_reset();
        mx28_add_fec(0, &mx28_fec_pdata[0]);
        mx28_add_fec(1, &mx28_fec_pdata[1]);
+
+       ret = gpio_request_one(MX28EVK_FLEXCAN_SWITCH, GPIOF_DIR_OUT,
+                               "flexcan-switch");
+       if (ret) {
+               pr_err("failed to request gpio flexcan-switch: %d\n", ret);
+       } else {
+               mx28_add_flexcan(0, &mx28evk_flexcan_pdata[0]);
+               mx28_add_flexcan(1, &mx28evk_flexcan_pdata[1]);
+       }
 }
 
 static void __init mx28evk_timer_init(void)