linux/drivers/staging/fieldbus/anybuss/arcx-anybus.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Arcx Anybus-S Controller driver
   4 *
   5 * Copyright (C) 2018 Arcx Inc
   6 */
   7
   8#include <linux/kernel.h>
   9#include <linux/module.h>
  10#include <linux/init.h>
  11#include <linux/slab.h>
  12#include <linux/platform_device.h>
  13#include <linux/gpio/consumer.h>
  14#include <linux/io.h>
  15#include <linux/of.h>
  16#include <linux/delay.h>
  17#include <linux/idr.h>
  18#include <linux/mutex.h>
  19#include <linux/regulator/driver.h>
  20#include <linux/regulator/machine.h>
  21#include <linux/regmap.h>
  22
  23/* move to <linux/anybuss-controller.h> when taking this out of staging */
  24#include "anybuss-controller.h"
  25
  26#define CPLD_STATUS1            0x80
  27#define CPLD_CONTROL            0x80
  28#define CPLD_CONTROL_CRST       0x40
  29#define CPLD_CONTROL_RST1       0x04
  30#define CPLD_CONTROL_RST2       0x80
  31#define CPLD_STATUS1_AB         0x02
  32#define CPLD_STATUS1_CAN_POWER  0x01
  33#define CPLD_DESIGN_LO          0x81
  34#define CPLD_DESIGN_HI          0x82
  35#define CPLD_CAP                0x83
  36#define CPLD_CAP_COMPAT         0x01
  37#define CPLD_CAP_SEP_RESETS     0x02
  38
  39struct controller_priv {
  40        struct device *class_dev;
  41        bool common_reset;
  42        struct gpio_desc *reset_gpiod;
  43        void __iomem *cpld_base;
  44        struct mutex ctrl_lock; /* protects CONTROL register */
  45        u8 control_reg;
  46        char version[3];
  47        u16 design_no;
  48};
  49
  50static void do_reset(struct controller_priv *cd, u8 rst_bit, bool reset)
  51{
  52        mutex_lock(&cd->ctrl_lock);
  53        /*
  54         * CPLD_CONTROL is write-only, so cache its value in
  55         * cd->control_reg
  56         */
  57        if (reset)
  58                cd->control_reg &= ~rst_bit;
  59        else
  60                cd->control_reg |= rst_bit;
  61        writeb(cd->control_reg, cd->cpld_base + CPLD_CONTROL);
  62        /*
  63         * h/w work-around:
  64         * the hardware is 'too fast', so a reset followed by an immediate
  65         * not-reset will _not_ change the anybus reset line in any way,
  66         * losing the reset. to prevent this from happening, introduce
  67         * a minimum reset duration.
  68         * Verified minimum safe duration required using a scope
  69         * on 14-June-2018: 100 us.
  70         */
  71        if (reset)
  72                usleep_range(100, 200);
  73        mutex_unlock(&cd->ctrl_lock);
  74}
  75
  76static int anybuss_reset(struct controller_priv *cd,
  77                         unsigned long id, bool reset)
  78{
  79        if (id >= 2)
  80                return -EINVAL;
  81        if (cd->common_reset)
  82                do_reset(cd, CPLD_CONTROL_CRST, reset);
  83        else
  84                do_reset(cd, id ? CPLD_CONTROL_RST2 : CPLD_CONTROL_RST1, reset);
  85        return 0;
  86}
  87
  88static void export_reset_0(struct device *dev, bool assert)
  89{
  90        struct controller_priv *cd = dev_get_drvdata(dev);
  91
  92        anybuss_reset(cd, 0, assert);
  93}
  94
  95static void export_reset_1(struct device *dev, bool assert)
  96{
  97        struct controller_priv *cd = dev_get_drvdata(dev);
  98
  99        anybuss_reset(cd, 1, assert);
 100}
 101
 102/*
 103 * parallel bus limitation:
 104 *
 105 * the anybus is 8-bit wide. we can't assume that the hardware will translate
 106 * word accesses on the parallel bus to multiple byte-accesses on the anybus.
 107 *
 108 * the imx WEIM bus does not provide this type of translation.
 109 *
 110 * to be safe, we will limit parallel bus accesses to a single byte
 111 * at a time for now.
 112 */
 113
 114static const struct regmap_config arcx_regmap_cfg = {
 115        .reg_bits = 16,
 116        .val_bits = 8,
 117        .max_register = 0x7ff,
 118        .use_single_read = true,
 119        .use_single_write = true,
 120        /*
 121         * single-byte parallel bus accesses are atomic, so don't
 122         * require any synchronization.
 123         */
 124        .disable_locking = true,
 125};
 126
 127static struct regmap *create_parallel_regmap(struct platform_device *pdev,
 128                                             int idx)
 129{
 130        void __iomem *base;
 131        struct device *dev = &pdev->dev;
 132
 133        base = devm_platform_ioremap_resource(pdev, idx + 1);
 134        if (IS_ERR(base))
 135                return ERR_CAST(base);
 136        return devm_regmap_init_mmio(dev, base, &arcx_regmap_cfg);
 137}
 138
 139static struct anybuss_host *
 140create_anybus_host(struct platform_device *pdev, int idx)
 141{
 142        struct anybuss_ops ops = {};
 143
 144        switch (idx) {
 145        case 0:
 146                ops.reset = export_reset_0;
 147                break;
 148        case 1:
 149                ops.reset = export_reset_1;
 150                break;
 151        default:
 152                return ERR_PTR(-EINVAL);
 153        }
 154        ops.host_idx = idx;
 155        ops.regmap = create_parallel_regmap(pdev, idx);
 156        if (IS_ERR(ops.regmap))
 157                return ERR_CAST(ops.regmap);
 158        ops.irq = platform_get_irq(pdev, idx);
 159        if (ops.irq <= 0)
 160                return ERR_PTR(-EINVAL);
 161        return devm_anybuss_host_common_probe(&pdev->dev, &ops);
 162}
 163
 164static ssize_t version_show(struct device *dev,
 165                            struct device_attribute *attr, char *buf)
 166{
 167        struct controller_priv *cd = dev_get_drvdata(dev);
 168
 169        return sprintf(buf, "%s\n", cd->version);
 170}
 171static DEVICE_ATTR_RO(version);
 172
 173static ssize_t design_number_show(struct device *dev,
 174                                  struct device_attribute *attr, char *buf)
 175{
 176        struct controller_priv *cd = dev_get_drvdata(dev);
 177
 178        return sprintf(buf, "%d\n", cd->design_no);
 179}
 180static DEVICE_ATTR_RO(design_number);
 181
 182static struct attribute *controller_attributes[] = {
 183        &dev_attr_version.attr,
 184        &dev_attr_design_number.attr,
 185        NULL,
 186};
 187
 188static const struct attribute_group controller_attribute_group = {
 189        .attrs = controller_attributes,
 190};
 191
 192static const struct attribute_group *controller_attribute_groups[] = {
 193        &controller_attribute_group,
 194        NULL,
 195};
 196
 197static void controller_device_release(struct device *dev)
 198{
 199        kfree(dev);
 200}
 201
 202static int can_power_is_enabled(struct regulator_dev *rdev)
 203{
 204        struct controller_priv *cd = rdev_get_drvdata(rdev);
 205
 206        return !(readb(cd->cpld_base + CPLD_STATUS1) & CPLD_STATUS1_CAN_POWER);
 207}
 208
 209static const struct regulator_ops can_power_ops = {
 210        .is_enabled = can_power_is_enabled,
 211};
 212
 213static const struct regulator_desc can_power_desc = {
 214        .name = "regulator-can-power",
 215        .id = -1,
 216        .type = REGULATOR_VOLTAGE,
 217        .owner = THIS_MODULE,
 218        .ops = &can_power_ops,
 219};
 220
 221static struct class *controller_class;
 222static DEFINE_IDA(controller_index_ida);
 223
 224static int controller_probe(struct platform_device *pdev)
 225{
 226        struct controller_priv *cd;
 227        struct device *dev = &pdev->dev;
 228        struct regulator_config config = { };
 229        struct regulator_dev *regulator;
 230        int err, id;
 231        struct anybuss_host *host;
 232        u8 status1, cap;
 233
 234        cd = devm_kzalloc(dev, sizeof(*cd), GFP_KERNEL);
 235        if (!cd)
 236                return -ENOMEM;
 237        dev_set_drvdata(dev, cd);
 238        mutex_init(&cd->ctrl_lock);
 239        cd->reset_gpiod = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
 240        if (IS_ERR(cd->reset_gpiod))
 241                return PTR_ERR(cd->reset_gpiod);
 242
 243        /* CPLD control memory, sits at index 0 */
 244        cd->cpld_base = devm_platform_ioremap_resource(pdev, 0);
 245        if (IS_ERR(cd->cpld_base)) {
 246                dev_err(dev,
 247                        "failed to map cpld base address\n");
 248                err = PTR_ERR(cd->cpld_base);
 249                goto out_reset;
 250        }
 251
 252        /* identify cpld */
 253        status1 = readb(cd->cpld_base + CPLD_STATUS1);
 254        cd->design_no = (readb(cd->cpld_base + CPLD_DESIGN_HI) << 8) |
 255                                readb(cd->cpld_base + CPLD_DESIGN_LO);
 256        snprintf(cd->version, sizeof(cd->version), "%c%d",
 257                 'A' + ((status1 >> 5) & 0x7),
 258                 (status1 >> 2) & 0x7);
 259        dev_info(dev, "design number %d, revision %s\n",
 260                 cd->design_no,
 261                cd->version);
 262        cap = readb(cd->cpld_base + CPLD_CAP);
 263        if (!(cap & CPLD_CAP_COMPAT)) {
 264                dev_err(dev, "unsupported controller [cap=0x%02X]", cap);
 265                err = -ENODEV;
 266                goto out_reset;
 267        }
 268
 269        if (status1 & CPLD_STATUS1_AB) {
 270                dev_info(dev, "has anybus-S slot(s)");
 271                cd->common_reset = !(cap & CPLD_CAP_SEP_RESETS);
 272                dev_info(dev, "supports %s", cd->common_reset ?
 273                        "a common reset" : "separate resets");
 274                for (id = 0; id < 2; id++) {
 275                        host = create_anybus_host(pdev, id);
 276                        if (!IS_ERR(host))
 277                                continue;
 278                        err = PTR_ERR(host);
 279                        /* -ENODEV is fine, it just means no card detected */
 280                        if (err != -ENODEV)
 281                                goto out_reset;
 282                }
 283        }
 284
 285        id = ida_simple_get(&controller_index_ida, 0, 0, GFP_KERNEL);
 286        if (id < 0) {
 287                err = id;
 288                goto out_reset;
 289        }
 290        /* export can power readout as a regulator */
 291        config.dev = dev;
 292        config.driver_data = cd;
 293        regulator = devm_regulator_register(dev, &can_power_desc, &config);
 294        if (IS_ERR(regulator)) {
 295                err = PTR_ERR(regulator);
 296                goto out_ida;
 297        }
 298        /* make controller info visible to userspace */
 299        cd->class_dev = kzalloc(sizeof(*cd->class_dev), GFP_KERNEL);
 300        if (!cd->class_dev) {
 301                err = -ENOMEM;
 302                goto out_ida;
 303        }
 304        cd->class_dev->class = controller_class;
 305        cd->class_dev->groups = controller_attribute_groups;
 306        cd->class_dev->parent = dev;
 307        cd->class_dev->id = id;
 308        cd->class_dev->release = controller_device_release;
 309        dev_set_name(cd->class_dev, "%d", cd->class_dev->id);
 310        dev_set_drvdata(cd->class_dev, cd);
 311        err = device_register(cd->class_dev);
 312        if (err)
 313                goto out_dev;
 314        return 0;
 315out_dev:
 316        put_device(cd->class_dev);
 317out_ida:
 318        ida_simple_remove(&controller_index_ida, id);
 319out_reset:
 320        gpiod_set_value_cansleep(cd->reset_gpiod, 1);
 321        return err;
 322}
 323
 324static int controller_remove(struct platform_device *pdev)
 325{
 326        struct controller_priv *cd = platform_get_drvdata(pdev);
 327        int id = cd->class_dev->id;
 328
 329        device_unregister(cd->class_dev);
 330        ida_simple_remove(&controller_index_ida, id);
 331        gpiod_set_value_cansleep(cd->reset_gpiod, 1);
 332        return 0;
 333}
 334
 335static const struct of_device_id controller_of_match[] = {
 336        { .compatible = "arcx,anybus-controller" },
 337        { }
 338};
 339
 340MODULE_DEVICE_TABLE(of, controller_of_match);
 341
 342static struct platform_driver controller_driver = {
 343        .probe = controller_probe,
 344        .remove = controller_remove,
 345        .driver         = {
 346                .name   = "arcx-anybus-controller",
 347                .of_match_table = of_match_ptr(controller_of_match),
 348        },
 349};
 350
 351static int __init controller_init(void)
 352{
 353        int err;
 354
 355        controller_class = class_create(THIS_MODULE, "arcx_anybus_controller");
 356        if (IS_ERR(controller_class))
 357                return PTR_ERR(controller_class);
 358        err = platform_driver_register(&controller_driver);
 359        if (err)
 360                class_destroy(controller_class);
 361
 362        return err;
 363}
 364
 365static void __exit controller_exit(void)
 366{
 367        platform_driver_unregister(&controller_driver);
 368        class_destroy(controller_class);
 369        ida_destroy(&controller_index_ida);
 370}
 371
 372module_init(controller_init);
 373module_exit(controller_exit);
 374
 375MODULE_DESCRIPTION("Arcx Anybus-S Controller driver");
 376MODULE_AUTHOR("Sven Van Asbroeck <TheSven73@gmail.com>");
 377MODULE_LICENSE("GPL v2");
 378