[PATCH v3 6/6] mfd: da9063: add 32 kHz output clock to clock tree

From: Philipp Zabel
Date: Mon Jul 29 2013 - 13:01:17 EST


Signed-off-by: Philipp Zabel <p.zabel@xxxxxxxxxxxxxx>
---
drivers/mfd/da9063-core.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)

diff --git a/drivers/mfd/da9063-core.c b/drivers/mfd/da9063-core.c
index c9cf8d9..adcdc50 100644
--- a/drivers/mfd/da9063-core.c
+++ b/drivers/mfd/da9063-core.c
@@ -14,6 +14,7 @@
*
*/

+#include <linux/clk-provider.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -107,10 +108,68 @@ static struct mfd_cell da9063_devs[] = {
},
};

+struct da9063_out_32k_clk {
+ struct clk_hw clk_hw;
+ struct regmap *regmap;
+};
+
+static int da9063_out_32k_prepare(struct clk_hw *hw)
+{
+ struct da9063_out_32k_clk *out_32k =
+ container_of(hw, struct da9063_out_32k_clk, clk_hw);
+
+ return regmap_update_bits(out_32k->regmap, DA9063_REG_EN_32K,
+ DA9063_OUT_32K_EN, DA9063_OUT_32K_EN);
+}
+
+static void da9063_out_32k_unprepare(struct clk_hw *hw)
+{
+ struct da9063_out_32k_clk *out_32k =
+ container_of(hw, struct da9063_out_32k_clk, clk_hw);
+
+ regmap_update_bits(out_32k->regmap, DA9063_REG_EN_32K,
+ DA9063_OUT_32K_EN, 0);
+}
+
+static int da9063_out_32k_is_prepared(struct clk_hw *hw)
+{
+ struct da9063_out_32k_clk *out_32k =
+ container_of(hw, struct da9063_out_32k_clk, clk_hw);
+ int val;
+
+ regmap_read(out_32k->regmap, DA9063_REG_EN_32K, &val);
+
+ return val & DA9063_OUT_32K_EN;
+}
+
+static unsigned long da9063_out_32k_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ return 32000;
+}
+
+static long da9063_out_32k_round_rate(struct clk_hw *hw,
+ unsigned long rate,
+ unsigned long *prate)
+{
+ return 32000;
+}
+
+static const struct clk_ops da9063_out_32k_ops = {
+ .prepare = da9063_out_32k_prepare,
+ .unprepare = da9063_out_32k_unprepare,
+ .is_prepared = da9063_out_32k_is_prepared,
+ .recalc_rate = da9063_out_32k_recalc_rate,
+ .round_rate = da9063_out_32k_round_rate,
+};
+
int da9063_device_init(struct da9063 *da9063, unsigned int irq)
{
struct da9063_pdata *pdata = da9063->dev->platform_data;
+ struct da9063_out_32k_clk *out_32k;
+ struct clk_init_data init;
int model, revision;
+ struct clk *clk;
int ret;

if (pdata) {
@@ -165,6 +224,23 @@ int da9063_device_init(struct da9063 *da9063, unsigned int irq)
return ret;
}

+ out_32k = devm_kzalloc(da9063->dev, sizeof(*out_32k), GFP_KERNEL);
+ if (!out_32k)
+ return -ENOMEM;
+
+ init.name = "da9063_out_32k";
+ init.ops = &da9063_out_32k_ops;
+ init.flags = CLK_IS_BASIC | CLK_IS_ROOT;
+ init.parent_names = NULL;
+ init.num_parents = 0;
+
+ out_32k->clk_hw.init = &init;
+ out_32k->regmap = da9063->regmap;
+
+ clk = devm_clk_register(da9063->dev, &out_32k->clk_hw);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
ret = mfd_add_devices(da9063->dev, -1, da9063_devs,
ARRAY_SIZE(da9063_devs), NULL, da9063->irq_base,
NULL);
--
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/