speedfax.c (12472B)
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);