1085d7a45SStephen Boyd /* 2085d7a45SStephen Boyd * Copyright (c) 2014, The Linux Foundation. All rights reserved. 3085d7a45SStephen Boyd * 4085d7a45SStephen Boyd * This software is licensed under the terms of the GNU General Public 5085d7a45SStephen Boyd * License version 2, as published by the Free Software Foundation, and 6085d7a45SStephen Boyd * may be copied, distributed, and modified under those terms. 7085d7a45SStephen Boyd * 8085d7a45SStephen Boyd * This program is distributed in the hope that it will be useful, 9085d7a45SStephen Boyd * but WITHOUT ANY WARRANTY; without even the implied warranty of 10085d7a45SStephen Boyd * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11085d7a45SStephen Boyd * GNU General Public License for more details. 12085d7a45SStephen Boyd */ 13085d7a45SStephen Boyd 14085d7a45SStephen Boyd #include <linux/device.h> 15085d7a45SStephen Boyd #include <linux/clk-provider.h> 16085d7a45SStephen Boyd #include <linux/regmap.h> 17085d7a45SStephen Boyd #include <linux/export.h> 18085d7a45SStephen Boyd 19085d7a45SStephen Boyd #include "clk-regmap.h" 20085d7a45SStephen Boyd 21085d7a45SStephen Boyd /** 22085d7a45SStephen Boyd * clk_is_enabled_regmap - standard is_enabled() for regmap users 23085d7a45SStephen Boyd * 24085d7a45SStephen Boyd * @hw: clk to operate on 25085d7a45SStephen Boyd * 26085d7a45SStephen Boyd * Clocks that use regmap for their register I/O can set the 27085d7a45SStephen Boyd * enable_reg and enable_mask fields in their struct clk_regmap and then use 28085d7a45SStephen Boyd * this as their is_enabled operation, saving some code. 29085d7a45SStephen Boyd */ 30085d7a45SStephen Boyd int clk_is_enabled_regmap(struct clk_hw *hw) 31085d7a45SStephen Boyd { 32085d7a45SStephen Boyd struct clk_regmap *rclk = to_clk_regmap(hw); 33085d7a45SStephen Boyd unsigned int val; 34085d7a45SStephen Boyd int ret; 35085d7a45SStephen Boyd 36085d7a45SStephen Boyd ret = regmap_read(rclk->regmap, rclk->enable_reg, &val); 37085d7a45SStephen Boyd if (ret != 0) 38085d7a45SStephen Boyd return ret; 39085d7a45SStephen Boyd 40085d7a45SStephen Boyd if (rclk->enable_is_inverted) 41085d7a45SStephen Boyd return (val & rclk->enable_mask) == 0; 42085d7a45SStephen Boyd else 43085d7a45SStephen Boyd return (val & rclk->enable_mask) != 0; 44085d7a45SStephen Boyd } 45085d7a45SStephen Boyd EXPORT_SYMBOL_GPL(clk_is_enabled_regmap); 46085d7a45SStephen Boyd 47085d7a45SStephen Boyd /** 48085d7a45SStephen Boyd * clk_enable_regmap - standard enable() for regmap users 49085d7a45SStephen Boyd * 50085d7a45SStephen Boyd * @hw: clk to operate on 51085d7a45SStephen Boyd * 52085d7a45SStephen Boyd * Clocks that use regmap for their register I/O can set the 53085d7a45SStephen Boyd * enable_reg and enable_mask fields in their struct clk_regmap and then use 54085d7a45SStephen Boyd * this as their enable() operation, saving some code. 55085d7a45SStephen Boyd */ 56085d7a45SStephen Boyd int clk_enable_regmap(struct clk_hw *hw) 57085d7a45SStephen Boyd { 58085d7a45SStephen Boyd struct clk_regmap *rclk = to_clk_regmap(hw); 59085d7a45SStephen Boyd unsigned int val; 60085d7a45SStephen Boyd 61085d7a45SStephen Boyd if (rclk->enable_is_inverted) 62085d7a45SStephen Boyd val = 0; 63085d7a45SStephen Boyd else 64085d7a45SStephen Boyd val = rclk->enable_mask; 65085d7a45SStephen Boyd 66085d7a45SStephen Boyd return regmap_update_bits(rclk->regmap, rclk->enable_reg, 67085d7a45SStephen Boyd rclk->enable_mask, val); 68085d7a45SStephen Boyd } 69085d7a45SStephen Boyd EXPORT_SYMBOL_GPL(clk_enable_regmap); 70085d7a45SStephen Boyd 71085d7a45SStephen Boyd /** 72085d7a45SStephen Boyd * clk_disable_regmap - standard disable() for regmap users 73085d7a45SStephen Boyd * 74085d7a45SStephen Boyd * @hw: clk to operate on 75085d7a45SStephen Boyd * 76085d7a45SStephen Boyd * Clocks that use regmap for their register I/O can set the 77085d7a45SStephen Boyd * enable_reg and enable_mask fields in their struct clk_regmap and then use 78085d7a45SStephen Boyd * this as their disable() operation, saving some code. 79085d7a45SStephen Boyd */ 80085d7a45SStephen Boyd void clk_disable_regmap(struct clk_hw *hw) 81085d7a45SStephen Boyd { 82085d7a45SStephen Boyd struct clk_regmap *rclk = to_clk_regmap(hw); 83085d7a45SStephen Boyd unsigned int val; 84085d7a45SStephen Boyd 85085d7a45SStephen Boyd if (rclk->enable_is_inverted) 86085d7a45SStephen Boyd val = rclk->enable_mask; 87085d7a45SStephen Boyd else 88085d7a45SStephen Boyd val = 0; 89085d7a45SStephen Boyd 90085d7a45SStephen Boyd regmap_update_bits(rclk->regmap, rclk->enable_reg, rclk->enable_mask, 91085d7a45SStephen Boyd val); 92085d7a45SStephen Boyd } 93085d7a45SStephen Boyd EXPORT_SYMBOL_GPL(clk_disable_regmap); 94085d7a45SStephen Boyd 95085d7a45SStephen Boyd /** 96085d7a45SStephen Boyd * devm_clk_register_regmap - register a clk_regmap clock 97085d7a45SStephen Boyd * 98085d7a45SStephen Boyd * @rclk: clk to operate on 99085d7a45SStephen Boyd * 100085d7a45SStephen Boyd * Clocks that use regmap for their register I/O should register their 101085d7a45SStephen Boyd * clk_regmap struct via this function so that the regmap is initialized 102085d7a45SStephen Boyd * and so that the clock is registered with the common clock framework. 103085d7a45SStephen Boyd */ 104085d7a45SStephen Boyd struct clk *devm_clk_register_regmap(struct device *dev, 105085d7a45SStephen Boyd struct clk_regmap *rclk) 106085d7a45SStephen Boyd { 107085d7a45SStephen Boyd if (dev && dev_get_regmap(dev, NULL)) 108085d7a45SStephen Boyd rclk->regmap = dev_get_regmap(dev, NULL); 109085d7a45SStephen Boyd else if (dev && dev->parent) 110085d7a45SStephen Boyd rclk->regmap = dev_get_regmap(dev->parent, NULL); 111085d7a45SStephen Boyd 112085d7a45SStephen Boyd return devm_clk_register(dev, &rclk->hw); 113085d7a45SStephen Boyd } 114085d7a45SStephen Boyd EXPORT_SYMBOL_GPL(devm_clk_register_regmap); 115