brintos

brintos / linux-shallow public Read only

0
0
Text · 2.8 KiB · cf8ddcf Raw
119 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Clock driver for Hi655x4 *5 * Copyright (c) 2017, Linaro Ltd.6 *7 * Author: Daniel Lezcano <daniel.lezcano@linaro.org>8 */9#include <linux/clk-provider.h>10#include <linux/module.h>11#include <linux/platform_device.h>12#include <linux/regmap.h>13#include <linux/slab.h>14#include <linux/mfd/core.h>15#include <linux/mfd/hi655x-pmic.h>16 17#define HI655X_CLK_BASE	HI655X_BUS_ADDR(0x1c)18#define HI655X_CLK_SET	BIT(6)19 20struct hi655x_clk {21	struct hi655x_pmic *hi655x;22	struct clk_hw       clk_hw;23};24 25static unsigned long hi655x_clk_recalc_rate(struct clk_hw *hw,26					    unsigned long parent_rate)27{28	return 32768;29}30 31static int hi655x_clk_enable(struct clk_hw *hw, bool enable)32{33	struct hi655x_clk *hi655x_clk =34		container_of(hw, struct hi655x_clk, clk_hw);35 36	struct hi655x_pmic *hi655x = hi655x_clk->hi655x;37 38	return regmap_update_bits(hi655x->regmap, HI655X_CLK_BASE,39				  HI655X_CLK_SET, enable ? HI655X_CLK_SET : 0);40}41 42static int hi655x_clk_prepare(struct clk_hw *hw)43{44	return hi655x_clk_enable(hw, true);45}46 47static void hi655x_clk_unprepare(struct clk_hw *hw)48{49	hi655x_clk_enable(hw, false);50}51 52static int hi655x_clk_is_prepared(struct clk_hw *hw)53{54	struct hi655x_clk *hi655x_clk =55		container_of(hw, struct hi655x_clk, clk_hw);56	struct hi655x_pmic *hi655x = hi655x_clk->hi655x;57	int ret;58	uint32_t val;59 60	ret = regmap_read(hi655x->regmap, HI655X_CLK_BASE, &val);61	if (ret < 0)62		return ret;63 64	return val & HI655X_CLK_BASE;65}66 67static const struct clk_ops hi655x_clk_ops = {68	.prepare     = hi655x_clk_prepare,69	.unprepare   = hi655x_clk_unprepare,70	.is_prepared = hi655x_clk_is_prepared,71	.recalc_rate = hi655x_clk_recalc_rate,72};73 74static int hi655x_clk_probe(struct platform_device *pdev)75{76	struct device *parent = pdev->dev.parent;77	struct hi655x_pmic *hi655x = dev_get_drvdata(parent);78	struct hi655x_clk *hi655x_clk;79	const char *clk_name = "hi655x-clk";80	struct clk_init_data init = {81		.name = clk_name,82		.ops = &hi655x_clk_ops83	};84	int ret;85 86	hi655x_clk = devm_kzalloc(&pdev->dev, sizeof(*hi655x_clk), GFP_KERNEL);87	if (!hi655x_clk)88		return -ENOMEM;89 90	of_property_read_string_index(parent->of_node, "clock-output-names",91				      0, &clk_name);92 93	hi655x_clk->clk_hw.init	= &init;94	hi655x_clk->hi655x	= hi655x;95 96	platform_set_drvdata(pdev, hi655x_clk);97 98	ret = devm_clk_hw_register(&pdev->dev, &hi655x_clk->clk_hw);99	if (ret)100		return ret;101 102	return devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_simple_get,103					   &hi655x_clk->clk_hw);104}105 106static struct platform_driver hi655x_clk_driver = {107	.probe =  hi655x_clk_probe,108	.driver		= {109		.name	= "hi655x-clk",110	},111};112 113module_platform_driver(hi655x_clk_driver);114 115MODULE_DESCRIPTION("Clk driver for the hi655x series PMICs");116MODULE_AUTHOR("Daniel Lezcano <daniel.lezcano@linaro.org>");117MODULE_LICENSE("GPL");118MODULE_ALIAS("platform:hi655x-clk");119