162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) 2014, The Linux Foundation. All rights reserved. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include <linux/device.h> 762306a36Sopenharmony_ci#include <linux/clk-provider.h> 862306a36Sopenharmony_ci#include <linux/regmap.h> 962306a36Sopenharmony_ci#include <linux/export.h> 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include "clk-regmap.h" 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci/** 1462306a36Sopenharmony_ci * clk_is_enabled_regmap - standard is_enabled() for regmap users 1562306a36Sopenharmony_ci * 1662306a36Sopenharmony_ci * @hw: clk to operate on 1762306a36Sopenharmony_ci * 1862306a36Sopenharmony_ci * Clocks that use regmap for their register I/O can set the 1962306a36Sopenharmony_ci * enable_reg and enable_mask fields in their struct clk_regmap and then use 2062306a36Sopenharmony_ci * this as their is_enabled operation, saving some code. 2162306a36Sopenharmony_ci */ 2262306a36Sopenharmony_ciint clk_is_enabled_regmap(struct clk_hw *hw) 2362306a36Sopenharmony_ci{ 2462306a36Sopenharmony_ci struct clk_regmap *rclk = to_clk_regmap(hw); 2562306a36Sopenharmony_ci unsigned int val; 2662306a36Sopenharmony_ci int ret; 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci ret = regmap_read(rclk->regmap, rclk->enable_reg, &val); 2962306a36Sopenharmony_ci if (ret != 0) 3062306a36Sopenharmony_ci return ret; 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci if (rclk->enable_is_inverted) 3362306a36Sopenharmony_ci return (val & rclk->enable_mask) == 0; 3462306a36Sopenharmony_ci else 3562306a36Sopenharmony_ci return (val & rclk->enable_mask) != 0; 3662306a36Sopenharmony_ci} 3762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(clk_is_enabled_regmap); 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci/** 4062306a36Sopenharmony_ci * clk_enable_regmap - standard enable() for regmap users 4162306a36Sopenharmony_ci * 4262306a36Sopenharmony_ci * @hw: clk to operate on 4362306a36Sopenharmony_ci * 4462306a36Sopenharmony_ci * Clocks that use regmap for their register I/O can set the 4562306a36Sopenharmony_ci * enable_reg and enable_mask fields in their struct clk_regmap and then use 4662306a36Sopenharmony_ci * this as their enable() operation, saving some code. 4762306a36Sopenharmony_ci */ 4862306a36Sopenharmony_ciint clk_enable_regmap(struct clk_hw *hw) 4962306a36Sopenharmony_ci{ 5062306a36Sopenharmony_ci struct clk_regmap *rclk = to_clk_regmap(hw); 5162306a36Sopenharmony_ci unsigned int val; 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci if (rclk->enable_is_inverted) 5462306a36Sopenharmony_ci val = 0; 5562306a36Sopenharmony_ci else 5662306a36Sopenharmony_ci val = rclk->enable_mask; 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci return regmap_update_bits(rclk->regmap, rclk->enable_reg, 5962306a36Sopenharmony_ci rclk->enable_mask, val); 6062306a36Sopenharmony_ci} 6162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(clk_enable_regmap); 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci/** 6462306a36Sopenharmony_ci * clk_disable_regmap - standard disable() for regmap users 6562306a36Sopenharmony_ci * 6662306a36Sopenharmony_ci * @hw: clk to operate on 6762306a36Sopenharmony_ci * 6862306a36Sopenharmony_ci * Clocks that use regmap for their register I/O can set the 6962306a36Sopenharmony_ci * enable_reg and enable_mask fields in their struct clk_regmap and then use 7062306a36Sopenharmony_ci * this as their disable() operation, saving some code. 7162306a36Sopenharmony_ci */ 7262306a36Sopenharmony_civoid clk_disable_regmap(struct clk_hw *hw) 7362306a36Sopenharmony_ci{ 7462306a36Sopenharmony_ci struct clk_regmap *rclk = to_clk_regmap(hw); 7562306a36Sopenharmony_ci unsigned int val; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci if (rclk->enable_is_inverted) 7862306a36Sopenharmony_ci val = rclk->enable_mask; 7962306a36Sopenharmony_ci else 8062306a36Sopenharmony_ci val = 0; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci regmap_update_bits(rclk->regmap, rclk->enable_reg, rclk->enable_mask, 8362306a36Sopenharmony_ci val); 8462306a36Sopenharmony_ci} 8562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(clk_disable_regmap); 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci/** 8862306a36Sopenharmony_ci * devm_clk_register_regmap - register a clk_regmap clock 8962306a36Sopenharmony_ci * 9062306a36Sopenharmony_ci * @dev: reference to the caller's device 9162306a36Sopenharmony_ci * @rclk: clk to operate on 9262306a36Sopenharmony_ci * 9362306a36Sopenharmony_ci * Clocks that use regmap for their register I/O should register their 9462306a36Sopenharmony_ci * clk_regmap struct via this function so that the regmap is initialized 9562306a36Sopenharmony_ci * and so that the clock is registered with the common clock framework. 9662306a36Sopenharmony_ci */ 9762306a36Sopenharmony_ciint devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk) 9862306a36Sopenharmony_ci{ 9962306a36Sopenharmony_ci if (dev && dev_get_regmap(dev, NULL)) 10062306a36Sopenharmony_ci rclk->regmap = dev_get_regmap(dev, NULL); 10162306a36Sopenharmony_ci else if (dev && dev->parent) 10262306a36Sopenharmony_ci rclk->regmap = dev_get_regmap(dev->parent, NULL); 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci return devm_clk_hw_register(dev, &rclk->hw); 10562306a36Sopenharmony_ci} 10662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(devm_clk_register_regmap); 107