root/drivers/clk/sprd/div.c

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

DEFINITIONS

This source file includes following definitions.
  1. sprd_div_helper_round_rate
  2. sprd_div_round_rate
  3. sprd_div_helper_recalc_rate
  4. sprd_div_recalc_rate
  5. sprd_div_helper_set_rate
  6. sprd_div_set_rate

   1 // SPDX-License-Identifier: GPL-2.0
   2 //
   3 // Spreadtrum divider clock driver
   4 //
   5 // Copyright (C) 2017 Spreadtrum, Inc.
   6 // Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
   7 
   8 #include <linux/clk-provider.h>
   9 
  10 #include "div.h"
  11 
  12 long sprd_div_helper_round_rate(struct sprd_clk_common *common,
  13                                 const struct sprd_div_internal *div,
  14                                 unsigned long rate,
  15                                 unsigned long *parent_rate)
  16 {
  17         return divider_round_rate(&common->hw, rate, parent_rate,
  18                                   NULL, div->width, 0);
  19 }
  20 EXPORT_SYMBOL_GPL(sprd_div_helper_round_rate);
  21 
  22 static long sprd_div_round_rate(struct clk_hw *hw, unsigned long rate,
  23                                 unsigned long *parent_rate)
  24 {
  25         struct sprd_div *cd = hw_to_sprd_div(hw);
  26 
  27         return sprd_div_helper_round_rate(&cd->common, &cd->div,
  28                                           rate, parent_rate);
  29 }
  30 
  31 unsigned long sprd_div_helper_recalc_rate(struct sprd_clk_common *common,
  32                                           const struct sprd_div_internal *div,
  33                                           unsigned long parent_rate)
  34 {
  35         unsigned long val;
  36         unsigned int reg;
  37 
  38         regmap_read(common->regmap, common->reg, &reg);
  39         val = reg >> div->shift;
  40         val &= (1 << div->width) - 1;
  41 
  42         return divider_recalc_rate(&common->hw, parent_rate, val, NULL, 0,
  43                                    div->width);
  44 }
  45 EXPORT_SYMBOL_GPL(sprd_div_helper_recalc_rate);
  46 
  47 static unsigned long sprd_div_recalc_rate(struct clk_hw *hw,
  48                                           unsigned long parent_rate)
  49 {
  50         struct sprd_div *cd = hw_to_sprd_div(hw);
  51 
  52         return sprd_div_helper_recalc_rate(&cd->common, &cd->div, parent_rate);
  53 }
  54 
  55 int sprd_div_helper_set_rate(const struct sprd_clk_common *common,
  56                              const struct sprd_div_internal *div,
  57                              unsigned long rate,
  58                              unsigned long parent_rate)
  59 {
  60         unsigned long val;
  61         unsigned int reg;
  62 
  63         val = divider_get_val(rate, parent_rate, NULL,
  64                               div->width, 0);
  65 
  66         regmap_read(common->regmap, common->reg, &reg);
  67         reg &= ~GENMASK(div->width + div->shift - 1, div->shift);
  68 
  69         regmap_write(common->regmap, common->reg,
  70                           reg | (val << div->shift));
  71 
  72         return 0;
  73 
  74 }
  75 EXPORT_SYMBOL_GPL(sprd_div_helper_set_rate);
  76 
  77 static int sprd_div_set_rate(struct clk_hw *hw, unsigned long rate,
  78                              unsigned long parent_rate)
  79 {
  80         struct sprd_div *cd = hw_to_sprd_div(hw);
  81 
  82         return sprd_div_helper_set_rate(&cd->common, &cd->div,
  83                                         rate, parent_rate);
  84 }
  85 
  86 const struct clk_ops sprd_div_ops = {
  87         .recalc_rate = sprd_div_recalc_rate,
  88         .round_rate = sprd_div_round_rate,
  89         .set_rate = sprd_div_set_rate,
  90 };
  91 EXPORT_SYMBOL_GPL(sprd_div_ops);

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