From mboxrd@z Thu Jan 1 00:00:00 1970 From: mturquette@ti.com (Mike Turquette) Date: Mon, 29 Oct 2012 10:30:08 -0700 Subject: [PATCH] CLK: clk-twl6040: Initial clock driver for OMAP4+ McPDM fclk clock In-Reply-To: <1347633027-20731-1-git-send-email-peter.ujfalusi@ti.com> References: <1347633027-20731-1-git-send-email-peter.ujfalusi@ti.com> Message-ID: <20121029173008.18780.35000@nucleus> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Quoting Peter Ujfalusi (2012-09-14 07:30:27) > On OMAP4+ platforms the functional clock for the McPDM IP is suplied by > the twl6040 codec (bit clock on the PDM bus). > This common clock driver for twl6040 will register the mcpdm_fclk clock to > be used by the McPDM driver to make sure that the needed clocks are > available when needed. > > Signed-off-by: Peter Ujfalusi > --- > > Hello Mike, > > This driver is going to be used by the OMAP McPDM driver when we moved to common > clock framework. > To avoid merge conflicts I'm going to send the patch needed for the twl6040 MFD > core driver to register the platform device for the clk driver. > Peter, The patch looks good to me. To be clear, you wan this to go through clk-next or the mfd tree for avoiding conflicts? Thanks, Mike > Some background: OMAP McPDM's functional clock is coming from external source, > which is the bitclock of the McPDM interface generated by external codec > (twl6040). This clock is needed to access McPDM registers as well and when I'm > going to implement the power states of twl6040 we need to make sure that the > clock is running from twl6040 to McPDM in order to avoid surprises. > > Regards, > Peter > > drivers/clk/Kconfig | 8 +++ > drivers/clk/Makefile | 1 + > drivers/clk/clk-twl6040.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 135 insertions(+) > create mode 100644 drivers/clk/clk-twl6040.c > > diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig > index bace9e9..3d0b784 100644 > --- a/drivers/clk/Kconfig > +++ b/drivers/clk/Kconfig > @@ -53,4 +53,12 @@ config COMMON_CLK_MAX77686 > ---help--- > This driver supports Maxim 77686 crystal oscillator clock. > > +config CLK_TWL6040 > + tristate "External McPDM functional clock from twl6040" > + depends on TWL6040_CORE > + ---help--- > + Enable the external functional clock support on OMAP4+ platforms for > + McPDM. McPDM module is using the external bit clock on the McPDM bus > + as functional clock. > + > endmenu > diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile > index 6327536..c55d840 100644 > --- a/drivers/clk/Makefile > +++ b/drivers/clk/Makefile > @@ -20,3 +20,4 @@ obj-$(CONFIG_ARCH_U8500) += ux500/ > # Chip specific > obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o > obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o > +obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o > diff --git a/drivers/clk/clk-twl6040.c b/drivers/clk/clk-twl6040.c > new file mode 100644 > index 0000000..f4a3389 > --- /dev/null > +++ b/drivers/clk/clk-twl6040.c > @@ -0,0 +1,126 @@ > +/* > +* TWL6040 clock module driver for OMAP4 McPDM functional clock > +* > +* Copyright (C) 2012 Texas Instruments Inc. > +* Peter Ujfalusi > +* > +* This program is free software; you can redistribute it and/or > +* modify it under the terms of the GNU General Public License > +* version 2 as published by the Free Software Foundation. > +* > +* 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 St, Fifth Floor, Boston, MA > +* 02110-1301 USA > +* > +*/ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +struct twl6040_clk { > + struct twl6040 *twl6040; > + struct device *dev; > + struct clk_hw mcpdm_fclk; > + struct clk *clk; > + int enabled; > +}; > + > +static int twl6040_bitclk_is_enabled(struct clk_hw *hw) > +{ > + struct twl6040_clk *twl6040_clk = container_of(hw, struct twl6040_clk, > + mcpdm_fclk); > + return twl6040_clk->enabled; > +} > + > +static int twl6040_bitclk_prepare(struct clk_hw *hw) > +{ > + struct twl6040_clk *twl6040_clk = container_of(hw, struct twl6040_clk, > + mcpdm_fclk); > + int ret; > + > + ret = twl6040_power(twl6040_clk->twl6040, 1); > + if (!ret) > + twl6040_clk->enabled = 1; > + > + return ret; > +} > + > +static void twl6040_bitclk_unprepare(struct clk_hw *hw) > +{ > + struct twl6040_clk *twl6040_clk = container_of(hw, struct twl6040_clk, > + mcpdm_fclk); > + int ret; > + > + ret = twl6040_power(twl6040_clk->twl6040, 0); > + if (!ret) > + twl6040_clk->enabled = 0; > +} > + > +static const struct clk_ops twl6040_mcpdm_ops = { > + .is_enabled = twl6040_bitclk_is_enabled, > + .prepare = twl6040_bitclk_prepare, > + .unprepare = twl6040_bitclk_unprepare, > +}; > + > +static struct clk_init_data wm831x_clkout_init = { > + .name = "mcpdm_fclk", > + .ops = &twl6040_mcpdm_ops, > + .flags = CLK_IS_ROOT, > +}; > + > +static int __devinit twl6040_clk_probe(struct platform_device *pdev) > +{ > + struct twl6040 *twl6040 = dev_get_drvdata(pdev->dev.parent); > + struct twl6040_clk *clkdata; > + > + clkdata = devm_kzalloc(&pdev->dev, sizeof(*clkdata), GFP_KERNEL); > + if (!clkdata) > + return -ENOMEM; > + > + clkdata->dev = &pdev->dev; > + clkdata->twl6040 = twl6040; > + > + clkdata->mcpdm_fclk.init = &wm831x_clkout_init; > + clkdata->clk = clk_register(&pdev->dev, &clkdata->mcpdm_fclk); > + if (!clkdata->clk) > + return -EINVAL; > + > + dev_set_drvdata(&pdev->dev, clkdata); > + > + return 0; > +} > + > +static int __devexit twl6040_clk_remove(struct platform_device *pdev) > +{ > + struct twl6040_clk *clkdata = dev_get_drvdata(&pdev->dev); > + > + clk_unregister(clkdata->clk); > + > + return 0; > +} > + > +static struct platform_driver twl6040_clk_driver = { > + .driver = { > + .name = "twl6040-clk", > + .owner = THIS_MODULE, > + }, > + .probe = twl6040_clk_probe, > + .remove = __devexit_p(twl6040_clk_remove), > +}; > + > +module_platform_driver(twl6040_clk_driver); > + > +MODULE_DESCRIPTION("TWL6040 clock driver for McPDM functional clock"); > +MODULE_AUTHOR("Peter Ujfalusi "); > +MODULE_ALIAS("platform:twl6040-clk"); > +MODULE_LICENSE("GPL"); > -- > 1.7.12