#include <linux/list.h>
 
 #include <plat/clkdev_omap.h>
+#include <plat/control.h>
 
 #include "clock.h"
 #include "clock2xxx.h"
        .clkdm_name     = "wkup_clkdm",
 };
 
+/* Optional external clock input for McBSP CLKS */
+static struct clk mcbsp_clks = {
+       .name           = "mcbsp_clks",
+       .ops            = &clkops_null,
+};
+
 /*
  * Analog domain root source clocks
  */
        .recalc         = &followparent_recalc,
 };
 
+static const struct clksel_rate common_mcbsp_96m_rates[] = {
+       { .div = 1, .val = 0, .flags = RATE_IN_24XX },
+       { .div = 0 }
+};
+
+static const struct clksel_rate common_mcbsp_mcbsp_rates[] = {
+       { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+       { .div = 0 }
+};
+
+static const struct clksel mcbsp_fck_clksel[] = {
+       { .parent = &func_96m_ck,  .rates = common_mcbsp_96m_rates },
+       { .parent = &mcbsp_clks,   .rates = common_mcbsp_mcbsp_rates },
+       { .parent = NULL }
+};
+
 static struct clk mcbsp1_fck = {
        .name           = "mcbsp1_fck",
        .ops            = &clkops_omap2_dflt_wait,
        .parent         = &func_96m_ck,
+       .init           = &omap2_init_clksel_parent,
        .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP24XX_EN_MCBSP1_SHIFT,
-       .recalc         = &followparent_recalc,
+       .clksel_reg     = OMAP242X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
+       .clksel_mask    = OMAP2_MCBSP1_CLKS_MASK,
+       .clksel         = mcbsp_fck_clksel,
+       .recalc         = &omap2_clksel_recalc,
 };
 
 static struct clk mcbsp2_ick = {
        .name           = "mcbsp2_fck",
        .ops            = &clkops_omap2_dflt_wait,
        .parent         = &func_96m_ck,
+       .init           = &omap2_init_clksel_parent,
        .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP24XX_EN_MCBSP2_SHIFT,
-       .recalc         = &followparent_recalc,
+       .clksel_reg     = OMAP242X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
+       .clksel_mask    = OMAP2_MCBSP2_CLKS_MASK,
+       .clksel         = mcbsp_fck_clksel,
+       .recalc         = &omap2_clksel_recalc,
 };
 
 static struct clk mcspi1_ick = {
        CLK(NULL,       "osc_ck",       &osc_ck,        CK_242X),
        CLK(NULL,       "sys_ck",       &sys_ck,        CK_242X),
        CLK(NULL,       "alt_ck",       &alt_ck,        CK_242X),
+       CLK("omap-mcbsp.1",     "pad_fck",      &mcbsp_clks,    CK_242X),
+       CLK("omap-mcbsp.2",     "pad_fck",      &mcbsp_clks,    CK_242X),
+       CLK(NULL,       "mcbsp_clks",   &mcbsp_clks,    CK_242X),
        /* internal analog sources */
        CLK(NULL,       "dpll_ck",      &dpll_ck,       CK_242X),
        CLK(NULL,       "apll96_ck",    &apll96_ck,     CK_242X),
        /* internal prcm root sources */
        CLK(NULL,       "func_54m_ck",  &func_54m_ck,   CK_242X),
        CLK(NULL,       "core_ck",      &core_ck,       CK_242X),
+       CLK("omap-mcbsp.1",     "prcm_fck",     &func_96m_ck,   CK_242X),
+       CLK("omap-mcbsp.2",     "prcm_fck",     &func_96m_ck,   CK_242X),
        CLK(NULL,       "func_96m_ck",  &func_96m_ck,   CK_242X),
        CLK(NULL,       "func_48m_ck",  &func_48m_ck,   CK_242X),
        CLK(NULL,       "func_12m_ck",  &func_12m_ck,   CK_242X),