DA850/OMAP-L138 EVM has a RMII Ethernet PHY on the UI daughter card. The PHY
is enabled by proper programming of the IO Expander (TCA6416) ports. Also for
RMII PHY to work, the MDIO clock of MII PHY has to be disabled since both the
PHYs have the same address. This is done via the GPIO2[6] pin. This patch adds
support for RMII PHY.

This patch also adds a menuconfig option to select UI card and peripherals
present on it. Currently, the only sub-option in this menu is RMII.
This menuconfig option is similar to the one present for UI card on
DA830/OMAP-L137 EVM.

Signed-off-by: Chaithrika U S <chaithr...@ti.com>
---
 arch/arm/mach-davinci/Kconfig              |   26 +++++
 arch/arm/mach-davinci/board-da850-evm.c    |  141 +++++++++++++++++++++++++++-
 arch/arm/mach-davinci/da850.c              |   17 ++++
 arch/arm/mach-davinci/include/mach/da8xx.h |    1 +
 arch/arm/mach-davinci/include/mach/mux.h   |    9 ++
 5 files changed, 189 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
index 7b6dddf..4ee61cc 100644
--- a/arch/arm/mach-davinci/Kconfig
+++ b/arch/arm/mach-davinci/Kconfig
@@ -129,6 +129,32 @@ config MACH_DAVINCI_DA850_EVM
        help
          Say Y here to select the TI DA850/OMAP-L138 Evaluation Module.
 
+config DA850_UI
+       bool "DA850/OMAP-L138 UI (User Interface) board support"
+       depends on MACH_DAVINCI_DA850_EVM
+       help
+         Say Y here if you have the DA850/OMAP-L138 UI
+         (User Interface) board installed and you want to
+         enable the peripherals located on User Interface
+         board.
+
+choice
+       prompt "Select DA850/OMAP-L138 UI board peripheral"
+       depends on DA850_UI
+
+config DA850_UI_RMII
+       bool "RMII Ethernet PHY"
+       help
+         Say Y if you want to use the RMII PHY on the DA850/OMAP-L138 EVM.
+         This PHY is found on the UI daughter card that is supplied with
+         the EVM.
+         NOTE: Please take care while choosing this option, MII PHY will
+         not be functional if RMII mode is selected. This also affects
+         the operation of video devices as they are pin multiplexed with
+         RMII pins.
+
+endchoice
+
 config DAVINCI_MUX
        bool "DAVINCI multiplexing support"
        depends on ARCH_DAVINCI
diff --git a/arch/arm/mach-davinci/board-da850-evm.c 
b/arch/arm/mach-davinci/board-da850-evm.c
index 25ae007..43cc629 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -17,6 +17,7 @@
 #include <linux/console.h>
 #include <linux/i2c.h>
 #include <linux/i2c/at24.h>
+#include <linux/i2c/pca953x.h>
 #include <linux/gpio.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
@@ -43,6 +44,8 @@
 #define DA850_MMCSD_CD_PIN             GPIO_TO_PIN(4, 0)
 #define DA850_MMCSD_WP_PIN             GPIO_TO_PIN(4, 1)
 
