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        struct resource *res;
 131        void __iomem *base;
 132        struct device *dev = &pdev->dev;
 133
 134        res = platform_get_resource(pdev, IORESOURCE_MEM, idx + 1);
 135        base = devm_ioremap_resource(dev, res);
 136        if (IS_ERR(base))
 137                return ERR_CAST(base);
 138        return devm_regmap_init_mmio(dev, base, &arcx_regmap_cfg);
 139}
 140
 141static struct anybuss_host *
 142create_anybus_host(struct platform_device *pdev, int idx)
 143{
 144        struct anybuss_ops ops = {};
 145
 146        switch (idx) {
 147        case 0:
 148                ops.reset = export_reset_0;
 149                break;
 150        case 1:
 151                ops.reset = export_reset_1;
 152                break;
 153        default:
 154                return ERR_PTR(-EINVAL);
 155        }
 156        ops.host_idx = idx;
 157        ops.regmap = create_parallel_regmap(pdev, idx);
 158        if (IS_ERR(ops.regmap))
 159                return ERR_CAST(ops.regmap);
 160        ops.irq = platform_get_irq(pdev, idx);
 161        if (ops.irq <= 0)
 162                return ERR_PTR(-EINVAL);
 163        return devm_anybuss_host_common_probe(&pdev->dev, &ops);
 164}
 165
 166static ssize_t version_show(struct device *dev,
 167                            struct device_attribute *attr, char *buf)
 168{
 169        struct controller_priv *cd = dev_get_drvdata(dev);
 170
 171        return sprintf(buf, "%s\n", cd->version);
 172}
 173static DEVICE_ATTR_RO(version);
 174
 175static ssize_t design_number_show(struct device *dev,
 176                                  struct device_attribute *attr, char *buf)
 177{
 178        struct controller_priv *cd = dev_get_drvdata(dev);
 179
 180        return sprintf(buf, "%d\n", cd->design_no);
 181}
 182static DEVICE_ATTR_RO(design_number);
 183
 184static struct attribute *controller_attributes[] = {
 185        &dev_attr_version.attr,
 186        &dev_attr_design_number.attr,
 187        NULL,
 188};
 189
 190static struct attribute_group controller_attribute_group = {
 191        .attrs = controller_attributes,
 192};
 193
 194static const struct attribute_group *controller_attribute_groups[] = {
 195        &controller_attribute_group,
 196        NULL,
 197};
 198
 199static void controller_device_release(struct device *dev)
 200{
 201        kfree(dev);
 202}
 203
 204static int can_power_is_enabled(struct regulator_dev *rdev)
 205{
 206        struct controller_priv *cd = rdev_get_drvdata(rdev);
 207
 208        return !(readb(cd->cpld_base + CPLD_STATUS1) & CPLD_STATUS1_CAN_POWER);
 209}
 210
 211static struct regulator_ops can_power_ops = {
 212        .is_enabled = can_power_is_enabled,
 213};
 214
 215static const struct regulator_desc can_power_desc = {
 216        .name = "regulator-can-power",
 217        .id = -1,
 218        .type = REGULATOR_VOLTAGE,
 219        .owner = THIS_MODULE,
 220        .ops = &can_power_ops,
 221};
 222
 223static struct class *controller_class;
 224static DEFINE_IDA(controller_index_ida);
 225
 226static int controller_probe(struct platform_device *pdev)
 227{
 228        struct controller_priv *cd;
 229        struct device *dev = &pdev->dev;
 230        struct regulator_config config = { };
 231        struct regulator_dev *regulator;
 232        int err, id;
 233        struct resource *res;
 234        struct anybuss_host *host;
 235        u8 status1, cap;
 236
 237        cd = devm_kzalloc(dev, sizeof(*cd), GFP_KERNEL);
 238        if (!cd)
 239                return -ENOMEM;
 240        dev_set_drvdata(dev, cd);
 241        mutex_init(&cd->ctrl_lock);
 242        cd->reset_gpiod = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
 243        if (IS_ERR(cd->reset_gpiod))
 244                return PTR_ERR(cd->reset_gpiod);
 245
 246        /* CPLD control memory, sits at index 0 */
 247        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 248        cd->cpld_base = devm_ioremap_resource(dev, res);
 249        if (IS_ERR(cd->cpld_base)) {
 250                dev_err(dev,
 251                        "failed to map cpld base address\n");
 252                err = PTR_ERR(cd->cpld_base);
 253                goto out_reset;
 254        }
 255
 256        /* identify cpld */
 257        status1 = readb(cd->cpld_base + CPLD_STATUS1);
 258        cd->design_no = (readb(cd->cpld_base + CPLD_DESIGN_HI) << 8) |
 259                                readb(cd->cpld_base + CPLD_DESIGN_LO);
 260        snprintf(cd->version, sizeof(cd->version), "%c%d",
 261                 'A' + ((status1 >> 5) & 0x7),
 262                 (status1 >> 2) & 0x7);
 263        dev_info(dev, "design number %d, revision %s\n",
 264                 cd->design_no,
 265                cd->version);
 266        cap = readb(cd->cpld_base + CPLD_CAP);
 267        if (!(cap & CPLD_CAP_COMPAT)) {
 268                dev_err(dev, "unsupported controller [cap=0x%02X]", cap);
 269                err = -ENODEV;
 270                goto out_reset;
 271        }
 272
 273        if (status1 & CPLD_STATUS1_AB) {
 274                dev_info(dev, "has anybus-S slot(s)");
 275                cd->common_reset = !(cap & CPLD_CAP_SEP_RESETS);
 276                dev_info(dev, "supports %s", cd->common_reset ?
 277                        "a common reset" : "separate resets");
 278                for (id = 0; id < 2; id++) {
 279                        host = create_anybus_host(pdev, id);
 280                        if (!IS_ERR(host))
 281                                continue;
 282                        err = PTR_ERR(host);
 283                        /* -ENODEV is fine, it just means no card detected */
 284                        if (err != -ENODEV)
 285                                goto out_reset;
 286                }
 287        }
 288
 289        id = ida_simple_get(&controller_index_ida, 0, 0, GFP_KERNEL);
 290        if (id < 0) {
 291                err = id;
 292                goto out_reset;
 293        }
 294        /* export can power readout as a regulator */
 295        config.dev = dev;
 296        config.driver_data = cd;
 297        regulator = devm_regulator_register(dev, &can_power_desc, &config);
 298        if (IS_ERR(regulator)) {
 299                err = PTR_ERR(regulator);
 300                goto out_reset;
 301        }
 302        /* make controller info visible to userspace */
 303        cd->class_dev = kzalloc(sizeof(*cd->class_dev), GFP_KERNEL);
 304        if (!cd->class_dev) {
 305                err = -ENOMEM;
 306                goto out_ida;
 307        }
 308        cd->class_dev->class = controller_class;
 309        cd->class_dev->groups = controller_attribute_groups;
 310        cd->class_dev->parent = dev;
 311        cd->class_dev->id = id;
 312        cd->class_dev->release = controller_device_release;
 313        dev_set_name(cd->class_dev, "%d", cd->class_dev->id);
 314        dev_set_drvdata(cd->class_dev, cd);
 315        err = device_register(cd->class_dev);
 316        if (err)
 317                goto out_dev;
 318        return 0;
 319out_dev:
 320        put_device(cd->class_dev);
 321out_ida:
 322        ida_simple_remove(&controller_index_ida, id);
 323out_reset:
 324        gpiod_set_value_cansleep(cd->reset_gpiod, 1);
 325        return err;
 326}
 327
 328static int controller_remove(struct platform_device *pdev)
 329{
 330        struct controller_priv *cd = platform_get_drvdata(pdev);
 331        int id = cd->class_dev->id;
 332
 333        device_unregister(cd->class_dev);
 334        ida_simple_remove(&controller_index_ida, id);
 335        gpiod_set_value_cansleep(cd->reset_gpiod, 1);
 336        return 0;
 337}
 338
 339static const struct of_device_id controller_of_match[] = {
 340        { .compatible = "arcx,anybus-controller" },
 341        { }
 342};
 343
 344MODULE_DEVICE_TABLE(of, controller_of_match);
 345
 346static struct platform_driver controller_driver = {
 347        .probe = controller_probe,
 348        .remove = controller_remove,
 349        .driver         = {
 350                .name   = "arcx-anybus-controller",
 351                .of_match_table = of_match_ptr(controller_of_match),
 352        },
 353};
 354
 355static int __init controller_init(void)
 356{
 357        int err;
 358
 359        controller_class = class_create(THIS_MODULE, "arcx_anybus_controller");
 360        if (IS_ERR(controller_class))
 361                return PTR_ERR(controller_class);
 362        err = platform_driver_register(&controller_driver);
 363        if (err)
 364                class_destroy(controller_class);
 365
 366        return err;
 367}
 368
 369static void __exit controller_exit(void)
 370{
 371        platform_driver_unregister(&controller_driver);
 372        class_destroy(controller_class);
 373        ida_destroy(&controller_index_ida);
 374}
 375
 376module_init(controller_init);
 377module_exit(controller_exit);
 378
 379MODULE_DESCRIPTION("Arcx Anybus-S Controller driver");
 380MODULE_AUTHOR("Sven Van Asbroeck <TheSven73@gmail.com>");
 381MODULE_LICENSE("GPL v2");
 382