linux/drivers/staging/greybus/arche-apb-ctrl.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Arche Platform driver to control APB.
   4 *
   5 * Copyright 2014-2015 Google Inc.
   6 * Copyright 2014-2015 Linaro Ltd.
   7 */
   8
   9#include <linux/clk.h>
  10#include <linux/delay.h>
  11#include <linux/gpio/consumer.h>
  12#include <linux/interrupt.h>
  13#include <linux/of_irq.h>
  14#include <linux/module.h>
  15#include <linux/pinctrl/consumer.h>
  16#include <linux/platform_device.h>
  17#include <linux/pm.h>
  18#include <linux/regulator/consumer.h>
  19#include <linux/spinlock.h>
  20#include "arche_platform.h"
  21
  22static void apb_bootret_deassert(struct device *dev);
  23
  24struct arche_apb_ctrl_drvdata {
  25        /* Control GPIO signals to and from AP <=> AP Bridges */
  26        struct gpio_desc *resetn;
  27        struct gpio_desc *boot_ret;
  28        struct gpio_desc *pwroff;
  29        struct gpio_desc *wake_in;
  30        struct gpio_desc *wake_out;
  31        struct gpio_desc *pwrdn;
  32
  33        enum arche_platform_state state;
  34        bool init_disabled;
  35
  36        struct regulator *vcore;
  37        struct regulator *vio;
  38
  39        struct gpio_desc *clk_en;
  40        struct clk *clk;
  41
  42        struct pinctrl *pinctrl;
  43        struct pinctrl_state *pin_default;
  44
  45        /* V2: SPI Bus control  */
  46        struct gpio_desc *spi_en;
  47        bool spi_en_polarity_high;
  48};
  49
  50/*
  51 * Note that these low level api's are active high
  52 */
  53static inline void deassert_reset(struct gpio_desc *gpio)
  54{
  55        gpiod_set_raw_value(gpio, 1);
  56}
  57
  58static inline void assert_reset(struct gpio_desc *gpio)
  59{
  60        gpiod_set_raw_value(gpio, 0);
  61}
  62
  63/*
  64 * Note: Please do not modify the below sequence, as it is as per the spec
  65 */
  66static int coldboot_seq(struct platform_device *pdev)
  67{
  68        struct device *dev = &pdev->dev;
  69        struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);
  70        int ret;
  71
  72        if (apb->init_disabled ||
  73            apb->state == ARCHE_PLATFORM_STATE_ACTIVE)
  74                return 0;
  75
  76        /* Hold APB in reset state */
  77        assert_reset(apb->resetn);
  78
  79        if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && apb->spi_en)
  80                devm_gpiod_put(dev, apb->spi_en);
  81
  82        /* Enable power to APB */
  83        if (!IS_ERR(apb->vcore)) {
  84                ret = regulator_enable(apb->vcore);
  85                if (ret) {
  86                        dev_err(dev, "failed to enable core regulator\n");
  87                        return ret;
  88                }
  89        }
  90
  91        if (!IS_ERR(apb->vio)) {
  92                ret = regulator_enable(apb->vio);
  93                if (ret) {
  94                        dev_err(dev, "failed to enable IO regulator\n");
  95                        return ret;
  96                }
  97        }
  98
  99        apb_bootret_deassert(dev);
 100
 101        /* On DB3 clock was not mandatory */
 102        if (apb->clk_en)
 103                gpiod_set_value(apb->clk_en, 1);
 104
 105        usleep_range(100, 200);
 106
 107        /* deassert reset to APB : Active-low signal */
 108        deassert_reset(apb->resetn);
 109
 110        apb->state = ARCHE_PLATFORM_STATE_ACTIVE;
 111
 112        return 0;
 113}
 114
 115static int fw_flashing_seq(struct platform_device *pdev)
 116{
 117        struct device *dev = &pdev->dev;
 118        struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);
 119        int ret;
 120
 121        if (apb->init_disabled ||
 122            apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING)
 123                return 0;
 124
 125        ret = regulator_enable(apb->vcore);
 126        if (ret) {
 127                dev_err(dev, "failed to enable core regulator\n");
 128                return ret;
 129        }
 130
 131        ret = regulator_enable(apb->vio);
 132        if (ret) {
 133                dev_err(dev, "failed to enable IO regulator\n");
 134                return ret;
 135        }
 136
 137        if (apb->spi_en) {
 138                unsigned long flags;
 139
 140                if (apb->spi_en_polarity_high)
 141                        flags = GPIOD_OUT_HIGH;
 142                else
 143                        flags = GPIOD_OUT_LOW;
 144
 145                apb->spi_en = devm_gpiod_get(dev, "spi-en", flags);
 146                if (IS_ERR(apb->spi_en)) {
 147                        ret = PTR_ERR(apb->spi_en);
 148                        dev_err(dev, "Failed requesting SPI bus en GPIO: %d\n",
 149                                ret);
 150                        return ret;
 151                }
 152        }
 153
 154        /* for flashing device should be in reset state */
 155        assert_reset(apb->resetn);
 156        apb->state = ARCHE_PLATFORM_STATE_FW_FLASHING;
 157
 158        return 0;
 159}
 160
 161static int standby_boot_seq(struct platform_device *pdev)
 162{
 163        struct device *dev = &pdev->dev;
 164        struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);
 165
 166        if (apb->init_disabled)
 167                return 0;
 168
 169        /*
 170         * Even if it is in OFF state,
 171         * then we do not want to change the state
 172         */
 173        if (apb->state == ARCHE_PLATFORM_STATE_STANDBY ||
 174            apb->state == ARCHE_PLATFORM_STATE_OFF)
 175                return 0;
 176
 177        if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && apb->spi_en)
 178                devm_gpiod_put(dev, apb->spi_en);
 179
 180        /*
 181         * As per WDM spec, do nothing
 182         *
 183         * Pasted from WDM spec,
 184         *  - A falling edge on POWEROFF_L is detected (a)
 185         *  - WDM enters standby mode, but no output signals are changed
 186         */
 187
 188        /* TODO: POWEROFF_L is input to WDM module  */
 189        apb->state = ARCHE_PLATFORM_STATE_STANDBY;
 190        return 0;
 191}
 192
 193static void poweroff_seq(struct platform_device *pdev)
 194{
 195        struct device *dev = &pdev->dev;
 196        struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);
 197
 198        if (apb->init_disabled || apb->state == ARCHE_PLATFORM_STATE_OFF)
 199                return;
 200
 201        if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && apb->spi_en)
 202                devm_gpiod_put(dev, apb->spi_en);
 203
 204        /* disable the clock */
 205        if (apb->clk_en)
 206                gpiod_set_value(apb->clk_en, 0);
 207
 208        if (!IS_ERR(apb->vcore) && regulator_is_enabled(apb->vcore) > 0)
 209                regulator_disable(apb->vcore);
 210
 211        if (!IS_ERR(apb->vio) && regulator_is_enabled(apb->vio) > 0)
 212                regulator_disable(apb->vio);
 213
 214        /* As part of exit, put APB back in reset state */
 215        assert_reset(apb->resetn);
 216        apb->state = ARCHE_PLATFORM_STATE_OFF;
 217
 218        /* TODO: May have to send an event to SVC about this exit */
 219}
 220
 221static void apb_bootret_deassert(struct device *dev)
 222{
 223        struct arche_apb_ctrl_drvdata *apb = dev_get_drvdata(dev);
 224
 225        gpiod_set_value(apb->boot_ret, 0);
 226}
 227
 228int apb_ctrl_coldboot(struct device *dev)
 229{
 230        return coldboot_seq(to_platform_device(dev));
 231}
 232
 233int apb_ctrl_fw_flashing(struct device *dev)
 234{
 235        return fw_flashing_seq(to_platform_device(dev));
 236}
 237
 238int apb_ctrl_standby_boot(struct device *dev)
 239{
 240        return standby_boot_seq(to_platform_device(dev));
 241}
 242
 243void apb_ctrl_poweroff(struct device *dev)
 244{
 245        poweroff_seq(to_platform_device(dev));
 246}
 247
 248static ssize_t state_store(struct device *dev,
 249                           struct device_attribute *attr,
 250                           const char *buf, size_t count)
 251{
 252        struct platform_device *pdev = to_platform_device(dev);
 253        struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);
 254        int ret = 0;
 255        bool is_disabled;
 256
 257        if (sysfs_streq(buf, "off")) {
 258                if (apb->state == ARCHE_PLATFORM_STATE_OFF)
 259                        return count;
 260
 261                poweroff_seq(pdev);
 262        } else if (sysfs_streq(buf, "active")) {
 263                if (apb->state == ARCHE_PLATFORM_STATE_ACTIVE)
 264                        return count;
 265
 266                poweroff_seq(pdev);
 267                is_disabled = apb->init_disabled;
 268                apb->init_disabled = false;
 269                ret = coldboot_seq(pdev);
 270                if (ret)
 271                        apb->init_disabled = is_disabled;
 272        } else if (sysfs_streq(buf, "standby")) {
 273                if (apb->state == ARCHE_PLATFORM_STATE_STANDBY)
 274                        return count;
 275
 276                ret = standby_boot_seq(pdev);
 277        } else if (sysfs_streq(buf, "fw_flashing")) {
 278                if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING)
 279                        return count;
 280
 281                /*
 282                 * First we want to make sure we power off everything
 283                 * and then enter FW flashing state
 284                 */
 285                poweroff_seq(pdev);
 286                ret = fw_flashing_seq(pdev);
 287        } else {
 288                dev_err(dev, "unknown state\n");
 289                ret = -EINVAL;
 290        }
 291
 292        return ret ? ret : count;
 293}
 294
 295static ssize_t state_show(struct device *dev,
 296                          struct device_attribute *attr, char *buf)
 297{
 298        struct arche_apb_ctrl_drvdata *apb = dev_get_drvdata(dev);
 299
 300        switch (apb->state) {
 301        case ARCHE_PLATFORM_STATE_OFF:
 302                return sprintf(buf, "off%s\n",
 303                                apb->init_disabled ? ",disabled" : "");
 304        case ARCHE_PLATFORM_STATE_ACTIVE:
 305                return sprintf(buf, "active\n");
 306        case ARCHE_PLATFORM_STATE_STANDBY:
 307                return sprintf(buf, "standby\n");
 308        case ARCHE_PLATFORM_STATE_FW_FLASHING:
 309                return sprintf(buf, "fw_flashing\n");
 310        default:
 311                return sprintf(buf, "unknown state\n");
 312        }
 313}
 314
 315static DEVICE_ATTR_RW(state);
 316
 317static int apb_ctrl_get_devtree_data(struct platform_device *pdev,
 318                                     struct arche_apb_ctrl_drvdata *apb)
 319{
 320        struct device *dev = &pdev->dev;
 321        int ret;
 322
 323        apb->resetn = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
 324        if (IS_ERR(apb->resetn)) {
 325                ret = PTR_ERR(apb->resetn);
 326                dev_err(dev, "Failed requesting reset GPIO: %d\n", ret);
 327                return ret;
 328        }
 329
 330        apb->boot_ret = devm_gpiod_get(dev, "boot-ret", GPIOD_OUT_LOW);
 331        if (IS_ERR(apb->boot_ret)) {
 332                ret = PTR_ERR(apb->boot_ret);
 333                dev_err(dev, "Failed requesting bootret GPIO: %d\n", ret);
 334                return ret;
 335        }
 336
 337        /* It's not mandatory to support power management interface */
 338        apb->pwroff = devm_gpiod_get_optional(dev, "pwr-off", GPIOD_IN);
 339        if (IS_ERR(apb->pwroff)) {
 340                ret = PTR_ERR(apb->pwroff);
 341                dev_err(dev, "Failed requesting pwroff_n GPIO: %d\n", ret);
 342                return ret;
 343        }
 344
 345        /* Do not make clock mandatory as of now (for DB3) */
 346        apb->clk_en = devm_gpiod_get_optional(dev, "clock-en", GPIOD_OUT_LOW);
 347        if (IS_ERR(apb->clk_en)) {
 348                ret = PTR_ERR(apb->clk_en);
 349                dev_err(dev, "Failed requesting APB clock en GPIO: %d\n", ret);
 350                return ret;
 351        }
 352
 353        apb->pwrdn = devm_gpiod_get(dev, "pwr-down", GPIOD_OUT_LOW);
 354        if (IS_ERR(apb->pwrdn)) {
 355                ret = PTR_ERR(apb->pwrdn);
 356                dev_warn(dev, "Failed requesting power down GPIO: %d\n", ret);
 357                return ret;
 358        }
 359
 360        /* Regulators are optional, as we may have fixed supply coming in */
 361        apb->vcore = devm_regulator_get(dev, "vcore");
 362        if (IS_ERR(apb->vcore))
 363                dev_warn(dev, "no core regulator found\n");
 364
 365        apb->vio = devm_regulator_get(dev, "vio");
 366        if (IS_ERR(apb->vio))
 367                dev_warn(dev, "no IO regulator found\n");
 368
 369        apb->pinctrl = devm_pinctrl_get(&pdev->dev);
 370        if (IS_ERR(apb->pinctrl)) {
 371                dev_err(&pdev->dev, "could not get pinctrl handle\n");
 372                return PTR_ERR(apb->pinctrl);
 373        }
 374        apb->pin_default = pinctrl_lookup_state(apb->pinctrl, "default");
 375        if (IS_ERR(apb->pin_default)) {
 376                dev_err(&pdev->dev, "could not get default pin state\n");
 377                return PTR_ERR(apb->pin_default);
 378        }
 379
 380        /* Only applicable for platform >= V2 */
 381        if (of_property_read_bool(pdev->dev.of_node, "gb,spi-en-active-high"))
 382                apb->spi_en_polarity_high = true;
 383
 384        return 0;
 385}
 386
 387static int arche_apb_ctrl_probe(struct platform_device *pdev)
 388{
 389        int ret;
 390        struct arche_apb_ctrl_drvdata *apb;
 391        struct device *dev = &pdev->dev;
 392
 393        apb = devm_kzalloc(&pdev->dev, sizeof(*apb), GFP_KERNEL);
 394        if (!apb)
 395                return -ENOMEM;
 396
 397        ret = apb_ctrl_get_devtree_data(pdev, apb);
 398        if (ret) {
 399                dev_err(dev, "failed to get apb devicetree data %d\n", ret);
 400                return ret;
 401        }
 402
 403        /* Initially set APB to OFF state */
 404        apb->state = ARCHE_PLATFORM_STATE_OFF;
 405        /* Check whether device needs to be enabled on boot */
 406        if (of_property_read_bool(pdev->dev.of_node, "arche,init-disable"))
 407                apb->init_disabled = true;
 408
 409        platform_set_drvdata(pdev, apb);
 410
 411        /* Create sysfs interface to allow user to change state dynamically */
 412        ret = device_create_file(dev, &dev_attr_state);
 413        if (ret) {
 414                dev_err(dev, "failed to create state file in sysfs\n");
 415                return ret;
 416        }
 417
 418        dev_info(&pdev->dev, "Device registered successfully\n");
 419        return 0;
 420}
 421
 422static int arche_apb_ctrl_remove(struct platform_device *pdev)
 423{
 424        device_remove_file(&pdev->dev, &dev_attr_state);
 425        poweroff_seq(pdev);
 426        platform_set_drvdata(pdev, NULL);
 427
 428        return 0;
 429}
 430
 431static int __maybe_unused arche_apb_ctrl_suspend(struct device *dev)
 432{
 433        /*
 434         * If timing profile permits, we may shutdown bridge
 435         * completely
 436         *
 437         * TODO: sequence ??
 438         *
 439         * Also, need to make sure we meet precondition for unipro suspend
 440         * Precondition: Definition ???
 441         */
 442        return 0;
 443}
 444
 445static int __maybe_unused arche_apb_ctrl_resume(struct device *dev)
 446{
 447        /*
 448         * Atleast for ES2 we have to meet the delay requirement between
 449         * unipro switch and AP bridge init, depending on whether bridge is in
 450         * OFF state or standby state.
 451         *
 452         * Based on whether bridge is in standby or OFF state we may have to
 453         * assert multiple signals. Please refer to WDM spec, for more info.
 454         *
 455         */
 456        return 0;
 457}
 458
 459static void arche_apb_ctrl_shutdown(struct platform_device *pdev)
 460{
 461        apb_ctrl_poweroff(&pdev->dev);
 462}
 463
 464static SIMPLE_DEV_PM_OPS(arche_apb_ctrl_pm_ops, arche_apb_ctrl_suspend,
 465                         arche_apb_ctrl_resume);
 466
 467static const struct of_device_id arche_apb_ctrl_of_match[] = {
 468        { .compatible = "usbffff,2", },
 469        { },
 470};
 471
 472static struct platform_driver arche_apb_ctrl_device_driver = {
 473        .probe          = arche_apb_ctrl_probe,
 474        .remove         = arche_apb_ctrl_remove,
 475        .shutdown       = arche_apb_ctrl_shutdown,
 476        .driver         = {
 477                .name   = "arche-apb-ctrl",
 478                .pm     = &arche_apb_ctrl_pm_ops,
 479                .of_match_table = arche_apb_ctrl_of_match,
 480        }
 481};
 482
 483int __init arche_apb_init(void)
 484{
 485        return platform_driver_register(&arche_apb_ctrl_device_driver);
 486}
 487
 488void __exit arche_apb_exit(void)
 489{
 490        platform_driver_unregister(&arche_apb_ctrl_device_driver);
 491}
 492