root/drivers/isdn/hardware/mISDN/speedfax.c

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

DEFINITIONS

This source file includes following definitions.
  1. _set_debug
  2. set_debug
  3. IOFUNC_IND
  4. enable_hwirq
  5. disable_hwirq
  6. reset_speedfax
  7. sfax_ctrl
  8. channel_ctrl
  9. sfax_dctrl
  10. init_card
  11. setup_speedfax
  12. release_card
  13. setup_instance
  14. sfaxpci_probe
  15. sfax_remove_pci
  16. Speedfax_init
  17. Speedfax_cleanup

   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 
  53 static int sfax_cnt;
  54 static u32 debug;
  55 static u32 irqloops = 4;
  56 
  57 struct 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 
  72 static LIST_HEAD(Cards);
  73 static DEFINE_RWLOCK(card_lock); /* protect Cards */
  74 
  75 static 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 
  83 static int
  84 set_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 
  99 MODULE_AUTHOR("Karsten Keil");
 100 MODULE_LICENSE("GPL v2");
 101 MODULE_VERSION(SPEEDFAX_REV);
 102 MODULE_FIRMWARE("isdn/ISAR.BIN");
 103 module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
 104 MODULE_PARM_DESC(debug, "Speedfax debug mask");
 105 module_param(irqloops, uint, S_IRUGO | S_IWUSR);
 106 MODULE_PARM_DESC(irqloops, "Speedfax maximal irqloops (default 4)");
 107 
 108 IOFUNC_IND(ISAC, sfax_hw, p_isac)
 109 IOFUNC_IND(ISAR, sfax_hw, p_isar)
 110 
 111 static irqreturn_t
 112 speedfax_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);
 126 Start_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 
 145 static void
 146 enable_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 
 153 static void
 154 disable_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 
 161 static void
 162 reset_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 
 175 static int
 176 sfax_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 
 207 static int
 208 channel_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 
 235 static int
 236 sfax_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 
 272 static int
 273 init_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 
 311 static int
 312 setup_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 
 340 static void
 341 release_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 
 361 static int
 362 setup_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);
 424 error_init:
 425         mISDN_unregister_device(&card->isac.dch.dev);
 426 error:
 427         release_region(card->cfg, 256);
 428 error_setup:
 429         card->isac.release(&card->isac);
 430         card->isar.release(&card->isar);
 431         release_firmware(firmware);
 432 error_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 
 441 static int
 442 sfaxpci_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 
 470 static void
 471 sfax_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 
 481 static 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 };
 492 MODULE_DEVICE_TABLE(pci, sfaxpci_ids);
 493 
 494 static 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 
 501 static int __init
 502 Speedfax_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 
 512 static void __exit
 513 Speedfax_cleanup(void)
 514 {
 515         pci_unregister_driver(&sfaxpci_driver);
 516 }
 517 
 518 module_init(Speedfax_init);
 519 module_exit(Speedfax_cleanup);

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