linux/drivers/clk/clk-gpio.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2013 - 2014 Texas Instruments Incorporated - http://www.ti.com
   3 *
   4 * Authors:
   5 *    Jyri Sarha <jsarha@ti.com>
   6 *    Sergej Sawazki <ce3a@gmx.de>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 *
  12 * Gpio controlled clock implementation
  13 */
  14
  15#include <linux/clk-provider.h>
  16#include <linux/export.h>
  17#include <linux/slab.h>
  18#include <linux/gpio.h>
  19#include <linux/gpio/consumer.h>
  20#include <linux/of_gpio.h>
  21#include <linux/err.h>
  22#include <linux/device.h>
  23#include <linux/platform_device.h>
  24#include <linux/of_device.h>
  25
  26/**
  27 * DOC: basic gpio gated clock which can be enabled and disabled
  28 *      with gpio output
  29 * Traits of this clock:
  30 * prepare - clk_(un)prepare only ensures parent is (un)prepared
  31 * enable - clk_enable and clk_disable are functional & control gpio
  32 * rate - inherits rate from parent.  No clk_set_rate support
  33 * parent - fixed parent.  No clk_set_parent support
  34 */
  35
  36static int clk_gpio_gate_enable(struct clk_hw *hw)
  37{
  38        struct clk_gpio *clk = to_clk_gpio(hw);
  39
  40        gpiod_set_value(clk->gpiod, 1);
  41
  42        return 0;
  43}
  44
  45static void clk_gpio_gate_disable(struct clk_hw *hw)
  46{
  47        struct clk_gpio *clk = to_clk_gpio(hw);
  48
  49        gpiod_set_value(clk->gpiod, 0);
  50}
  51
  52static int clk_gpio_gate_is_enabled(struct clk_hw *hw)
  53{
  54        struct clk_gpio *clk = to_clk_gpio(hw);
  55
  56        return gpiod_get_value(clk->gpiod);
  57}
  58
  59const struct clk_ops clk_gpio_gate_ops = {
  60        .enable = clk_gpio_gate_enable,
  61        .disable = clk_gpio_gate_disable,
  62        .is_enabled = clk_gpio_gate_is_enabled,
  63};
  64EXPORT_SYMBOL_GPL(clk_gpio_gate_ops);
  65
  66/**
  67 * DOC: basic clock multiplexer which can be controlled with a gpio output
  68 * Traits of this clock:
  69 * prepare - clk_prepare only ensures that parents are prepared
  70 * rate - rate is only affected by parent switching.  No clk_set_rate support
  71 * parent - parent is adjustable through clk_set_parent
  72 */
  73
  74static u8 clk_gpio_mux_get_parent(struct clk_hw *hw)
  75{
  76        struct clk_gpio *clk = to_clk_gpio(hw);
  77
  78        return gpiod_get_value(clk->gpiod);
  79}
  80
  81static int clk_gpio_mux_set_parent(struct clk_hw *hw, u8 index)
  82{
  83        struct clk_gpio *clk = to_clk_gpio(hw);
  84
  85        gpiod_set_value(clk->gpiod, index);
  86
  87        return 0;
  88}
  89
  90const struct clk_ops clk_gpio_mux_ops = {
  91        .get_parent = clk_gpio_mux_get_parent,
  92        .set_parent = clk_gpio_mux_set_parent,
  93        .determine_rate = __clk_mux_determine_rate,
  94};
  95EXPORT_SYMBOL_GPL(clk_gpio_mux_ops);
  96
  97static struct clk_hw *clk_register_gpio(struct device *dev, const char *name,
  98                const char * const *parent_names, u8 num_parents, unsigned gpio,
  99                bool active_low, unsigned long flags,
 100                const struct clk_ops *clk_gpio_ops)
 101{
 102        struct clk_gpio *clk_gpio;
 103        struct clk_hw *hw;
 104        struct clk_init_data init = {};
 105        unsigned long gpio_flags;
 106        int err;
 107
 108        if (dev)
 109                clk_gpio = devm_kzalloc(dev, sizeof(*clk_gpio), GFP_KERNEL);
 110        else
 111                clk_gpio = kzalloc(sizeof(*clk_gpio), GFP_KERNEL);
 112
 113        if (!clk_gpio)
 114                return ERR_PTR(-ENOMEM);
 115
 116        if (active_low)
 117                gpio_flags = GPIOF_ACTIVE_LOW | GPIOF_OUT_INIT_HIGH;
 118        else
 119                gpio_flags = GPIOF_OUT_INIT_LOW;
 120
 121        if (dev)
 122                err = devm_gpio_request_one(dev, gpio, gpio_flags, name);
 123        else
 124                err = gpio_request_one(gpio, gpio_flags, name);
 125        if (err) {
 126                if (err != -EPROBE_DEFER)
 127                        pr_err("%s: %s: Error requesting clock control gpio %u\n",
 128                                        __func__, name, gpio);
 129                if (!dev)
 130                        kfree(clk_gpio);
 131
 132                return ERR_PTR(err);
 133        }
 134
 135        init.name = name;
 136        init.ops = clk_gpio_ops;
 137        init.flags = flags | CLK_IS_BASIC;
 138        init.parent_names = parent_names;
 139        init.num_parents = num_parents;
 140
 141        clk_gpio->gpiod = gpio_to_desc(gpio);
 142        clk_gpio->hw.init = &init;
 143
 144        hw = &clk_gpio->hw;
 145        if (dev)
 146                err = devm_clk_hw_register(dev, hw);
 147        else
 148                err = clk_hw_register(NULL, hw);
 149
 150        if (!err)
 151                return hw;
 152
 153        if (!dev) {
 154                gpiod_put(clk_gpio->gpiod);
 155                kfree(clk_gpio);
 156        }
 157
 158        return ERR_PTR(err);
 159}
 160
 161/**
 162 * clk_hw_register_gpio_gate - register a gpio clock gate with the clock
 163 * framework
 164 * @dev: device that is registering this clock
 165 * @name: name of this clock
 166 * @parent_name: name of this clock's parent
 167 * @gpio: gpio number to gate this clock
 168 * @active_low: true if gpio should be set to 0 to enable clock
 169 * @flags: clock flags
 170 */
 171struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name,
 172                const char *parent_name, unsigned gpio, bool active_low,
 173                unsigned long flags)
 174{
 175        return clk_register_gpio(dev, name,
 176                        (parent_name ? &parent_name : NULL),
 177                        (parent_name ? 1 : 0), gpio, active_low, flags,
 178                        &clk_gpio_gate_ops);
 179}
 180EXPORT_SYMBOL_GPL(clk_hw_register_gpio_gate);
 181
 182struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
 183                const char *parent_name, unsigned gpio, bool active_low,
 184                unsigned long flags)
 185{
 186        struct clk_hw *hw;
 187
 188        hw = clk_hw_register_gpio_gate(dev, name, parent_name, gpio, active_low,
 189                                       flags);
 190        if (IS_ERR(hw))
 191                return ERR_CAST(hw);
 192        return hw->clk;
 193}
 194EXPORT_SYMBOL_GPL(clk_register_gpio_gate);
 195
 196/**
 197 * clk_hw_register_gpio_mux - register a gpio clock mux with the clock framework
 198 * @dev: device that is registering this clock
 199 * @name: name of this clock
 200 * @parent_names: names of this clock's parents
 201 * @num_parents: number of parents listed in @parent_names
 202 * @gpio: gpio number to gate this clock
 203 * @active_low: true if gpio should be set to 0 to enable clock
 204 * @flags: clock flags
 205 */
 206struct clk_hw *clk_hw_register_gpio_mux(struct device *dev, const char *name,
 207                const char * const *parent_names, u8 num_parents, unsigned gpio,
 208                bool active_low, unsigned long flags)
 209{
 210        if (num_parents != 2) {
 211                pr_err("mux-clock %s must have 2 parents\n", name);
 212                return ERR_PTR(-EINVAL);
 213        }
 214
 215        return clk_register_gpio(dev, name, parent_names, num_parents,
 216                        gpio, active_low, flags, &clk_gpio_mux_ops);
 217}
 218EXPORT_SYMBOL_GPL(clk_hw_register_gpio_mux);
 219
 220struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
 221                const char * const *parent_names, u8 num_parents, unsigned gpio,
 222                bool active_low, unsigned long flags)
 223{
 224        struct clk_hw *hw;
 225
 226        hw = clk_hw_register_gpio_mux(dev, name, parent_names, num_parents,
 227                        gpio, active_low, flags);
 228        if (IS_ERR(hw))
 229                return ERR_CAST(hw);
 230        return hw->clk;
 231}
 232EXPORT_SYMBOL_GPL(clk_register_gpio_mux);
 233
 234static int gpio_clk_driver_probe(struct platform_device *pdev)
 235{
 236        struct device_node *node = pdev->dev.of_node;
 237        const char **parent_names, *gpio_name;
 238        unsigned int num_parents;
 239        int gpio;
 240        enum of_gpio_flags of_flags;
 241        struct clk *clk;
 242        bool active_low, is_mux;
 243
 244        num_parents = of_clk_get_parent_count(node);
 245        if (num_parents) {
 246                parent_names = devm_kcalloc(&pdev->dev, num_parents,
 247                                            sizeof(char *), GFP_KERNEL);
 248                if (!parent_names)
 249                        return -ENOMEM;
 250
 251                of_clk_parent_fill(node, parent_names, num_parents);
 252        } else {
 253                parent_names = NULL;
 254        }
 255
 256        is_mux = of_device_is_compatible(node, "gpio-mux-clock");
 257
 258        gpio_name = is_mux ? "select-gpios" : "enable-gpios";
 259        gpio = of_get_named_gpio_flags(node, gpio_name, 0, &of_flags);
 260        if (gpio < 0) {
 261                if (gpio == -EPROBE_DEFER)
 262                        pr_debug("%s: %s: GPIOs not yet available, retry later\n",
 263                                        node->name, __func__);
 264                else
 265                        pr_err("%s: %s: Can't get '%s' DT property\n",
 266                                        node->name, __func__,
 267                                        gpio_name);
 268                return gpio;
 269        }
 270
 271        active_low = of_flags & OF_GPIO_ACTIVE_LOW;
 272
 273        if (is_mux)
 274                clk = clk_register_gpio_mux(&pdev->dev, node->name,
 275                                parent_names, num_parents, gpio, active_low, 0);
 276        else
 277                clk = clk_register_gpio_gate(&pdev->dev, node->name,
 278                                parent_names ?  parent_names[0] : NULL, gpio,
 279                                active_low, 0);
 280        if (IS_ERR(clk))
 281                return PTR_ERR(clk);
 282
 283        return of_clk_add_provider(node, of_clk_src_simple_get, clk);
 284}
 285
 286static const struct of_device_id gpio_clk_match_table[] = {
 287        { .compatible = "gpio-mux-clock" },
 288        { .compatible = "gpio-gate-clock" },
 289        { }
 290};
 291
 292static struct platform_driver gpio_clk_driver = {
 293        .probe          = gpio_clk_driver_probe,
 294        .driver         = {
 295                .name   = "gpio-clk",
 296                .of_match_table = gpio_clk_match_table,
 297        },
 298};
 299builtin_platform_driver(gpio_clk_driver);
 300