diff options
| -rw-r--r-- | drivers/staging/comedi/drivers/s626.c | 169 |
1 files changed, 88 insertions, 81 deletions
diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 6f1705ba60e2..e1d10f366c2f 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c | |||
| @@ -2461,83 +2461,80 @@ static void s626_initialize(struct comedi_device *dev) | |||
| 2461 | uint16_t chan; | 2461 | uint16_t chan; |
| 2462 | int i; | 2462 | int i; |
| 2463 | 2463 | ||
| 2464 | /* enab DEBI and audio pins, enable I2C interface. */ | 2464 | /* Enable DEBI and audio pins, enable I2C interface */ |
| 2465 | MC_ENABLE(P_MC1, MC1_DEBI | MC1_AUDIO | MC1_I2C); | 2465 | MC_ENABLE(P_MC1, MC1_DEBI | MC1_AUDIO | MC1_I2C); |
| 2466 | /* Configure DEBI operating mode. */ | 2466 | |
| 2467 | WR7146(P_DEBICFG, DEBI_CFG_SLAVE16 /* Local bus is 16 */ | 2467 | /* |
| 2468 | /* bits wide. */ | 2468 | * Configure DEBI operating mode |
| 2469 | | (DEBI_TOUT << DEBI_CFG_TOUT_BIT) | 2469 | * |
| 2470 | 2470 | * Local bus is 16 bits wide | |
| 2471 | /* Declare DEBI */ | 2471 | * Declare DEBI transfer timeout interval |
| 2472 | /* transfer timeout */ | 2472 | * Set up byte lane steering |
| 2473 | /* interval. */ | 2473 | * Intel-compatible local bus (DEBI never times out) |
| 2474 | |DEBI_SWAP /* Set up byte lane */ | 2474 | */ |
| 2475 | /* steering. */ | 2475 | WR7146(P_DEBICFG, DEBI_CFG_SLAVE16 | |
| 2476 | | DEBI_CFG_INTEL); /* Intel-compatible */ | 2476 | (DEBI_TOUT << DEBI_CFG_TOUT_BIT) | |
| 2477 | /* local bus (DEBI */ | 2477 | DEBI_SWAP | DEBI_CFG_INTEL); |
| 2478 | /* never times out). */ | 2478 | |
| 2479 | 2479 | /* Disable MMU paging */ | |
| 2480 | /* DEBI INIT S626 WR7146( P_DEBICFG, DEBI_CFG_INTEL | DEBI_CFG_TOQ */ | 2480 | WR7146(P_DEBIPAGE, DEBI_PAGE_DISABLE); |
| 2481 | /* | DEBI_CFG_INCQ| DEBI_CFG_16Q); //end */ | 2481 | |
| 2482 | 2482 | /* Init GPIO so that ADC Start* is negated */ | |
| 2483 | /* Paging is disabled. */ | ||
| 2484 | WR7146(P_DEBIPAGE, DEBI_PAGE_DISABLE); /* Disable MMU paging. */ | ||
| 2485 | |||
| 2486 | /* Init GPIO so that ADC Start* is negated. */ | ||
| 2487 | WR7146(P_GPIO, GPIO_BASE | GPIO1_HI); | 2483 | WR7146(P_GPIO, GPIO_BASE | GPIO1_HI); |
| 2488 | 2484 | ||
| 2489 | /* I2C device address for onboard eeprom (revb) */ | 2485 | /* I2C device address for onboard eeprom (revb) */ |
| 2490 | devpriv->I2CAdrs = 0xA0; | 2486 | devpriv->I2CAdrs = 0xA0; |
| 2491 | 2487 | ||
| 2492 | /* Issue an I2C ABORT command to halt any I2C operation in */ | 2488 | /* |
| 2493 | /* progress and reset BUSY flag. */ | 2489 | * Issue an I2C ABORT command to halt any I2C |
| 2490 | * operation in progress and reset BUSY flag. | ||
| 2491 | */ | ||
| 2494 | WR7146(P_I2CSTAT, I2C_CLKSEL | I2C_ABORT); | 2492 | WR7146(P_I2CSTAT, I2C_CLKSEL | I2C_ABORT); |
| 2495 | /* Write I2C control: abort any I2C activity. */ | ||
| 2496 | MC_ENABLE(P_MC2, MC2_UPLD_IIC); | 2493 | MC_ENABLE(P_MC2, MC2_UPLD_IIC); |
| 2497 | /* Invoke command upload */ | ||
| 2498 | while ((RR7146(P_MC2) & MC2_UPLD_IIC) == 0) | 2494 | while ((RR7146(P_MC2) & MC2_UPLD_IIC) == 0) |
| 2499 | ; | 2495 | ; |
| 2500 | /* and wait for upload to complete. */ | ||
| 2501 | 2496 | ||
| 2502 | /* Per SAA7146 data sheet, write to STATUS reg twice to | 2497 | /* |
| 2503 | * reset all I2C error flags. */ | 2498 | * Per SAA7146 data sheet, write to STATUS |
| 2499 | * reg twice to reset all I2C error flags. | ||
| 2500 | */ | ||
| 2504 | for (i = 0; i < 2; i++) { | 2501 | for (i = 0; i < 2; i++) { |
| 2505 | WR7146(P_I2CSTAT, I2C_CLKSEL); | 2502 | WR7146(P_I2CSTAT, I2C_CLKSEL); |
| 2506 | /* Write I2C control: reset error flags. */ | 2503 | MC_ENABLE(P_MC2, MC2_UPLD_IIC); |
| 2507 | MC_ENABLE(P_MC2, MC2_UPLD_IIC); /* Invoke command upload */ | ||
| 2508 | while (!MC_TEST(P_MC2, MC2_UPLD_IIC)) | 2504 | while (!MC_TEST(P_MC2, MC2_UPLD_IIC)) |
| 2509 | ; | 2505 | ; |
| 2510 | /* and wait for upload to complete. */ | ||
| 2511 | } | 2506 | } |
| 2512 | 2507 | ||
| 2513 | /* Init audio interface functional attributes: set DAC/ADC | 2508 | /* |
| 2509 | * Init audio interface functional attributes: set DAC/ADC | ||
| 2514 | * serial clock rates, invert DAC serial clock so that | 2510 | * serial clock rates, invert DAC serial clock so that |
| 2515 | * DAC data setup times are satisfied, enable DAC serial | 2511 | * DAC data setup times are satisfied, enable DAC serial |
| 2516 | * clock out. | 2512 | * clock out. |
| 2517 | */ | 2513 | */ |
| 2518 | |||
| 2519 | WR7146(P_ACON2, ACON2_INIT); | 2514 | WR7146(P_ACON2, ACON2_INIT); |
| 2520 | 2515 | ||
| 2521 | /* Set up TSL1 slot list, which is used to control the | 2516 | /* |
| 2517 | * Set up TSL1 slot list, which is used to control the | ||
| 2522 | * accumulation of ADC data: RSD1 = shift data in on SD1. | 2518 | * accumulation of ADC data: RSD1 = shift data in on SD1. |
| 2523 | * SIB_A1 = store data uint8_t at next available location in | 2519 | * SIB_A1 = store data uint8_t at next available location |
| 2524 | * FB BUFFER1 register. */ | 2520 | * in FB BUFFER1 register. |
| 2521 | */ | ||
| 2525 | WR7146(P_TSL1, RSD1 | SIB_A1); | 2522 | WR7146(P_TSL1, RSD1 | SIB_A1); |
| 2526 | /* Fetch ADC high data uint8_t. */ | ||
| 2527 | WR7146(P_TSL1 + 4, RSD1 | SIB_A1 | EOS); | 2523 | WR7146(P_TSL1 + 4, RSD1 | SIB_A1 | EOS); |
| 2528 | /* Fetch ADC low data uint8_t; end of TSL1. */ | ||
| 2529 | 2524 | ||
| 2530 | /* enab TSL1 slot list so that it executes all the time. */ | 2525 | /* Enable TSL1 slot list so that it executes all the time */ |
| 2531 | WR7146(P_ACON1, ACON1_ADCSTART); | 2526 | WR7146(P_ACON1, ACON1_ADCSTART); |
| 2532 | 2527 | ||
| 2533 | /* Initialize RPS registers used for ADC. */ | 2528 | /* |
| 2534 | 2529 | * Initialize RPS registers used for ADC | |
| 2535 | /* Physical start of RPS program. */ | 2530 | */ |
| 2536 | WR7146(P_RPSADDR1, (uint32_t) devpriv->RPSBuf.PhysicalBase); | ||
| 2537 | 2531 | ||
| 2532 | /* Physical start of RPS program */ | ||
| 2533 | WR7146(P_RPSADDR1, (uint32_t)devpriv->RPSBuf.PhysicalBase); | ||
| 2534 | /* RPS program performs no explicit mem writes */ | ||
| 2538 | WR7146(P_RPSPAGE1, 0); | 2535 | WR7146(P_RPSPAGE1, 0); |
| 2539 | /* RPS program performs no explicit mem writes. */ | 2536 | /* Disable RPS timeouts */ |
| 2540 | WR7146(P_RPS1_TOUT, 0); /* Disable RPS timeouts. */ | 2537 | WR7146(P_RPS1_TOUT, 0); |
| 2541 | 2538 | ||
| 2542 | #if 0 | 2539 | #if 0 |
| 2543 | /* | 2540 | /* |
| @@ -2584,39 +2581,45 @@ static void s626_initialize(struct comedi_device *dev) | |||
| 2584 | } | 2581 | } |
| 2585 | #endif /* SAA7146 BUG WORKAROUND */ | 2582 | #endif /* SAA7146 BUG WORKAROUND */ |
| 2586 | 2583 | ||
| 2587 | /* end initADC */ | 2584 | /* |
| 2588 | 2585 | * Initialize the DAC interface | |
| 2589 | /* init the DAC interface */ | 2586 | */ |
| 2590 | 2587 | ||
| 2591 | /* Init Audio2's output DMAC attributes: burst length = 1 | 2588 | /* |
| 2592 | * DWORD, threshold = 1 DWORD. | 2589 | * Init Audio2's output DMAC attributes: |
| 2590 | * burst length = 1 DWORD | ||
| 2591 | * threshold = 1 DWORD. | ||
| 2593 | */ | 2592 | */ |
| 2594 | WR7146(P_PCI_BT_A, 0); | 2593 | WR7146(P_PCI_BT_A, 0); |
| 2595 | 2594 | ||
| 2596 | /* Init Audio2's output DMA physical addresses. The protection | 2595 | /* |
| 2596 | * Init Audio2's output DMA physical addresses. The protection | ||
| 2597 | * address is set to 1 DWORD past the base address so that a | 2597 | * address is set to 1 DWORD past the base address so that a |
| 2598 | * single DWORD will be transferred each time a DMA transfer is | 2598 | * single DWORD will be transferred each time a DMA transfer is |
| 2599 | * enabled. */ | 2599 | * enabled. |
| 2600 | 2600 | */ | |
| 2601 | pPhysBuf = devpriv->ANABuf.PhysicalBase + | 2601 | pPhysBuf = devpriv->ANABuf.PhysicalBase + |
| 2602 | (DAC_WDMABUF_OS * sizeof(uint32_t)); | 2602 | (DAC_WDMABUF_OS * sizeof(uint32_t)); |
| 2603 | WR7146(P_BASEA2_OUT, (uint32_t) pPhysBuf); | ||
| 2604 | WR7146(P_PROTA2_OUT, (uint32_t) (pPhysBuf + sizeof(uint32_t))); | ||
| 2603 | 2605 | ||
| 2604 | WR7146(P_BASEA2_OUT, (uint32_t) pPhysBuf); /* Buffer base adrs. */ | 2606 | /* |
| 2605 | WR7146(P_PROTA2_OUT, (uint32_t) (pPhysBuf + sizeof(uint32_t))); /* Protection address. */ | 2607 | * Cache Audio2's output DMA buffer logical address. This is |
| 2606 | 2608 | * where DAC data is buffered for A2 output DMA transfers. | |
| 2607 | /* Cache Audio2's output DMA buffer logical address. This is | 2609 | */ |
| 2608 | * where DAC data is buffered for A2 output DMA transfers. */ | ||
| 2609 | devpriv->pDacWBuf = (uint32_t *)devpriv->ANABuf.LogicalBase + | 2610 | devpriv->pDacWBuf = (uint32_t *)devpriv->ANABuf.LogicalBase + |
| 2610 | DAC_WDMABUF_OS; | 2611 | DAC_WDMABUF_OS; |
| 2611 | 2612 | ||
| 2612 | /* Audio2's output channels does not use paging. The protection | 2613 | /* |
| 2613 | * violation handling bit is set so that the DMAC will | 2614 | * Audio2's output channels does not use paging. The |
| 2614 | * automatically halt and its PCI address pointer will be reset | 2615 | * protection violation handling bit is set so that the |
| 2615 | * when the protection address is reached. */ | 2616 | * DMAC will automatically halt and its PCI address pointer |
| 2616 | 2617 | * will be reset when the protection address is reached. | |
| 2618 | */ | ||
| 2617 | WR7146(P_PAGEA2_OUT, 8); | 2619 | WR7146(P_PAGEA2_OUT, 8); |
| 2618 | 2620 | ||
| 2619 | /* Initialize time slot list 2 (TSL2), which is used to control | 2621 | /* |
| 2622 | * Initialize time slot list 2 (TSL2), which is used to control | ||
| 2620 | * the clock generation for and serialization of data to be sent | 2623 | * the clock generation for and serialization of data to be sent |
| 2621 | * to the DAC devices. Slot 0 is a NOP that is used to trap TSL | 2624 | * to the DAC devices. Slot 0 is a NOP that is used to trap TSL |
| 2622 | * execution; this permits other slots to be safely modified | 2625 | * execution; this permits other slots to be safely modified |
| @@ -2627,48 +2630,52 @@ static void s626_initialize(struct comedi_device *dev) | |||
| 2627 | * not yet finished executing. | 2630 | * not yet finished executing. |
| 2628 | */ | 2631 | */ |
| 2629 | 2632 | ||
| 2633 | /* Slot 0: Trap TSL execution, shift 0xFF into FB_BUFFER2 */ | ||
| 2630 | SETVECT(0, XSD2 | RSD3 | SIB_A2 | EOS); | 2634 | SETVECT(0, XSD2 | RSD3 | SIB_A2 | EOS); |
| 2631 | /* Slot 0: Trap TSL execution, shift 0xFF into FB_BUFFER2. */ | ||
| 2632 | 2635 | ||
| 2633 | /* Initialize slot 1, which is constant. Slot 1 causes a | 2636 | /* |
| 2637 | * Initialize slot 1, which is constant. Slot 1 causes a | ||
| 2634 | * DWORD to be transferred from audio channel 2's output FIFO | 2638 | * DWORD to be transferred from audio channel 2's output FIFO |
| 2635 | * to the FIFO's output buffer so that it can be serialized | 2639 | * to the FIFO's output buffer so that it can be serialized |
| 2636 | * and sent to the DAC during subsequent slots. All remaining | 2640 | * and sent to the DAC during subsequent slots. All remaining |
| 2637 | * slots are dynamically populated as required by the target | 2641 | * slots are dynamically populated as required by the target |
| 2638 | * DAC device. | 2642 | * DAC device. |
| 2639 | */ | 2643 | */ |
| 2644 | |||
| 2645 | /* Slot 1: Fetch DWORD from Audio2's output FIFO */ | ||
| 2640 | SETVECT(1, LF_A2); | 2646 | SETVECT(1, LF_A2); |
| 2641 | /* Slot 1: Fetch DWORD from Audio2's output FIFO. */ | ||
| 2642 | 2647 | ||
| 2643 | /* Start DAC's audio interface (TSL2) running. */ | 2648 | /* Start DAC's audio interface (TSL2) running */ |
| 2644 | WR7146(P_ACON1, ACON1_DACSTART); | 2649 | WR7146(P_ACON1, ACON1_DACSTART); |
| 2645 | 2650 | ||
| 2646 | /* end init DAC interface */ | 2651 | /* |
| 2647 | 2652 | * Init Trim DACs to calibrated values. Do it twice because the | |
| 2648 | /* Init Trim DACs to calibrated values. Do it twice because the | ||
| 2649 | * SAA7146 audio channel does not always reset properly and | 2653 | * SAA7146 audio channel does not always reset properly and |
| 2650 | * sometimes causes the first few TrimDAC writes to malfunction. | 2654 | * sometimes causes the first few TrimDAC writes to malfunction. |
| 2651 | */ | 2655 | */ |
| 2652 | |||
| 2653 | LoadTrimDACs(dev); | 2656 | LoadTrimDACs(dev); |
| 2654 | LoadTrimDACs(dev); /* Insurance. */ | 2657 | LoadTrimDACs(dev); |
| 2655 | 2658 | ||
| 2656 | /* Manually init all gate array hardware in case this is a soft | 2659 | /* |
| 2660 | * Manually init all gate array hardware in case this is a soft | ||
| 2657 | * reset (we have no way of determining whether this is a warm | 2661 | * reset (we have no way of determining whether this is a warm |
| 2658 | * or cold start). This is necessary because the gate array will | 2662 | * or cold start). This is necessary because the gate array will |
| 2659 | * reset only in response to a PCI hard reset; there is no soft | 2663 | * reset only in response to a PCI hard reset; there is no soft |
| 2660 | * reset function. */ | 2664 | * reset function. |
| 2665 | */ | ||
| 2661 | 2666 | ||
| 2662 | /* Init all DAC outputs to 0V and init all DAC setpoint and | 2667 | /* |
| 2668 | * Init all DAC outputs to 0V and init all DAC setpoint and | ||
| 2663 | * polarity images. | 2669 | * polarity images. |
| 2664 | */ | 2670 | */ |
| 2665 | for (chan = 0; chan < S626_DAC_CHANNELS; chan++) | 2671 | for (chan = 0; chan < S626_DAC_CHANNELS; chan++) |
| 2666 | SetDAC(dev, chan, 0); | 2672 | SetDAC(dev, chan, 0); |
| 2667 | 2673 | ||
| 2668 | /* Init counters. */ | 2674 | /* Init counters */ |
| 2669 | CountersInit(dev); | 2675 | CountersInit(dev); |
| 2670 | 2676 | ||
| 2671 | /* Without modifying the state of the Battery Backup enab, disable | 2677 | /* |
| 2678 | * Without modifying the state of the Battery Backup enab, disable | ||
| 2672 | * the watchdog timer, set DIO channels 0-5 to operate in the | 2679 | * the watchdog timer, set DIO channels 0-5 to operate in the |
| 2673 | * standard DIO (vs. counter overflow) mode, disable the battery | 2680 | * standard DIO (vs. counter overflow) mode, disable the battery |
| 2674 | * charger, and reset the watchdog interval selector to zero. | 2681 | * charger, and reset the watchdog interval selector to zero. |
| @@ -2676,11 +2683,11 @@ static void s626_initialize(struct comedi_device *dev) | |||
| 2676 | WriteMISC2(dev, (uint16_t)(DEBIread(dev, LP_RDMISC2) & | 2683 | WriteMISC2(dev, (uint16_t)(DEBIread(dev, LP_RDMISC2) & |
| 2677 | MISC2_BATT_ENABLE)); | 2684 | MISC2_BATT_ENABLE)); |
| 2678 | 2685 | ||
| 2679 | /* Initialize the digital I/O subsystem. */ | 2686 | /* Initialize the digital I/O subsystem */ |
| 2680 | s626_dio_init(dev); | 2687 | s626_dio_init(dev); |
| 2681 | 2688 | ||
| 2682 | /* enable interrupt test */ | 2689 | /* enable interrupt test */ |
| 2683 | /* writel(IRQ_GPIO3 | IRQ_RPS1,devpriv->base_addr+P_IER); */ | 2690 | /* writel(IRQ_GPIO3 | IRQ_RPS1, devpriv->base_addr + P_IER); */ |
| 2684 | } | 2691 | } |
| 2685 | 2692 | ||
| 2686 | static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) | 2693 | static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) |
