summaryrefslogtreecommitdiff
path: root/drivers/clk/clk-bd718x7.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/clk-bd718x7.c')
-rw-r--r--drivers/clk/clk-bd718x7.c73
1 files changed, 58 insertions, 15 deletions
diff --git a/drivers/clk/clk-bd718x7.c b/drivers/clk/clk-bd718x7.c
index 60422c72d142..ac40b669d60b 100644
--- a/drivers/clk/clk-bd718x7.c
+++ b/drivers/clk/clk-bd718x7.c
@@ -7,24 +7,36 @@
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
-#include <linux/mfd/rohm-bd718x7.h>
+#include <linux/mfd/rohm-generic.h>
#include <linux/clk-provider.h>
#include <linux/clkdev.h>
#include <linux/regmap.h>
+/* clk control registers */
+/* BD71815 */
+#define BD71815_REG_OUT32K 0x1d
+/* BD71828 */
+#define BD71828_REG_OUT32K 0x4B
+/* BD71837 and BD71847 */
+#define BD718XX_REG_OUT32K 0x2E
+
+/*
+ * BD71837, BD71847, and BD71828 all use bit [0] to clk output control
+ */
+#define CLK_OUT_EN_MASK BIT(0)
+
+
struct bd718xx_clk {
struct clk_hw hw;
u8 reg;
u8 mask;
struct platform_device *pdev;
- struct bd718xx *mfd;
+ struct regmap *regmap;
};
-static int bd71837_clk_set(struct clk_hw *hw, int status)
+static int bd71837_clk_set(struct bd718xx_clk *c, unsigned int status)
{
- struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw);
-
- return regmap_update_bits(c->mfd->regmap, c->reg, c->mask, status);
+ return regmap_update_bits(c->regmap, c->reg, c->mask, status);
}
static void bd71837_clk_disable(struct clk_hw *hw)
@@ -32,14 +44,16 @@ static void bd71837_clk_disable(struct clk_hw *hw)
int rv;
struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw);
- rv = bd71837_clk_set(hw, 0);
+ rv = bd71837_clk_set(c, 0);
if (rv)
dev_dbg(&c->pdev->dev, "Failed to disable 32K clk (%d)\n", rv);
}
static int bd71837_clk_enable(struct clk_hw *hw)
{
- return bd71837_clk_set(hw, 1);
+ struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw);
+
+ return bd71837_clk_set(c, 0xffffffff);
}
static int bd71837_clk_is_enabled(struct clk_hw *hw)
@@ -48,7 +62,7 @@ static int bd71837_clk_is_enabled(struct clk_hw *hw)
int rval;
struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw);
- rval = regmap_read(c->mfd->regmap, c->reg, &enabled);
+ rval = regmap_read(c->regmap, c->reg, &enabled);
if (rval)
return rval;
@@ -68,16 +82,20 @@ static int bd71837_clk_probe(struct platform_device *pdev)
int rval = -ENOMEM;
const char *parent_clk;
struct device *parent = pdev->dev.parent;
- struct bd718xx *mfd = dev_get_drvdata(parent);
struct clk_init_data init = {
.name = "bd718xx-32k-out",
.ops = &bd71837_clk_ops,
};
+ enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data;
c = devm_kzalloc(&pdev->dev, sizeof(*c), GFP_KERNEL);
if (!c)
return -ENOMEM;
+ c->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+ if (!c->regmap)
+ return -ENODEV;
+
init.num_parents = 1;
parent_clk = of_clk_get_parent_name(parent->of_node, 0);
@@ -86,10 +104,24 @@ static int bd71837_clk_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "No parent clk found\n");
return -EINVAL;
}
-
- c->reg = BD718XX_REG_OUT32K;
- c->mask = BD718XX_OUT32K_EN;
- c->mfd = mfd;
+ switch (chip) {
+ case ROHM_CHIP_TYPE_BD71837:
+ case ROHM_CHIP_TYPE_BD71847:
+ c->reg = BD718XX_REG_OUT32K;
+ c->mask = CLK_OUT_EN_MASK;
+ break;
+ case ROHM_CHIP_TYPE_BD71828:
+ c->reg = BD71828_REG_OUT32K;
+ c->mask = CLK_OUT_EN_MASK;
+ break;
+ case ROHM_CHIP_TYPE_BD71815:
+ c->reg = BD71815_REG_OUT32K;
+ c->mask = CLK_OUT_EN_MASK;
+ break;
+ default:
+ dev_err(&pdev->dev, "Unknown clk chip\n");
+ return -EINVAL;
+ }
c->pdev = pdev;
c->hw.init = &init;
@@ -109,15 +141,26 @@ static int bd71837_clk_probe(struct platform_device *pdev)
return rval;
}
+static const struct platform_device_id bd718x7_clk_id[] = {
+ { "bd71837-clk", ROHM_CHIP_TYPE_BD71837 },
+ { "bd71847-clk", ROHM_CHIP_TYPE_BD71847 },
+ { "bd71828-clk", ROHM_CHIP_TYPE_BD71828 },
+ { "bd71815-clk", ROHM_CHIP_TYPE_BD71815 },
+ { },
+};
+MODULE_DEVICE_TABLE(platform, bd718x7_clk_id);
+
static struct platform_driver bd71837_clk = {
.driver = {
.name = "bd718xx-clk",
},
.probe = bd71837_clk_probe,
+ .id_table = bd718x7_clk_id,
};
module_platform_driver(bd71837_clk);
MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
-MODULE_DESCRIPTION("BD71837 chip clk driver");
+MODULE_DESCRIPTION("BD718(15/18/28/37/47/50) and chip clk driver");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:bd718xx-clk");