linux/drivers/isdn/hardware/mISDN/speedfax.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * speedfax.c   low level stuff for Sedlbauer Speedfax+ cards
   4 *              based on the ISAR DSP
   5 *              Thanks to Sedlbauer AG for informations and HW
   6 *
   7 * Author       Karsten Keil <keil@isdn4linux.de>
   8 *
   9 * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
  10 */
  11
  12#include <linux/interrupt.h>
  13#include <linux/module.h>
  14#include <linux/slab.h>
  15#include <linux/pci.h>
  16#include <linux/delay.h>
  17#include <linux/mISDNhw.h>
  18#include <linux/firmware.h>
  19#include "ipac.h"
  20#include "isar.h"
  21
  22#define SPEEDFAX_REV    "2.0"
  23
  24#define PCI_SUBVENDOR_SPEEDFAX_PYRAMID  0x51
  25#define PCI_SUBVENDOR_SPEEDFAX_PCI      0x54
  26#define PCI_SUB_ID_SEDLBAUER            0x01
  27
  28#define SFAX_PCI_ADDR           0xc8
  29#define SFAX_PCI_ISAC           0xd0
  30#define SFAX_PCI_ISAR           0xe0
  31
  32/* TIGER 100 Registers */
  33
  34#define TIGER_RESET_ADDR        0x00
  35#define TIGER_EXTERN_RESET_ON   0x01
  36#define TIGER_EXTERN_RESET_OFF  0x00
  37#define TIGER_AUX_CTRL          0x02
  38#define TIGER_AUX_DATA          0x03
  39#define TIGER_AUX_IRQMASK       0x05
  40#define TIGER_AUX_STATUS        0x07
  41
  42/* Tiger AUX BITs */
  43#define SFAX_AUX_IOMASK         0xdd    /* 1 and 5 are inputs */
  44#define SFAX_ISAR_RESET_BIT_OFF 0x00
  45#define SFAX_ISAR_RESET_BIT_ON  0x01
  46#define SFAX_TIGER_IRQ_BIT      0x02
  47#define SFAX_LED1_BIT           0x08
  48#define SFAX_LED2_BIT           0x10
  49
  50#define SFAX_PCI_RESET_ON       (SFAX_ISAR_RESET_BIT_ON)
  51#define SFAX_PCI_RESET_OFF      (SFAX_LED1_BIT | SFAX_LED2_BIT)
  52
  53static int sfax_cnt;
  54static u32 debug;
  55static u32 irqloops = 4;
  56
  57struct sfax_hw {
  58        struct list_head        list;
  59        struct pci_dev          *pdev;
  60        char                    name[MISDN_MAX_IDLEN];
  61        u32                     irq;
  62        u32                     irqcnt;
  63        u32                     cfg;
  64        struct _ioport          p_isac;
  65        struct _ioport          p_isar;
  66        u8                      aux_data;
  67        spinlock_t              lock;   /* HW access lock */
  68        struct isac_hw          isac;
  69        struct isar_hw          isar;
  70};
  71
  72static LIST_HEAD(Cards);
  73static DEFINE_RWLOCK(card_lock); /* protect Cards */
  74
  75static void
  76_set_debug(struct sfax_hw *card)
  77{
  78        card->isac.dch.debug = debug;
  79        card->isar.ch[0].bch.debug = debug;
  80        card->isar.ch[1].bch.debug = debug;
  81}
  82
  83static int
  84set_debug(const char *val, const struct kernel_param *kp)
  85{
  86        int ret;
  87        struct sfax_hw *card;
  88
  89        ret = param_set_uint(val, kp);
  90        if (!ret) {
  91                read_lock(&card_lock);
  92                list_for_each_entry(card, &Cards, list)
  93                        _set_debug(card);
  94                read_unlock(&card_lock);
  95        }
  96        return ret;
  97}
  98
  99MODULE_AUTHOR("Karsten Keil");
 100MODULE_LICENSE("GPL v2");
 101MODULE_VERSION(SPEEDFAX_REV);
 102MODULE_FIRMWARE("isdn/ISAR.BIN");
 103module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
 104MODULE_PARM_DESC(debug, "Speedfax debug mask");
 105module_param(irqloops, uint, S_IRUGO | S_IWUSR);
 106MODULE_PARM_DESC(irqloops, "Speedfax maximal irqloops (default 4)");
 107
 108IOFUNC_IND(ISAC, sfax_hw, p_isac)
 109IOFUNC_IND(ISAR, sfax_hw, p_isar)
 110
 111static irqreturn_t
 112speedfax_irq(int intno, void *dev_id)
 113{
 114        struct sfax_hw  *sf = dev_id;
 115        u8 val;
 116        int cnt = irqloops;
 117
 118        spin_lock(&sf->lock);
 119        val = inb(sf->cfg + TIGER_AUX_STATUS);
 120        if (val & SFAX_TIGER_IRQ_BIT) { /* for us or shared ? */
 121                spin_unlock(&sf->lock);
 122                return IRQ_NONE; /* shared */
 123        }
 124        sf->irqcnt++;
 125        val = ReadISAR_IND(sf, ISAR_IRQBIT);
 126Start_ISAR:
 127        if (val & ISAR_IRQSTA)
 128                mISDNisar_irq(&sf->isar);
 129        val = ReadISAC_IND(sf, ISAC_ISTA);
 130        if (val)
 131                mISDNisac_irq(&sf->isac, val);
 132        val = ReadISAR_IND(sf, ISAR_IRQBIT);
 133        if ((val & ISAR_IRQSTA) && cnt--)
 134                goto Start_ISAR;
 135        if (cnt < irqloops)
 136                pr_debug("%s: %d irqloops cpu%d\n", sf->name,
 137                         irqloops - cnt, smp_processor_id());
 138        if (irqloops && !cnt)
 139                pr_notice("%s: %d IRQ LOOP cpu%d\n", sf->name,
 140                          irqloops, smp_processor_id());
 141        spin_unlock(&sf->lock);
 142        return IRQ_HANDLED;
 143}
 144
 145static void
 146enable_hwirq(struct sfax_hw *sf)
 147{
 148        WriteISAC_IND(sf, ISAC_MASK, 0);
 149        WriteISAR_IND(sf, ISAR_IRQBIT, ISAR_IRQMSK);
 150        outb(SFAX_TIGER_IRQ_BIT, sf->cfg + TIGER_AUX_IRQMASK);
 151}
 152
 153static void
 154disable_hwirq(struct sfax_hw *sf)
 155{
 156        WriteISAC_IND(sf, ISAC_MASK, 0xFF);
 157        WriteISAR_IND(sf, ISAR_IRQBIT, 0);
 158        outb(0, sf->cfg + TIGER_AUX_IRQMASK);
 159}
 160
 161static void
 162reset_speedfax(struct sfax_hw *sf)
 163{
 164
 165        pr_debug("%s: resetting card\n", sf->name);
 166        outb(TIGER_EXTERN_RESET_ON, sf->cfg + TIGER_RESET_ADDR);
 167        outb(SFAX_PCI_RESET_ON, sf->cfg + TIGER_AUX_DATA);
 168        mdelay(1);
 169        outb(TIGER_EXTERN_RESET_OFF, sf->cfg + TIGER_RESET_ADDR);
 170        sf->aux_data = SFAX_PCI_RESET_OFF;
 171        outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA);
 172        mdelay(1);
 173}
 174
 175static int
 176sfax_ctrl(struct sfax_hw  *sf, u32 cmd, u_long arg)
 177{
 178        int ret = 0;
 179
 180        switch (cmd) {
 181        case HW_RESET_REQ:
 182                reset_speedfax(sf);
 183                break;
 184        case HW_ACTIVATE_IND:
 185                if (arg & 1)
 186                        sf->aux_data &= ~SFAX_LED1_BIT;
 187                if (arg & 2)
 188                        sf->aux_data &= ~SFAX_LED2_BIT;
 189                outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA);
 190                break;
 191        case HW_DEACT_IND:
 192                if (arg & 1)
 193                        sf->aux_data |= SFAX_LED1_BIT;
 194                if (arg & 2)
 195                        sf->aux_data |= SFAX_LED2_BIT;
 196                outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA);
 197                break;
 198        default:
 199                pr_info("%s: %s unknown command %x %lx\n",
 200                        sf->name, __func__, cmd, arg);
 201                ret = -EINVAL;
 202                break;
 203        }
 204        return ret;
 205}
 206
 207static int
 208channel_ctrl(struct sfax_hw  *sf, struct mISDN_ctrl_req *cq)
 209{
 210        int     ret = 0;
 211
 212        switch (cq->op) {
 213        case MISDN_CTRL_GETOP:
 214                cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_L1_TIMER3;
 215                break;
 216        case MISDN_CTRL_LOOP:
 217                /* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
 218                if (cq->channel < 0 || cq->channel > 3) {
 219                        ret = -EINVAL;
 220                        break;
 221                }
 222                ret = sf->isac.ctrl(&sf->isac, HW_TESTLOOP, cq->channel);
 223                break;
 224        case MISDN_CTRL_L1_TIMER3:
 225                ret = sf->isac.ctrl(&sf->isac, HW_TIMER3_VALUE, cq->p1);
 226                break;
 227        default:
 228                pr_info("%s: unknown Op %x\n", sf->name, cq->op);
 229                ret = -EINVAL;
 230                break;
 231        }
 232        return ret;
 233}
 234
 235static int
 236sfax_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
 237{
 238        struct mISDNdevice      *dev = container_of(ch, struct mISDNdevice, D);
 239        struct dchannel         *dch = container_of(dev, struct dchannel, dev);
 240        struct sfax_hw          *sf = dch->hw;
 241        struct channel_req      *rq;
 242        int                     err = 0;
 243
 244        pr_debug("%s: cmd:%x %p\n", sf->name, cmd, arg);
 245        switch (cmd) {
 246        case OPEN_CHANNEL:
 247                rq = arg;
 248                if (rq->protocol == ISDN_P_TE_S0)
 249                        err = sf->isac.open(&sf->isac, rq);
 250                else
 251                        err = sf->isar.open(&sf->isar, rq);
 252                if (err)
 253                        break;
 254                if (!try_module_get(THIS_MODULE))
 255                        pr_info("%s: cannot get module\n", sf->name);
 256                break;
 257        case CLOSE_CHANNEL:
 258                pr_debug("%s: dev(%d) close from %p\n", sf->name,
 259                         dch->dev.id, __builtin_return_address(0));
 260                module_put(THIS_MODULE);
 261                break;
 262        case CONTROL_CHANNEL:
 263                err = channel_ctrl(sf, arg);
 264                break;
 265        default:
 266                pr_debug("%s: unknown command %x\n", sf->name, cmd);
 267                return -EINVAL;
 268        }
 269        return err;
 270}
 271
 272static int
 273init_card(struct sfax_hw *sf)
 274{
 275        int     ret, cnt = 3;
 276        u_long  flags;
 277
 278        ret = request_irq(sf->irq, speedfax_irq, IRQF_SHARED, sf->name, sf);
 279        if (ret) {
 280                pr_info("%s: couldn't get interrupt %d\n", sf->name, sf->irq);
 281                return ret;
 282        }
 283        while (cnt--) {
 284                spin_lock_irqsave(&sf->lock, flags);
 285                ret = sf->isac.init(&sf->isac);
 286                if (ret) {
 287                        spin_unlock_irqrestore(&sf->lock, flags);
 288                        pr_info("%s: ISAC init failed with %d\n",
 289                                sf->name, ret);
 290                        break;
 291                }
 292                enable_hwirq(sf);
 293                /* RESET Receiver and Transmitter */
 294                WriteISAC_IND(sf, ISAC_CMDR, 0x41);
 295                spin_unlock_irqrestore(&sf->lock, flags);
 296                msleep_interruptible(10);
 297                if (debug & DEBUG_HW)
 298                        pr_notice("%s: IRQ %d count %d\n", sf->name,
 299                                  sf->irq, sf->irqcnt);
 300                if (!sf->irqcnt) {
 301                        pr_info("%s: IRQ(%d) got no requests during init %d\n",
 302                                sf->name, sf->irq, 3 - cnt);
 303                } else
 304                        return 0;
 305        }
 306        free_irq(sf->irq, sf);
 307        return -EIO;
 308}
 309
 310
 311static int
 312setup_speedfax(struct sfax_hw *sf)
 313{
 314        u_long flags;
 315
 316        if (!request_region(sf->cfg, 256, sf->name)) {
 317                pr_info("mISDN: %s config port %x-%x already in use\n",
 318                        sf->name, sf->cfg, sf->cfg + 255);
 319                return -EIO;
 320        }
 321        outb(0xff, sf->cfg);
 322        outb(0, sf->cfg);
 323        outb(0xdd, sf->cfg + TIGER_AUX_CTRL);
 324        outb(0, sf->cfg + TIGER_AUX_IRQMASK);
 325
 326        sf->isac.type = IPAC_TYPE_ISAC;
 327        sf->p_isac.ale = sf->cfg + SFAX_PCI_ADDR;
 328        sf->p_isac.port = sf->cfg + SFAX_PCI_ISAC;
 329        sf->p_isar.ale = sf->cfg + SFAX_PCI_ADDR;
 330        sf->p_isar.port = sf->cfg + SFAX_PCI_ISAR;
 331        ASSIGN_FUNC(IND, ISAC, sf->isac);
 332        ASSIGN_FUNC(IND, ISAR, sf->isar);
 333        spin_lock_irqsave(&sf->lock, flags);
 334        reset_speedfax(sf);
 335        disable_hwirq(sf);
 336        spin_unlock_irqrestore(&sf->lock, flags);
 337        return 0;
 338}
 339
 340static void
 341release_card(struct sfax_hw *card) {
 342        u_long  flags;
 343
 344        spin_lock_irqsave(&card->lock, flags);
 345        disable_hwirq(card);
 346        spin_unlock_irqrestore(&card->lock, flags);
 347        card->isac.release(&card->isac);
 348        free_irq(card->irq, card);
 349        card->isar.release(&card->isar);
 350        mISDN_unregister_device(&card->isac.dch.dev);
 351        release_region(card->cfg, 256);
 352        pci_disable_device(card->pdev);
 353        pci_set_drvdata(card->pdev, NULL);
 354        write_lock_irqsave(&card_lock, flags);
 355        list_del(&card->list);
 356        write_unlock_irqrestore(&card_lock, flags);
 357        kfree(card);
 358        sfax_cnt--;
 359}
 360
 361static int
 362setup_instance(struct sfax_hw *card)
 363{
 364        const struct firmware *firmware;
 365        int i, err;
 366        u_long flags;
 367
 368        snprintf(card->name, MISDN_MAX_IDLEN - 1, "Speedfax.%d", sfax_cnt + 1);
 369        write_lock_irqsave(&card_lock, flags);
 370        list_add_tail(&card->list, &Cards);
 371        write_unlock_irqrestore(&card_lock, flags);
 372        _set_debug(card);
 373        spin_lock_init(&card->lock);
 374        card->isac.hwlock = &card->lock;
 375        card->isar.hwlock = &card->lock;
 376        card->isar.ctrl = (void *)&sfax_ctrl;
 377        card->isac.name = card->name;
 378        card->isar.name = card->name;
 379        card->isar.owner = THIS_MODULE;
 380
 381        err = request_firmware(&firmware, "isdn/ISAR.BIN", &card->pdev->dev);
 382        if (err < 0) {
 383                pr_info("%s: firmware request failed %d\n",
 384                        card->name, err);
 385                goto error_fw;
 386        }
 387        if (debug & DEBUG_HW)
 388                pr_notice("%s: got firmware %zu bytes\n",
 389                          card->name, firmware->size);
 390
 391        mISDNisac_init(&card->isac, card);
 392
 393        card->isac.dch.dev.D.ctrl = sfax_dctrl;
 394        card->isac.dch.dev.Bprotocols =
 395                mISDNisar_init(&card->isar, card);
 396        for (i = 0; i < 2; i++) {
 397                set_channelmap(i + 1, card->isac.dch.dev.channelmap);
 398                list_add(&card->isar.ch[i].bch.ch.list,
 399                         &card->isac.dch.dev.bchannels);
 400        }
 401
 402        err = setup_speedfax(card);
 403        if (err)
 404                goto error_setup;
 405        err = card->isar.init(&card->isar);
 406        if (err)
 407                goto error;
 408        err = mISDN_register_device(&card->isac.dch.dev,
 409                                    &card->pdev->dev, card->name);
 410        if (err)
 411                goto error;
 412        err = init_card(card);
 413        if (err)
 414                goto error_init;
 415        err = card->isar.firmware(&card->isar, firmware->data, firmware->size);
 416        if (!err)  {
 417                release_firmware(firmware);
 418                sfax_cnt++;
 419                pr_notice("SpeedFax %d cards installed\n", sfax_cnt);
 420                return 0;
 421        }
 422        disable_hwirq(card);
 423        free_irq(card->irq, card);
 424error_init:
 425        mISDN_unregister_device(&card->isac.dch.dev);
 426error:
 427        release_region(card->cfg, 256);
 428error_setup:
 429        card->isac.release(&card->isac);
 430        card->isar.release(&card->isar);
 431        release_firmware(firmware);
 432error_fw:
 433        pci_disable_device(card->pdev);
 434        write_lock_irqsave(&card_lock, flags);
 435        list_del(&card->list);
 436        write_unlock_irqrestore(&card_lock, flags);
 437        kfree(card);
 438        return err;
 439}
 440
 441static int
 442sfaxpci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 443{
 444        int err = -ENOMEM;
 445        struct sfax_hw *card = kzalloc(sizeof(struct sfax_hw), GFP_KERNEL);
 446
 447        if (!card) {
 448                pr_info("No memory for Speedfax+ PCI\n");
 449                return err;
 450        }
 451        card->pdev = pdev;
 452        err = pci_enable_device(pdev);
 453        if (err) {
 454                kfree(card);
 455                return err;
 456        }
 457
 458        pr_notice("mISDN: Speedfax found adapter %s at %s\n",
 459                  (char *)ent->driver_data, pci_name(pdev));
 460
 461        card->cfg = pci_resource_start(pdev, 0);
 462        card->irq = pdev->irq;
 463        pci_set_drvdata(pdev, card);
 464        err = setup_instance(card);
 465        if (err)
 466                pci_set_drvdata(pdev, NULL);
 467        return err;
 468}
 469
 470static void
 471sfax_remove_pci(struct pci_dev *pdev)
 472{
 473        struct sfax_hw  *card = pci_get_drvdata(pdev);
 474
 475        if (card)
 476                release_card(card);
 477        else
 478                pr_debug("%s: drvdata already removed\n", __func__);
 479}
 480
 481static struct pci_device_id sfaxpci_ids[] = {
 482        { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
 483          PCI_SUBVENDOR_SPEEDFAX_PYRAMID, PCI_SUB_ID_SEDLBAUER,
 484          0, 0, (unsigned long) "Pyramid Speedfax + PCI"
 485        },
 486        { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
 487          PCI_SUBVENDOR_SPEEDFAX_PCI, PCI_SUB_ID_SEDLBAUER,
 488          0, 0, (unsigned long) "Sedlbauer Speedfax + PCI"
 489        },
 490        { }
 491};
 492MODULE_DEVICE_TABLE(pci, sfaxpci_ids);
 493
 494static struct pci_driver sfaxpci_driver = {
 495        .name = "speedfax+ pci",
 496        .probe = sfaxpci_probe,
 497        .remove = sfax_remove_pci,
 498        .id_table = sfaxpci_ids,
 499};
 500
 501static int __init
 502Speedfax_init(void)
 503{
 504        int err;
 505
 506        pr_notice("Sedlbauer Speedfax+ Driver Rev. %s\n",
 507                  SPEEDFAX_REV);
 508        err = pci_register_driver(&sfaxpci_driver);
 509        return err;
 510}
 511
 512static void __exit
 513Speedfax_cleanup(void)
 514{
 515        pci_unregister_driver(&sfaxpci_driver);
 516}
 517
 518module_init(Speedfax_init);
 519module_exit(Speedfax_cleanup);
 520