root/drivers/staging/fieldbus/anybuss/arcx-anybus.c

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

DEFINITIONS

This source file includes following definitions.
  1. do_reset
  2. anybuss_reset
  3. export_reset_0
  4. export_reset_1
  5. create_parallel_regmap
  6. create_anybus_host
  7. version_show
  8. design_number_show
  9. controller_device_release
  10. can_power_is_enabled
  11. controller_probe
  12. controller_remove
  13. controller_init
  14. controller_exit

   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 
  39 struct 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 
  50 static 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 
  76 static 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 
  88 static 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 
  95 static 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 
 114 static 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 
 127 static 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 
 141 static struct anybuss_host *
 142 create_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 
 166 static 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 }
 173 static DEVICE_ATTR_RO(version);
 174 
 175 static 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 }
 182 static DEVICE_ATTR_RO(design_number);
 183 
 184 static struct attribute *controller_attributes[] = {
 185         &dev_attr_version.attr,
 186         &dev_attr_design_number.attr,
 187         NULL,
 188 };
 189 
 190 static struct attribute_group controller_attribute_group = {
 191         .attrs = controller_attributes,
 192 };
 193 
 194 static const struct attribute_group *controller_attribute_groups[] = {
 195         &controller_attribute_group,
 196         NULL,
 197 };
 198 
 199 static void controller_device_release(struct device *dev)
 200 {
 201         kfree(dev);
 202 }
 203 
 204 static 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 
 211 static struct regulator_ops can_power_ops = {
 212         .is_enabled = can_power_is_enabled,
 213 };
 214 
 215 static 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 
 223 static struct class *controller_class;
 224 static DEFINE_IDA(controller_index_ida);
 225 
 226 static 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;
 319 out_dev:
 320         put_device(cd->class_dev);
 321 out_ida:
 322         ida_simple_remove(&controller_index_ida, id);
 323 out_reset:
 324         gpiod_set_value_cansleep(cd->reset_gpiod, 1);
 325         return err;
 326 }
 327 
 328 static 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 
 339 static const struct of_device_id controller_of_match[] = {
 340         { .compatible = "arcx,anybus-controller" },
 341         { }
 342 };
 343 
 344 MODULE_DEVICE_TABLE(of, controller_of_match);
 345 
 346 static 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 
 355 static 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 
 369 static 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 
 376 module_init(controller_init);
 377 module_exit(controller_exit);
 378 
 379 MODULE_DESCRIPTION("Arcx Anybus-S Controller driver");
 380 MODULE_AUTHOR("Sven Van Asbroeck <TheSven73@gmail.com>");
 381 MODULE_LICENSE("GPL v2");

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