linux/drivers/net/can/sja1000/sja1000_platform.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (C) 2005 Sascha Hauer, Pengutronix
   4 * Copyright (C) 2007 Wolfgang Grandegger <wg@grandegger.com>
   5 */
   6
   7#include <linux/kernel.h>
   8#include <linux/module.h>
   9#include <linux/interrupt.h>
  10#include <linux/netdevice.h>
  11#include <linux/delay.h>
  12#include <linux/pci.h>
  13#include <linux/platform_device.h>
  14#include <linux/irq.h>
  15#include <linux/can/dev.h>
  16#include <linux/can/platform/sja1000.h>
  17#include <linux/io.h>
  18#include <linux/of.h>
  19#include <linux/of_device.h>
  20#include <linux/of_irq.h>
  21
  22#include "sja1000.h"
  23
  24#define DRV_NAME "sja1000_platform"
  25#define SP_CAN_CLOCK  (16000000 / 2)
  26
  27MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
  28MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
  29MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the platform bus");
  30MODULE_ALIAS("platform:" DRV_NAME);
  31MODULE_LICENSE("GPL v2");
  32
  33struct sja1000_of_data {
  34        size_t  priv_sz;
  35        int     (*init)(struct sja1000_priv *priv, struct device_node *of);
  36};
  37
  38struct technologic_priv {
  39        spinlock_t      io_lock;
  40};
  41
  42static u8 sp_read_reg8(const struct sja1000_priv *priv, int reg)
  43{
  44        return ioread8(priv->reg_base + reg);
  45}
  46
  47static void sp_write_reg8(const struct sja1000_priv *priv, int reg, u8 val)
  48{
  49        iowrite8(val, priv->reg_base + reg);
  50}
  51
  52static u8 sp_read_reg16(const struct sja1000_priv *priv, int reg)
  53{
  54        return ioread8(priv->reg_base + reg * 2);
  55}
  56
  57static void sp_write_reg16(const struct sja1000_priv *priv, int reg, u8 val)
  58{
  59        iowrite8(val, priv->reg_base + reg * 2);
  60}
  61
  62static u8 sp_read_reg32(const struct sja1000_priv *priv, int reg)
  63{
  64        return ioread8(priv->reg_base + reg * 4);
  65}
  66
  67static void sp_write_reg32(const struct sja1000_priv *priv, int reg, u8 val)
  68{
  69        iowrite8(val, priv->reg_base + reg * 4);
  70}
  71
  72static u8 sp_technologic_read_reg16(const struct sja1000_priv *priv, int reg)
  73{
  74        struct technologic_priv *tp = priv->priv;
  75        unsigned long flags;
  76        u8 val;
  77
  78        spin_lock_irqsave(&tp->io_lock, flags);
  79        iowrite16(reg, priv->reg_base + 0);
  80        val = ioread16(priv->reg_base + 2);
  81        spin_unlock_irqrestore(&tp->io_lock, flags);
  82
  83        return val;
  84}
  85
  86static void sp_technologic_write_reg16(const struct sja1000_priv *priv,
  87                                       int reg, u8 val)
  88{
  89        struct technologic_priv *tp = priv->priv;
  90        unsigned long flags;
  91
  92        spin_lock_irqsave(&tp->io_lock, flags);
  93        iowrite16(reg, priv->reg_base + 0);
  94        iowrite16(val, priv->reg_base + 2);
  95        spin_unlock_irqrestore(&tp->io_lock, flags);
  96}
  97
  98static int sp_technologic_init(struct sja1000_priv *priv, struct device_node *of)
  99{
 100        struct technologic_priv *tp = priv->priv;
 101
 102        priv->read_reg = sp_technologic_read_reg16;
 103        priv->write_reg = sp_technologic_write_reg16;
 104        spin_lock_init(&tp->io_lock);
 105
 106        return 0;
 107}
 108
 109static void sp_populate(struct sja1000_priv *priv,
 110                        struct sja1000_platform_data *pdata,
 111                        unsigned long resource_mem_flags)
 112{
 113        /* The CAN clock frequency is half the oscillator clock frequency */
 114        priv->can.clock.freq = pdata->osc_freq / 2;
 115        priv->ocr = pdata->ocr;
 116        priv->cdr = pdata->cdr;
 117
 118        switch (resource_mem_flags & IORESOURCE_MEM_TYPE_MASK) {
 119        case IORESOURCE_MEM_32BIT:
 120                priv->read_reg = sp_read_reg32;
 121                priv->write_reg = sp_write_reg32;
 122                break;
 123        case IORESOURCE_MEM_16BIT:
 124                priv->read_reg = sp_read_reg16;
 125                priv->write_reg = sp_write_reg16;
 126                break;
 127        case IORESOURCE_MEM_8BIT:
 128        default:
 129                priv->read_reg = sp_read_reg8;
 130                priv->write_reg = sp_write_reg8;
 131                break;
 132        }
 133}
 134
 135static void sp_populate_of(struct sja1000_priv *priv, struct device_node *of)
 136{
 137        int err;
 138        u32 prop;
 139
 140        err = of_property_read_u32(of, "reg-io-width", &prop);
 141        if (err)
 142                prop = 1; /* 8 bit is default */
 143
 144        switch (prop) {
 145        case 4:
 146                priv->read_reg = sp_read_reg32;
 147                priv->write_reg = sp_write_reg32;
 148                break;
 149        case 2:
 150                priv->read_reg = sp_read_reg16;
 151                priv->write_reg = sp_write_reg16;
 152                break;
 153        case 1:
 154        default:
 155                priv->read_reg = sp_read_reg8;
 156                priv->write_reg = sp_write_reg8;
 157        }
 158
 159        err = of_property_read_u32(of, "nxp,external-clock-frequency", &prop);
 160        if (!err)
 161                priv->can.clock.freq = prop / 2;
 162        else
 163                priv->can.clock.freq = SP_CAN_CLOCK; /* default */
 164
 165        err = of_property_read_u32(of, "nxp,tx-output-mode", &prop);
 166        if (!err)
 167                priv->ocr |= prop & OCR_MODE_MASK;
 168        else
 169                priv->ocr |= OCR_MODE_NORMAL; /* default */
 170
 171        err = of_property_read_u32(of, "nxp,tx-output-config", &prop);
 172        if (!err)
 173                priv->ocr |= (prop << OCR_TX_SHIFT) & OCR_TX_MASK;
 174        else
 175                priv->ocr |= OCR_TX0_PULLDOWN; /* default */
 176
 177        err = of_property_read_u32(of, "nxp,clock-out-frequency", &prop);
 178        if (!err && prop) {
 179                u32 divider = priv->can.clock.freq * 2 / prop;
 180
 181                if (divider > 1)
 182                        priv->cdr |= divider / 2 - 1;
 183                else
 184                        priv->cdr |= CDR_CLKOUT_MASK;
 185        } else {
 186                priv->cdr |= CDR_CLK_OFF; /* default */
 187        }
 188
 189        if (!of_property_read_bool(of, "nxp,no-comparator-bypass"))
 190                priv->cdr |= CDR_CBP; /* default */
 191}
 192
 193static struct sja1000_of_data technologic_data = {
 194        .priv_sz = sizeof(struct technologic_priv),
 195        .init = sp_technologic_init,
 196};
 197
 198static const struct of_device_id sp_of_table[] = {
 199        { .compatible = "nxp,sja1000", .data = NULL, },
 200        { .compatible = "technologic,sja1000", .data = &technologic_data, },
 201        { /* sentinel */ },
 202};
 203MODULE_DEVICE_TABLE(of, sp_of_table);
 204
 205static int sp_probe(struct platform_device *pdev)
 206{
 207        int err, irq = 0;
 208        void __iomem *addr;
 209        struct net_device *dev;
 210        struct sja1000_priv *priv;
 211        struct resource *res_mem, *res_irq = NULL;
 212        struct sja1000_platform_data *pdata;
 213        struct device_node *of = pdev->dev.of_node;
 214        const struct of_device_id *of_id;
 215        const struct sja1000_of_data *of_data = NULL;
 216        size_t priv_sz = 0;
 217
 218        pdata = dev_get_platdata(&pdev->dev);
 219        if (!pdata && !of) {
 220                dev_err(&pdev->dev, "No platform data provided!\n");
 221                return -ENODEV;
 222        }
 223
 224        res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 225        if (!res_mem)
 226                return -ENODEV;
 227
 228        if (!devm_request_mem_region(&pdev->dev, res_mem->start,
 229                                     resource_size(res_mem), DRV_NAME))
 230                return -EBUSY;
 231
 232        addr = devm_ioremap(&pdev->dev, res_mem->start,
 233                                    resource_size(res_mem));
 234        if (!addr)
 235                return -ENOMEM;
 236
 237        if (of)
 238                irq = irq_of_parse_and_map(of, 0);
 239        else
 240                res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 241
 242        if (!irq && !res_irq)
 243                return -ENODEV;
 244
 245        of_id = of_match_device(sp_of_table, &pdev->dev);
 246        if (of_id && of_id->data) {
 247                of_data = of_id->data;
 248                priv_sz = of_data->priv_sz;
 249        }
 250
 251        dev = alloc_sja1000dev(priv_sz);
 252        if (!dev)
 253                return -ENOMEM;
 254        priv = netdev_priv(dev);
 255
 256        if (res_irq) {
 257                irq = res_irq->start;
 258                priv->irq_flags = res_irq->flags & IRQF_TRIGGER_MASK;
 259                if (res_irq->flags & IORESOURCE_IRQ_SHAREABLE)
 260                        priv->irq_flags |= IRQF_SHARED;
 261        } else {
 262                priv->irq_flags = IRQF_SHARED;
 263        }
 264
 265        dev->irq = irq;
 266        priv->reg_base = addr;
 267
 268        if (of) {
 269                sp_populate_of(priv, of);
 270
 271                if (of_data && of_data->init) {
 272                        err = of_data->init(priv, of);
 273                        if (err)
 274                                goto exit_free;
 275                }
 276        } else {
 277                sp_populate(priv, pdata, res_mem->flags);
 278        }
 279
 280        platform_set_drvdata(pdev, dev);
 281        SET_NETDEV_DEV(dev, &pdev->dev);
 282
 283        err = register_sja1000dev(dev);
 284        if (err) {
 285                dev_err(&pdev->dev, "registering %s failed (err=%d)\n",
 286                        DRV_NAME, err);
 287                goto exit_free;
 288        }
 289
 290        dev_info(&pdev->dev, "%s device registered (reg_base=%p, irq=%d)\n",
 291                 DRV_NAME, priv->reg_base, dev->irq);
 292        return 0;
 293
 294 exit_free:
 295        free_sja1000dev(dev);
 296        return err;
 297}
 298
 299static int sp_remove(struct platform_device *pdev)
 300{
 301        struct net_device *dev = platform_get_drvdata(pdev);
 302
 303        unregister_sja1000dev(dev);
 304        free_sja1000dev(dev);
 305
 306        return 0;
 307}
 308
 309static struct platform_driver sp_driver = {
 310        .probe = sp_probe,
 311        .remove = sp_remove,
 312        .driver = {
 313                .name = DRV_NAME,
 314                .of_match_table = sp_of_table,
 315        },
 316};
 317
 318module_platform_driver(sp_driver);
 319