+#define DA850_MII_MDIO_CLKEN_PIN       GPIO_TO_PIN(2, 6)
+
 static struct mtd_partition da850_evm_norflash_partition[] = {
        {
                .name           = "NOR filesystem",
@@ -270,11 +273,141 @@ static const short da850_evm_lcdc_pins[] = {
        -1
 };
 
+#ifdef CONFIG_DA850_UI
+static int da850_evm_ui_expander_setup(struct i2c_client *client, unsigned 
gpio,
+                                               unsigned ngpio, void *c)
+{
+       struct davinci_soc_info *soc_info = &davinci_soc_info;
+       int sel_a, sel_b, sel_c, ret;
+
+       sel_a = gpio + 7;
+       sel_b = gpio + 6;
+       sel_c = gpio + 5;
+
+       ret = gpio_request(sel_a, "sel_a");
+       if (ret) {
+               pr_warning("Cannot open UI expander pin %d\n", sel_a);
+               goto exp_setup_sela_fail;
+       }
+
+       ret = gpio_request(sel_b, "sel_b");
+       if (ret) {
+               pr_warning("Cannot open UI expander pin %d\n", sel_b);
+               goto exp_setup_selb_fail;
+       }
+
+       ret = gpio_request(sel_c, "sel_c");
+       if (ret) {
+               pr_warning("Cannot open UI expander pin %d\n", sel_c);
+               goto exp_setup_selc_fail;
+       }
+
+       /* deselect all fucntionalities */
+       gpio_direction_output(sel_a, 1);
+       gpio_direction_output(sel_b, 1);
+       gpio_direction_output(sel_c, 1);
+
+       if (soc_info->emac_pdata->rmii_en)
+               /* enable RMII */
+               gpio_direction_output(sel_a, 0);
+
+       return 0;
+
+exp_setup_selc_fail:
+       gpio_free(sel_b);
+exp_setup_selb_fail:
+       gpio_free(sel_a);
+exp_setup_sela_fail:
+       return ret;
+}
+
+static int da850_evm_ui_expander_teardown(struct i2c_client *client,
+                                       unsigned gpio, unsigned ngpio, void *c)
+{
+       /* deselect all fucntionalities */
+       gpio_direction_output(gpio + 5, 1);
+       gpio_direction_output(gpio + 6, 1);
+       gpio_direction_output(gpio + 7, 1);
+
+       gpio_free(gpio + 5);
+       gpio_free(gpio + 6);
+       gpio_free(gpio + 7);
+
+       return 0;
+}
+
+static struct pca953x_platform_data da850_evm_ui_expander_info = {
+       .gpio_base      = DAVINCI_N_GPIO,
+       .setup          = da850_evm_ui_expander_setup,
+       .teardown       = da850_evm_ui_expander_teardown,
+};
+#endif
+
+static struct i2c_board_info __initdata i2c_info[] =  {
+#ifdef CONFIG_DA850_UI
+       {
+               I2C_BOARD_INFO("tca6416", 0x20),
+               .platform_data = &da850_evm_ui_expander_info,
+       },
+#endif
+};
+
+static int __init da850_evm_config_emac(u8 rmii_en)
+{
+       void __iomem *cfg_chip3_base;
+       int ret;
+       u32 val;
+
+       cfg_chip3_base = DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP3_REG);
+
+       /* configure the CFGCHIP3 register for RMII or MII */
+       val = __raw_readl(cfg_chip3_base);
+       if (rmii_en)
+               val |= BIT(8);
+       else
+               val &= ~BIT(8);
+
+       __raw_writel(val, cfg_chip3_base);
+
+       if (!rmii_en)
+               ret = da8xx_pinmux_setup(da850_cpgmac_pins);
+       else
+               ret = da8xx_pinmux_setup(da850_rmii_pins);
+       if (ret)
+               pr_warning("da850_evm_init: cpgmac/rmii mux setup failed: %d\n",
+                               ret);
+
+       if (rmii_en) {
+               /* Disable MII MDIO clock */
+               ret = davinci_cfg_reg(DA850_GPIO2_6);
+               if (ret)
+                       pr_warning("da850_evm_init:GPIO(2,6) mux setup "
+                                                       "failed\n");
+
+               ret = gpio_request(DA850_MII_MDIO_CLKEN_PIN, "mdio_clk_en");
+               if (ret) {
+                       pr_warning("Cannot open GPIO %d\n",
+                                               DA850_MII_MDIO_CLKEN_PIN);
+                       return ret;
+               }
+
+               gpio_direction_output(DA850_MII_MDIO_CLKEN_PIN, 1);
+       }
+
+       return 0;
+}
+
 static __init void da850_evm_init(void)
 {
        struct davinci_soc_info *soc_info = &davinci_soc_info;
        int ret;
 
+#ifdef CONFIG_DA850_UI_RMII
+       soc_info->emac_pdata->rmii_en = 1;
+#else
+       soc_info->emac_pdata->rmii_en = 0;
+#endif
+
        ret = da8xx_pinmux_setup(da850_nand_pins);
        if (ret)
                pr_warning("da850_evm_init: nand mux setup failed: %d\n",
@@ -295,6 +428,7 @@ static __init void da850_evm_init(void)
                pr_warning("da850_evm_init: edma registration failed: %d\n",
                                ret);
 
+       i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
        ret = da8xx_pinmux_setup(da850_i2c0_pins);
        if (ret)
                pr_warning("da850_evm_init: i2c0 mux setup failed: %d\n",
@@ -307,12 +441,9 @@ static __init void da850_evm_init(void)
 
        soc_info->emac_pdata->phy_mask = DA850_EVM_PHY_MASK;
        soc_info->emac_pdata->mdio_max_freq = DA850_EVM_MDIO_FREQUENCY;
-       soc_info->emac_pdata->rmii_en = 0;
-
-       ret = da8xx_pinmux_setup(da850_cpgmac_pins);
+       ret = da850_evm_config_emac(soc_info->emac_pdata->rmii_en);
        if (ret)
-               pr_warning("da850_evm_init: cpgmac mux setup failed: %d\n",
-                               ret);
+               pr_warning("da850_evm_init: emac setup failed: %d\n", ret);
 
        ret = da8xx_register_emac();
        if (ret)
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index a62863c..da20b4f 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -411,6 +411,14 @@ static const struct mux_config da850_pins[] = {
        MUX_CFG(DA850, MII_RXD_0,       3,      28,     15,     8,      false)
        MUX_CFG(DA850, MDIO_CLK,        4,      0,      15,     8,      false)
        MUX_CFG(DA850, MDIO_D,          4,      4,      15,     8,      false)
+       MUX_CFG(DA850, RMII_TXD_0,      14,     12,     15,     8,      false)
+       MUX_CFG(DA850, RMII_TXD_1,      14,     8,      15,     8,      false)
+       MUX_CFG(DA850, RMII_TXEN,       14,     16,     15,     8,      false)
+       MUX_CFG(DA850, RMII_CRS_DV,     15,     4,      15,     8,      false)
+       MUX_CFG(DA850, RMII_RXD_0,      14,     24,     15,     8,      false)
+       MUX_CFG(DA850, RMII_RXD_1,      14,     20,     15,     8,      false)
+       MUX_CFG(DA850, RMII_RXER,       14,     28,     15,     8,      false)
+       MUX_CFG(DA850, RMII_MHZ_50_CLK, 15,     0,      15,     0,      false)
        /* McASP function */
        MUX_CFG(DA850,  ACLKR,          0,      0,      15,     1,      false)
        MUX_CFG(DA850,  ACLKX,          0,      4,      15,     1,      false)
@@ -513,6 +521,7 @@ static const struct mux_config da850_pins[] = {
        MUX_CFG(DA850, EMA_WAIT_1,      6,      24,     15,     1,      false)
        MUX_CFG(DA850, NEMA_CS_2,       7,      0,      15,     1,      false)
        /* GPIO function */
+       MUX_CFG(DA850, GPIO2_6,         6,      4,      15,     8,      false)
        MUX_CFG(DA850, GPIO2_8,         5,      28,     15,     8,      false)
        MUX_CFG(DA850, GPIO2_15,        5,      0,      15,     8,      false)
        MUX_CFG(DA850, GPIO4_0,         10,     28,     15,     8,      false)
@@ -554,6 +563,14 @@ const short da850_cpgmac_pins[] __initdata = {
        -1
 };
 
+const short da850_rmii_pins[] __initdata = {
+       DA850_RMII_TXD_0, DA850_RMII_TXD_1, DA850_RMII_TXEN,
+       DA850_RMII_CRS_DV, DA850_RMII_RXD_0, DA850_RMII_RXD_1,
+       DA850_RMII_RXER, DA850_RMII_MHZ_50_CLK, DA850_MDIO_CLK,
+       DA850_MDIO_D,
+       -1
+};
+
 const short da850_mcasp_pins[] __initdata = {
        DA850_AHCLKX, DA850_ACLKX, DA850_AFSX,
        DA850_AHCLKR, DA850_ACLKR, DA850_AFSR, DA850_AMUTE,
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h 
b/arch/arm/mach-davinci/include/mach/da8xx.h
index a152261..d79b814 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -119,6 +119,7 @@ extern const short da850_uart2_pins[];
 extern const short da850_i2c0_pins[];
 extern const short da850_i2c1_pins[];
 extern const short da850_cpgmac_pins[];
+extern const short da850_rmii_pins[];
 extern const short da850_mcasp_pins[];
 extern const short da850_lcdcntl_pins[];
 extern const short da850_mmcsd0_pins[];
diff --git a/arch/arm/mach-davinci/include/mach/mux.h 
b/arch/arm/mach-davinci/include/mach/mux.h
index fc8eb16..4854065 100644
--- a/arch/arm/mach-davinci/include/mach/mux.h
+++ b/arch/arm/mach-davinci/include/mach/mux.h
@@ -765,6 +765,14 @@ enum davinci_da850_index {
        DA850_MII_RXD_0,
        DA850_MDIO_CLK,
        DA850_MDIO_D,
+       DA850_RMII_TXD_0,
+       DA850_RMII_TXD_1,
+       DA850_RMII_TXEN,
+       DA850_RMII_CRS_DV,
+       DA850_RMII_RXD_0,
+       DA850_RMII_RXD_1,
+       DA850_RMII_RXER,
+       DA850_RMII_MHZ_50_CLK,
 
        /* McASP function */
        DA850_ACLKR,
@@ -872,6 +880,7 @@ enum davinci_da850_index {
        DA850_NEMA_CS_2,
 
        /* GPIO function */
+       DA850_GPIO2_6,
        DA850_GPIO2_8,
        DA850_GPIO2_15,
        DA850_GPIO4_0,
-- 
1.5.6

_______________________________________________
Davinci-linux-open-source mailing list
Davinci-linux-open-source@linux.davincidsp.com
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to