root/drivers/clk/uniphier/clk-uniphier-mux.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. uniphier_clk_mux_set_parent
  2. uniphier_clk_mux_get_parent
  3. uniphier_clk_register_mux

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   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 
  13 struct 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 
  23 static 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 
  31 static u8 uniphier_clk_mux_get_parent(struct clk_hw *hw)
  32 {
  33         struct uniphier_clk_mux *mux = to_uniphier_clk_mux(hw);
  34         int num_parents = clk_hw_get_num_parents(hw);
  35         int ret;
  36         unsigned int val;
  37         u8 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 
  50 static 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 
  56 struct 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 }

/* [<][>][^][v][top][bottom][index][help] */