brintos

brintos / linux-shallow public Read only

0
0
Text · 2.0 KiB · 1998e9d Raw
87 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright (C) 2016 Socionext Inc.4 *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>5 */6 7#include <linux/clk-provider.h>8#include <linux/device.h>9#include <linux/regmap.h>10 11#include "clk-uniphier.h"12 13struct uniphier_clk_mux {14	struct clk_hw hw;15	struct regmap *regmap;16	unsigned int reg;17	const unsigned int *masks;18	const unsigned int *vals;19};20 21#define to_uniphier_clk_mux(_hw) container_of(_hw, struct uniphier_clk_mux, hw)22 23static int uniphier_clk_mux_set_parent(struct clk_hw *hw, u8 index)24{25	struct uniphier_clk_mux *mux = to_uniphier_clk_mux(hw);26 27	return regmap_write_bits(mux->regmap, mux->reg, mux->masks[index],28				 mux->vals[index]);29}30 31static u8 uniphier_clk_mux_get_parent(struct clk_hw *hw)32{33	struct uniphier_clk_mux *mux = to_uniphier_clk_mux(hw);34	unsigned int num_parents = clk_hw_get_num_parents(hw);35	int ret;36	unsigned int val;37	unsigned int i;38 39	ret = regmap_read(mux->regmap, mux->reg, &val);40	if (ret)41		return ret;42 43	for (i = 0; i < num_parents; i++)44		if ((mux->masks[i] & val) == mux->vals[i])45			return i;46 47	return -EINVAL;48}49 50static const struct clk_ops uniphier_clk_mux_ops = {51	.determine_rate = __clk_mux_determine_rate,52	.set_parent = uniphier_clk_mux_set_parent,53	.get_parent = uniphier_clk_mux_get_parent,54};55 56struct clk_hw *uniphier_clk_register_mux(struct device *dev,57					 struct regmap *regmap,58					 const char *name,59				const struct uniphier_clk_mux_data *data)60{61	struct uniphier_clk_mux *mux;62	struct clk_init_data init;63	int ret;64 65	mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);66	if (!mux)67		return ERR_PTR(-ENOMEM);68 69	init.name = name;70	init.ops = &uniphier_clk_mux_ops;71	init.flags = CLK_SET_RATE_PARENT;72	init.parent_names = data->parent_names;73	init.num_parents = data->num_parents;74 75	mux->regmap = regmap;76	mux->reg = data->reg;77	mux->masks = data->masks;78	mux->vals = data->vals;79	mux->hw.init = &init;80 81	ret = devm_clk_hw_register(dev, &mux->hw);82	if (ret)83		return ERR_PTR(ret);84 85	return &mux->hw;86}87