diff options
Diffstat (limited to 'drivers/net/irda/smsc-ircc2.c')
-rw-r--r-- | drivers/net/irda/smsc-ircc2.c | 330 |
1 files changed, 277 insertions, 53 deletions
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index bbcfc8ec35a1..a4674044bd6f 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include <linux/rtnetlink.h> | 54 | #include <linux/rtnetlink.h> |
55 | #include <linux/serial_reg.h> | 55 | #include <linux/serial_reg.h> |
56 | #include <linux/dma-mapping.h> | 56 | #include <linux/dma-mapping.h> |
57 | #include <linux/pnp.h> | ||
57 | #include <linux/platform_device.h> | 58 | #include <linux/platform_device.h> |
58 | 59 | ||
59 | #include <asm/io.h> | 60 | #include <asm/io.h> |
@@ -225,6 +226,8 @@ static int __init smsc_superio_lpc(unsigned short cfg_base); | |||
225 | #ifdef CONFIG_PCI | 226 | #ifdef CONFIG_PCI |
226 | static int __init preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuration *conf); | 227 | static int __init preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuration *conf); |
227 | static int __init preconfigure_through_82801(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf); | 228 | static int __init preconfigure_through_82801(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf); |
229 | static void __init preconfigure_ali_port(struct pci_dev *dev, | ||
230 | unsigned short port); | ||
228 | static int __init preconfigure_through_ali(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf); | 231 | static int __init preconfigure_through_ali(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf); |
229 | static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, | 232 | static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, |
230 | unsigned short ircc_fir, | 233 | unsigned short ircc_fir, |
@@ -356,6 +359,16 @@ static inline void register_bank(int iobase, int bank) | |||
356 | iobase + IRCC_MASTER); | 359 | iobase + IRCC_MASTER); |
357 | } | 360 | } |
358 | 361 | ||
362 | #ifdef CONFIG_PNP | ||
363 | /* PNP hotplug support */ | ||
364 | static const struct pnp_device_id smsc_ircc_pnp_table[] = { | ||
365 | { .id = "SMCf010", .driver_data = 0 }, | ||
366 | /* and presumably others */ | ||
367 | { } | ||
368 | }; | ||
369 | MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table); | ||
370 | #endif | ||
371 | |||
359 | 372 | ||
360 | /******************************************************************************* | 373 | /******************************************************************************* |
361 | * | 374 | * |
@@ -2070,7 +2083,8 @@ static void smsc_ircc_sir_wait_hw_transmitter_finish(struct smsc_ircc_cb *self) | |||
2070 | 2083 | ||
2071 | /* PROBING | 2084 | /* PROBING |
2072 | * | 2085 | * |
2073 | * | 2086 | * REVISIT we can be told about the device by PNP, and should use that info |
2087 | * instead of probing hardware and creating a platform_device ... | ||
2074 | */ | 2088 | */ |
2075 | 2089 | ||
2076 | static int __init smsc_ircc_look_for_chips(void) | 2090 | static int __init smsc_ircc_look_for_chips(void) |
@@ -2327,9 +2341,14 @@ static int __init smsc_superio_lpc(unsigned short cfg_base) | |||
2327 | * pre-configuration not properly done by the BIOS (especially laptops) | 2341 | * pre-configuration not properly done by the BIOS (especially laptops) |
2328 | * This code is based in part on smcinit.c, tosh1800-smcinit.c | 2342 | * This code is based in part on smcinit.c, tosh1800-smcinit.c |
2329 | * and tosh2450-smcinit.c. The table lists the device entries | 2343 | * and tosh2450-smcinit.c. The table lists the device entries |
2330 | * for ISA bridges with an LPC (Local Peripheral Configurator) | 2344 | * for ISA bridges with an LPC (Low Pin Count) controller which |
2331 | * that are in turn used to configure the SMSC device with default | 2345 | * handles the communication with the SMSC device. After the LPC |
2332 | * SIR and FIR I/O ports, DMA and IRQ. | 2346 | * controller is initialized through PCI, the SMSC device is initialized |
2347 | * through a dedicated port in the ISA port-mapped I/O area, this latter | ||
2348 | * area is used to configure the SMSC device with default | ||
2349 | * SIR and FIR I/O ports, DMA and IRQ. Different vendors have | ||
2350 | * used different sets of parameters and different control port | ||
2351 | * addresses making a subsystem device table necessary. | ||
2333 | */ | 2352 | */ |
2334 | #ifdef CONFIG_PCI | 2353 | #ifdef CONFIG_PCI |
2335 | #define PCIID_VENDOR_INTEL 0x8086 | 2354 | #define PCIID_VENDOR_INTEL 0x8086 |
@@ -2340,9 +2359,10 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __dev | |||
2340 | .device = 0x24cc, | 2359 | .device = 0x24cc, |
2341 | .subvendor = 0x103c, | 2360 | .subvendor = 0x103c, |
2342 | .subdevice = 0x088c, | 2361 | .subdevice = 0x088c, |
2343 | .sir_io = 0x02f8, /* Quite certain these are the same for nc8000 as for nc6000 */ | 2362 | /* Quite certain these are the same for nc8000 as for nc6000 */ |
2363 | .sir_io = 0x02f8, | ||
2344 | .fir_io = 0x0130, | 2364 | .fir_io = 0x0130, |
2345 | .fir_irq = 0x09, | 2365 | .fir_irq = 0x05, |
2346 | .fir_dma = 0x03, | 2366 | .fir_dma = 0x03, |
2347 | .cfg_base = 0x004e, | 2367 | .cfg_base = 0x004e, |
2348 | .preconfigure = preconfigure_through_82801, | 2368 | .preconfigure = preconfigure_through_82801, |
@@ -2355,60 +2375,79 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __dev | |||
2355 | .subdevice = 0x0890, | 2375 | .subdevice = 0x0890, |
2356 | .sir_io = 0x02f8, | 2376 | .sir_io = 0x02f8, |
2357 | .fir_io = 0x0130, | 2377 | .fir_io = 0x0130, |
2358 | .fir_irq = 0x09, | 2378 | .fir_irq = 0x05, |
2359 | .fir_dma = 0x03, | 2379 | .fir_dma = 0x03, |
2360 | .cfg_base = 0x004e, | 2380 | .cfg_base = 0x004e, |
2361 | .preconfigure = preconfigure_through_82801, | 2381 | .preconfigure = preconfigure_through_82801, |
2362 | .name = "HP nc6000", | 2382 | .name = "HP nc6000", |
2363 | }, | 2383 | }, |
2364 | { | 2384 | { |
2365 | .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge */ | 2385 | /* Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge */ |
2386 | .vendor = PCIID_VENDOR_INTEL, | ||
2366 | .device = 0x24c0, | 2387 | .device = 0x24c0, |
2367 | .subvendor = 0x1179, | 2388 | .subvendor = 0x1179, |
2368 | .subdevice = 0xffff, /* 0xffff is "any", Not sure, 0x0001 or 0x0002 */ | 2389 | .subdevice = 0xffff, /* 0xffff is "any" */ |
2369 | .sir_io = 0x03f8, | 2390 | .sir_io = 0x03f8, |
2370 | .fir_io = 0x0130, | 2391 | .fir_io = 0x0130, |
2371 | .fir_irq = 0x07, | 2392 | .fir_irq = 0x07, |
2372 | .fir_dma = 0x01, | 2393 | .fir_dma = 0x01, |
2373 | .cfg_base = 0x002e, | 2394 | .cfg_base = 0x002e, |
2374 | .preconfigure = preconfigure_through_82801, | 2395 | .preconfigure = preconfigure_through_82801, |
2375 | .name = "Toshiba Satellite 2450", | 2396 | .name = "Toshiba laptop with Intel 82801DB/DBL LPC bridge", |
2376 | }, | 2397 | }, |
2377 | { | 2398 | { |
2378 | .vendor = PCIID_VENDOR_INTEL, /* Intel 82801CAM ISA bridge */ | 2399 | .vendor = PCIID_VENDOR_INTEL, /* Intel 82801CAM ISA bridge */ |
2379 | .device = 0x248c, /* Some use 24cc? */ | 2400 | .device = 0x248c, |
2401 | .subvendor = 0x1179, | ||
2402 | .subdevice = 0xffff, /* 0xffff is "any" */ | ||
2403 | .sir_io = 0x03f8, | ||
2404 | .fir_io = 0x0130, | ||
2405 | .fir_irq = 0x03, | ||
2406 | .fir_dma = 0x03, | ||
2407 | .cfg_base = 0x002e, | ||
2408 | .preconfigure = preconfigure_through_82801, | ||
2409 | .name = "Toshiba laptop with Intel 82801CAM ISA bridge", | ||
2410 | }, | ||
2411 | { | ||
2412 | /* 82801DBM (ICH4-M) LPC Interface Bridge */ | ||
2413 | .vendor = PCIID_VENDOR_INTEL, | ||
2414 | .device = 0x24cc, | ||
2380 | .subvendor = 0x1179, | 2415 | .subvendor = 0x1179, |
2381 | .subdevice = 0xffff, /* 0xffff is "any", Not sure, 0x0001 or 0x0002 */ | 2416 | .subdevice = 0xffff, /* 0xffff is "any" */ |
2382 | .sir_io = 0x03f8, | 2417 | .sir_io = 0x03f8, |
2383 | .fir_io = 0x0130, | 2418 | .fir_io = 0x0130, |
2384 | .fir_irq = 0x03, | 2419 | .fir_irq = 0x03, |
2385 | .fir_dma = 0x03, | 2420 | .fir_dma = 0x03, |
2386 | .cfg_base = 0x002e, | 2421 | .cfg_base = 0x002e, |
2387 | .preconfigure = preconfigure_through_82801, | 2422 | .preconfigure = preconfigure_through_82801, |
2388 | .name = "Toshiba Satellite 5100/5200, Tecra 9100", | 2423 | .name = "Toshiba laptop with Intel 8281DBM LPC bridge", |
2389 | }, | 2424 | }, |
2390 | { | 2425 | { |
2391 | .vendor = PCIID_VENDOR_ALI, /* ALi M1533/M1535 PCI to ISA Bridge [Aladdin IV/V/V+] */ | 2426 | /* ALi M1533/M1535 PCI to ISA Bridge [Aladdin IV/V/V+] */ |
2427 | .vendor = PCIID_VENDOR_ALI, | ||
2392 | .device = 0x1533, | 2428 | .device = 0x1533, |
2393 | .subvendor = 0x1179, | 2429 | .subvendor = 0x1179, |
2394 | .subdevice = 0xffff, /* 0xffff is "any", Not sure, 0x0001 or 0x0002 */ | 2430 | .subdevice = 0xffff, /* 0xffff is "any" */ |
2395 | .sir_io = 0x02e8, | 2431 | .sir_io = 0x02e8, |
2396 | .fir_io = 0x02f8, | 2432 | .fir_io = 0x02f8, |
2397 | .fir_irq = 0x07, | 2433 | .fir_irq = 0x07, |
2398 | .fir_dma = 0x03, | 2434 | .fir_dma = 0x03, |
2399 | .cfg_base = 0x002e, | 2435 | .cfg_base = 0x002e, |
2400 | .preconfigure = preconfigure_through_ali, | 2436 | .preconfigure = preconfigure_through_ali, |
2401 | .name = "Toshiba Satellite 1800", | 2437 | .name = "Toshiba laptop with ALi ISA bridge", |
2402 | }, | 2438 | }, |
2403 | { } // Terminator | 2439 | { } // Terminator |
2404 | }; | 2440 | }; |
2405 | 2441 | ||
2406 | 2442 | ||
2407 | /* | 2443 | /* |
2408 | * This sets up the basic SMSC parameters (FIR port, SIR port, FIR DMA, FIR IRQ) | 2444 | * This sets up the basic SMSC parameters |
2445 | * (FIR port, SIR port, FIR DMA, FIR IRQ) | ||
2409 | * through the chip configuration port. | 2446 | * through the chip configuration port. |
2410 | */ | 2447 | */ |
2411 | static int __init preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuration *conf) | 2448 | static int __init preconfigure_smsc_chip(struct |
2449 | smsc_ircc_subsystem_configuration | ||
2450 | *conf) | ||
2412 | { | 2451 | { |
2413 | unsigned short iobase = conf->cfg_base; | 2452 | unsigned short iobase = conf->cfg_base; |
2414 | unsigned char tmpbyte; | 2453 | unsigned char tmpbyte; |
@@ -2416,7 +2455,9 @@ static int __init preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuratio | |||
2416 | outb(LPC47N227_CFGACCESSKEY, iobase); // enter configuration state | 2455 | outb(LPC47N227_CFGACCESSKEY, iobase); // enter configuration state |
2417 | outb(SMSCSIOFLAT_DEVICEID_REG, iobase); // set for device ID | 2456 | outb(SMSCSIOFLAT_DEVICEID_REG, iobase); // set for device ID |
2418 | tmpbyte = inb(iobase +1); // Read device ID | 2457 | tmpbyte = inb(iobase +1); // Read device ID |
2419 | IRDA_DEBUG(0, "Detected Chip id: 0x%02x, setting up registers...\n",tmpbyte); | 2458 | IRDA_DEBUG(0, |
2459 | "Detected Chip id: 0x%02x, setting up registers...\n", | ||
2460 | tmpbyte); | ||
2420 | 2461 | ||
2421 | /* Disable UART1 and set up SIR I/O port */ | 2462 | /* Disable UART1 and set up SIR I/O port */ |
2422 | outb(0x24, iobase); // select CR24 - UART1 base addr | 2463 | outb(0x24, iobase); // select CR24 - UART1 base addr |
@@ -2426,6 +2467,7 @@ static int __init preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuratio | |||
2426 | tmpbyte = inb(iobase + 1); | 2467 | tmpbyte = inb(iobase + 1); |
2427 | if (tmpbyte != (conf->sir_io >> 2) ) { | 2468 | if (tmpbyte != (conf->sir_io >> 2) ) { |
2428 | IRDA_WARNING("ERROR: could not configure SIR ioport.\n"); | 2469 | IRDA_WARNING("ERROR: could not configure SIR ioport.\n"); |
2470 | IRDA_WARNING("Try to supply ircc_cfg argument.\n"); | ||
2429 | return -ENXIO; | 2471 | return -ENXIO; |
2430 | } | 2472 | } |
2431 | 2473 | ||
@@ -2461,7 +2503,8 @@ static int __init preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuratio | |||
2461 | 2503 | ||
2462 | outb(SMSCSIOFLAT_UARTMODE0C_REG, iobase); // CR0C - UART mode | 2504 | outb(SMSCSIOFLAT_UARTMODE0C_REG, iobase); // CR0C - UART mode |
2463 | tmpbyte = inb(iobase + 1); | 2505 | tmpbyte = inb(iobase + 1); |
2464 | tmpbyte &= ~SMSCSIOFLAT_UART2MODE_MASK | SMSCSIOFLAT_UART2MODE_VAL_IRDA; | 2506 | tmpbyte &= ~SMSCSIOFLAT_UART2MODE_MASK | |
2507 | SMSCSIOFLAT_UART2MODE_VAL_IRDA; | ||
2465 | outb(tmpbyte, iobase + 1); // enable IrDA (HPSIR) mode, high speed | 2508 | outb(tmpbyte, iobase + 1); // enable IrDA (HPSIR) mode, high speed |
2466 | 2509 | ||
2467 | outb(LPC47N227_APMBOOTDRIVE_REG, iobase); // CR07 - Auto Pwr Mgt/boot drive sel | 2510 | outb(LPC47N227_APMBOOTDRIVE_REG, iobase); // CR07 - Auto Pwr Mgt/boot drive sel |
@@ -2486,53 +2529,226 @@ static int __init preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuratio | |||
2486 | return 0; | 2529 | return 0; |
2487 | } | 2530 | } |
2488 | 2531 | ||
2489 | /* 82801CAM registers */ | 2532 | /* 82801CAM generic registers */ |
2490 | #define VID 0x00 | 2533 | #define VID 0x00 |
2491 | #define DID 0x02 | 2534 | #define DID 0x02 |
2492 | #define PIRQA_ROUT 0x60 | 2535 | #define PIRQ_A_D_ROUT 0x60 |
2536 | #define SIRQ_CNTL 0x64 | ||
2537 | #define PIRQ_E_H_ROUT 0x68 | ||
2493 | #define PCI_DMA_C 0x90 | 2538 | #define PCI_DMA_C 0x90 |
2539 | /* LPC-specific registers */ | ||
2494 | #define COM_DEC 0xe0 | 2540 | #define COM_DEC 0xe0 |
2541 | #define GEN1_DEC 0xe4 | ||
2495 | #define LPC_EN 0xe6 | 2542 | #define LPC_EN 0xe6 |
2496 | #define GEN2_DEC 0xec | 2543 | #define GEN2_DEC 0xec |
2497 | /* | 2544 | /* |
2498 | * Sets up the I/O range using the 82801CAM ISA bridge, 82801DBM LPC bridge or | 2545 | * Sets up the I/O range using the 82801CAM ISA bridge, 82801DBM LPC bridge |
2499 | * Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge. They all work the same way! | 2546 | * or Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge. |
2547 | * They all work the same way! | ||
2500 | */ | 2548 | */ |
2501 | static int __init preconfigure_through_82801(struct pci_dev *dev, | 2549 | static int __init preconfigure_through_82801(struct pci_dev *dev, |
2502 | struct smsc_ircc_subsystem_configuration *conf) | 2550 | struct |
2551 | smsc_ircc_subsystem_configuration | ||
2552 | *conf) | ||
2503 | { | 2553 | { |
2504 | unsigned short tmpword; | 2554 | unsigned short tmpword; |
2505 | int ret; | 2555 | unsigned char tmpbyte; |
2506 | 2556 | ||
2507 | IRDA_MESSAGE("Setting up the SMSC device via the 82801 controller.\n"); | 2557 | IRDA_MESSAGE("Setting up Intel 82801 controller and SMSC device\n"); |
2508 | pci_write_config_byte(dev, COM_DEC, 0x10); | 2558 | /* |
2559 | * Select the range for the COMA COM port (SIR) | ||
2560 | * Register COM_DEC: | ||
2561 | * Bit 7: reserved | ||
2562 | * Bit 6-4, COMB decode range | ||
2563 | * Bit 3: reserved | ||
2564 | * Bit 2-0, COMA decode range | ||
2565 | * | ||
2566 | * Decode ranges: | ||
2567 | * 000 = 0x3f8-0x3ff (COM1) | ||
2568 | * 001 = 0x2f8-0x2ff (COM2) | ||
2569 | * 010 = 0x220-0x227 | ||
2570 | * 011 = 0x228-0x22f | ||
2571 | * 100 = 0x238-0x23f | ||
2572 | * 101 = 0x2e8-0x2ef (COM4) | ||
2573 | * 110 = 0x338-0x33f | ||
2574 | * 111 = 0x3e8-0x3ef (COM3) | ||
2575 | */ | ||
2576 | pci_read_config_byte(dev, COM_DEC, &tmpbyte); | ||
2577 | tmpbyte &= 0xf8; /* mask COMA bits */ | ||
2578 | switch(conf->sir_io) { | ||
2579 | case 0x3f8: | ||
2580 | tmpbyte |= 0x00; | ||
2581 | break; | ||
2582 | case 0x2f8: | ||
2583 | tmpbyte |= 0x01; | ||
2584 | break; | ||
2585 | case 0x220: | ||
2586 | tmpbyte |= 0x02; | ||
2587 | break; | ||
2588 | case 0x228: | ||
2589 | tmpbyte |= 0x03; | ||
2590 | break; | ||
2591 | case 0x238: | ||
2592 | tmpbyte |= 0x04; | ||
2593 | break; | ||
2594 | case 0x2e8: | ||
2595 | tmpbyte |= 0x05; | ||
2596 | break; | ||
2597 | case 0x338: | ||
2598 | tmpbyte |= 0x06; | ||
2599 | break; | ||
2600 | case 0x3e8: | ||
2601 | tmpbyte |= 0x07; | ||
2602 | break; | ||
2603 | default: | ||
2604 | tmpbyte |= 0x01; /* COM2 default */ | ||
2605 | } | ||
2606 | IRDA_DEBUG(1, "COM_DEC (write): 0x%02x\n", tmpbyte); | ||
2607 | pci_write_config_byte(dev, COM_DEC, tmpbyte); | ||
2509 | 2608 | ||
2510 | /* Enable LPC */ | 2609 | /* Enable Low Pin Count interface */ |
2511 | pci_read_config_word(dev, LPC_EN, &tmpword); /* LPC_EN register */ | 2610 | pci_read_config_word(dev, LPC_EN, &tmpword); |
2512 | tmpword &= 0xfffd; /* mask bit 1 */ | 2611 | /* These seem to be set up at all times, |
2513 | tmpword |= 0x0001; /* set bit 0 : COMA addr range enable */ | 2612 | * just make sure it is properly set. |
2613 | */ | ||
2614 | switch(conf->cfg_base) { | ||
2615 | case 0x04e: | ||
2616 | tmpword |= 0x2000; | ||
2617 | break; | ||
2618 | case 0x02e: | ||
2619 | tmpword |= 0x1000; | ||
2620 | break; | ||
2621 | case 0x062: | ||
2622 | tmpword |= 0x0800; | ||
2623 | break; | ||
2624 | case 0x060: | ||
2625 | tmpword |= 0x0400; | ||
2626 | break; | ||
2627 | default: | ||
2628 | IRDA_WARNING("Uncommon I/O base address: 0x%04x\n", | ||
2629 | conf->cfg_base); | ||
2630 | break; | ||
2631 | } | ||
2632 | tmpword &= 0xfffd; /* disable LPC COMB */ | ||
2633 | tmpword |= 0x0001; /* set bit 0 : enable LPC COMA addr range (GEN2) */ | ||
2634 | IRDA_DEBUG(1, "LPC_EN (write): 0x%04x\n", tmpword); | ||
2514 | pci_write_config_word(dev, LPC_EN, tmpword); | 2635 | pci_write_config_word(dev, LPC_EN, tmpword); |
2515 | 2636 | ||
2516 | /* Setup DMA */ | 2637 | /* |
2517 | pci_write_config_word(dev, PCI_DMA_C, 0xc0c0); /* LPC I/F DMA on, channel 3 -- rtm (?? PCI DMA ?) */ | 2638 | * Configure LPC DMA channel |
2518 | pci_write_config_word(dev, GEN2_DEC, 0x131); /* LPC I/F 2nd decode range */ | 2639 | * PCI_DMA_C bits: |
2640 | * Bit 15-14: DMA channel 7 select | ||
2641 | * Bit 13-12: DMA channel 6 select | ||
2642 | * Bit 11-10: DMA channel 5 select | ||
2643 | * Bit 9-8: Reserved | ||
2644 | * Bit 7-6: DMA channel 3 select | ||
2645 | * Bit 5-4: DMA channel 2 select | ||
2646 | * Bit 3-2: DMA channel 1 select | ||
2647 | * Bit 1-0: DMA channel 0 select | ||
2648 | * 00 = Reserved value | ||
2649 | * 01 = PC/PCI DMA | ||
2650 | * 10 = Reserved value | ||
2651 | * 11 = LPC I/F DMA | ||
2652 | */ | ||
2653 | pci_read_config_word(dev, PCI_DMA_C, &tmpword); | ||
2654 | switch(conf->fir_dma) { | ||
2655 | case 0x07: | ||
2656 | tmpword |= 0xc000; | ||
2657 | break; | ||
2658 | case 0x06: | ||
2659 | tmpword |= 0x3000; | ||
2660 | break; | ||
2661 | case 0x05: | ||
2662 | tmpword |= 0x0c00; | ||
2663 | break; | ||
2664 | case 0x03: | ||
2665 | tmpword |= 0x00c0; | ||
2666 | break; | ||
2667 | case 0x02: | ||
2668 | tmpword |= 0x0030; | ||
2669 | break; | ||
2670 | case 0x01: | ||
2671 | tmpword |= 0x000c; | ||
2672 | break; | ||
2673 | case 0x00: | ||
2674 | tmpword |= 0x0003; | ||
2675 | break; | ||
2676 | default: | ||
2677 | break; /* do not change settings */ | ||
2678 | } | ||
2679 | IRDA_DEBUG(1, "PCI_DMA_C (write): 0x%04x\n", tmpword); | ||
2680 | pci_write_config_word(dev, PCI_DMA_C, tmpword); | ||
2681 | |||
2682 | /* | ||
2683 | * GEN2_DEC bits: | ||
2684 | * Bit 15-4: Generic I/O range | ||
2685 | * Bit 3-1: reserved (read as 0) | ||
2686 | * Bit 0: enable GEN2 range on LPC I/F | ||
2687 | */ | ||
2688 | tmpword = conf->fir_io & 0xfff8; | ||
2689 | tmpword |= 0x0001; | ||
2690 | IRDA_DEBUG(1, "GEN2_DEC (write): 0x%04x\n", tmpword); | ||
2691 | pci_write_config_word(dev, GEN2_DEC, tmpword); | ||
2519 | 2692 | ||
2520 | /* Pre-configure chip */ | 2693 | /* Pre-configure chip */ |
2521 | ret = preconfigure_smsc_chip(conf); | 2694 | return preconfigure_smsc_chip(conf); |
2695 | } | ||
2522 | 2696 | ||
2523 | /* Disable LPC */ | 2697 | /* |
2524 | pci_read_config_word(dev, LPC_EN, &tmpword); /* LPC_EN register */ | 2698 | * Pre-configure a certain port on the ALi 1533 bridge. |
2525 | tmpword &= 0xfffc; /* mask bit 1 and bit 0, COMA addr range disable */ | 2699 | * This is based on reverse-engineering since ALi does not |
2526 | pci_write_config_word(dev, LPC_EN, tmpword); | 2700 | * provide any data sheet for the 1533 chip. |
2527 | return ret; | 2701 | */ |
2702 | static void __init preconfigure_ali_port(struct pci_dev *dev, | ||
2703 | unsigned short port) | ||
2704 | { | ||
2705 | unsigned char reg; | ||
2706 | /* These bits obviously control the different ports */ | ||
2707 | unsigned char mask; | ||
2708 | unsigned char tmpbyte; | ||
2709 | |||
2710 | switch(port) { | ||
2711 | case 0x0130: | ||
2712 | case 0x0178: | ||
2713 | reg = 0xb0; | ||
2714 | mask = 0x80; | ||
2715 | break; | ||
2716 | case 0x03f8: | ||
2717 | reg = 0xb4; | ||
2718 | mask = 0x80; | ||
2719 | break; | ||
2720 | case 0x02f8: | ||
2721 | reg = 0xb4; | ||
2722 | mask = 0x30; | ||
2723 | break; | ||
2724 | case 0x02e8: | ||
2725 | reg = 0xb4; | ||
2726 | mask = 0x08; | ||
2727 | break; | ||
2728 | default: | ||
2729 | IRDA_ERROR("Failed to configure unsupported port on ALi 1533 bridge: 0x%04x\n", port); | ||
2730 | return; | ||
2731 | } | ||
2732 | |||
2733 | pci_read_config_byte(dev, reg, &tmpbyte); | ||
2734 | /* Turn on the right bits */ | ||
2735 | tmpbyte |= mask; | ||
2736 | pci_write_config_byte(dev, reg, tmpbyte); | ||
2737 | IRDA_MESSAGE("Activated ALi 1533 ISA bridge port 0x%04x.\n", port); | ||
2738 | return; | ||
2528 | } | 2739 | } |
2529 | 2740 | ||
2530 | static int __init preconfigure_through_ali(struct pci_dev *dev, | 2741 | static int __init preconfigure_through_ali(struct pci_dev *dev, |
2531 | struct smsc_ircc_subsystem_configuration *conf) | 2742 | struct |
2743 | smsc_ircc_subsystem_configuration | ||
2744 | *conf) | ||
2532 | { | 2745 | { |
2533 | /* TODO: put in ALi 1533 configuration here. */ | 2746 | /* Configure the two ports on the ALi 1533 */ |
2534 | IRDA_MESSAGE("SORRY: %s has an unsupported bridge controller (ALi): not pre-configured.\n", conf->name); | 2747 | preconfigure_ali_port(dev, conf->sir_io); |
2535 | return -ENODEV; | 2748 | preconfigure_ali_port(dev, conf->fir_io); |
2749 | |||
2750 | /* Pre-configure chip */ | ||
2751 | return preconfigure_smsc_chip(conf); | ||
2536 | } | 2752 | } |
2537 | 2753 | ||
2538 | static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, | 2754 | static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, |
@@ -2552,9 +2768,10 @@ static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, | |||
2552 | struct smsc_ircc_subsystem_configuration *conf; | 2768 | struct smsc_ircc_subsystem_configuration *conf; |
2553 | 2769 | ||
2554 | /* | 2770 | /* |
2555 | * Cache the subsystem vendor/device: some manufacturers fail to set | 2771 | * Cache the subsystem vendor/device: |
2556 | * this for all components, so we save it in case there is just | 2772 | * some manufacturers fail to set this for all components, |
2557 | * 0x0000 0x0000 on the device we want to check. | 2773 | * so we save it in case there is just 0x0000 0x0000 on the |
2774 | * device we want to check. | ||
2558 | */ | 2775 | */ |
2559 | if (dev->subsystem_vendor != 0x0000U) { | 2776 | if (dev->subsystem_vendor != 0x0000U) { |
2560 | ss_vendor = dev->subsystem_vendor; | 2777 | ss_vendor = dev->subsystem_vendor; |
@@ -2564,13 +2781,20 @@ static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, | |||
2564 | for( ; conf->subvendor; conf++) { | 2781 | for( ; conf->subvendor; conf++) { |
2565 | if(conf->vendor == dev->vendor && | 2782 | if(conf->vendor == dev->vendor && |
2566 | conf->device == dev->device && | 2783 | conf->device == dev->device && |
2567 | conf->subvendor == ss_vendor && /* Sometimes these are cached values */ | 2784 | conf->subvendor == ss_vendor && |
2568 | (conf->subdevice == ss_device || conf->subdevice == 0xffff)) { | 2785 | /* Sometimes these are cached values */ |
2569 | struct smsc_ircc_subsystem_configuration tmpconf; | 2786 | (conf->subdevice == ss_device || |
2787 | conf->subdevice == 0xffff)) { | ||
2788 | struct smsc_ircc_subsystem_configuration | ||
2789 | tmpconf; | ||
2570 | 2790 | ||
2571 | memcpy(&tmpconf, conf, sizeof(struct smsc_ircc_subsystem_configuration)); | 2791 | memcpy(&tmpconf, conf, |
2792 | sizeof(struct smsc_ircc_subsystem_configuration)); | ||
2572 | 2793 | ||
2573 | /* Override the default values with anything passed in as parameter */ | 2794 | /* |
2795 | * Override the default values with anything | ||
2796 | * passed in as parameter | ||
2797 | */ | ||
2574 | if (ircc_cfg != 0) | 2798 | if (ircc_cfg != 0) |
2575 | tmpconf.cfg_base = ircc_cfg; | 2799 | tmpconf.cfg_base = ircc_cfg; |
2576 | if (ircc_fir != 0) | 2800 | if (ircc_fir != 0) |