X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/blobdiff_plain/92b76dca553a98a228f368f8ff6eedc25e33b870..d659fb1c5ce646e10820cfd349d8a4220d1ee67d:/lincan/src/unican.c diff --git a/lincan/src/unican.c b/lincan/src/unican.c index efc5ac2..5cab054 100644 --- a/lincan/src/unican.c +++ b/lincan/src/unican.c @@ -12,10 +12,8 @@ #include "../include/unican_cl2.h" #include "../include/setup.h" -#ifdef CAN_WITH_RTL - -#endif /*CAN_WITH_RTL*/ - +#define UNICAN_PCI_VENDOR 0xFA3C +#define UNICAN_PCI_ID 0x0101 static void unican_delay(long msdelay) { @@ -848,3 +846,121 @@ int unican_register(struct hwspecops_t *hwspecops) hwspecops->program_irq = unican_program_irq; return 0; } + + +/* Unicontrols PCI board specific functions */ + +#ifdef CAN_ENABLE_PCI_SUPPORT + +int unican_pci_request_io(struct candevice_t *candev) +{ + #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21)) + if(pci_request_region(candev->sysdevptr.pcidev, 0, "unican_pci") != 0){ + CANMSG("Request of Unican PCI range failed\n"); + return -ENODEV; + } + #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/ + if(pci_request_regions(candev->sysdevptr.pcidev, "kv_pcican") != 0){ + CANMSG("Request of Unican PCI range failed\n"); + return -ENODEV; + } + #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/ + + return 0; +} + + +int unican_pci_release_io(struct candevice_t *candev) +{ + #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21)) + pci_release_region(candev->sysdevptr.pcidev, 0); + #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/ + pci_release_regions(candev->sysdevptr.pcidev); + #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/ + return 0; +} + + +int unican_pci_init_hw_data(struct candevice_t *candev) +{ + struct pci_dev *pcidev = NULL; + + do { + pcidev = pci_find_device(UNICAN_PCI_VENDOR, UNICAN_PCI_ID, pcidev); + if(pcidev == NULL) return -ENODEV; + } while(can_check_dev_taken(pcidev)); + + if (pci_enable_device (pcidev)){ + printk(KERN_CRIT "Setup of Unican PCI failed\n"); + return -EIO; + } + candev->sysdevptr.pcidev=pcidev; + + if(!(pci_resource_flags(pcidev,0)&IORESOURCE_MEM)){ + printk(KERN_CRIT "Unican PCI region 0 is not MEM\n"); + return -EIO; + } + candev->dev_base_addr=pci_resource_start(pcidev,0); /*S5920*/ + candev->io_addr=candev->dev_base_addr; + candev->res_addr=candev->dev_base_addr; + + /*candev->flags |= CANDEV_PROGRAMMABLE_IRQ;*/ + + candev->nr_82527_chips=0; + candev->nr_sja1000_chips=0; + candev->nr_all_chips=1; + + return 0; +} + + +int unican_pci_init_chip_data(struct candevice_t *candev, int chipnr) +{ + int ret; + candev->chip[chipnr]->chip_irq=candev->sysdevptr.pcidev->irq; + ret = unican_pci_init_chip_data(candev, chipnr); + candev->chip[chipnr]->flags |= CHIP_IRQ_PCI; + return ret; +} + +int unican_pci_register(struct hwspecops_t *hwspecops) +{ + hwspecops->request_io = unican_pci_request_io; + hwspecops->release_io = unican_pci_release_io; + hwspecops->reset = unican_reset; + hwspecops->init_hw_data = unican_pci_init_hw_data; + hwspecops->init_chip_data = unican_pci_init_chip_data; + hwspecops->init_obj_data = unican_init_obj_data; + hwspecops->write_register = NULL; + hwspecops->read_register = NULL; + hwspecops->program_irq = unican_program_irq; + return 0; +} + +#endif /*CAN_ENABLE_PCI_SUPPORT*/ + +#ifdef CAN_ENABLE_VME_SUPPORT + +int unican_vme_reset(struct candevice_t *candev) +{ + struct chip_t *chip = candev->chip[0]; + writew(chip->chip_irq,chip->chip_base_addr+CL2_VME_INT_VECTOR); + return unican_reset(candev); +} + + +int unican_vme_register(struct hwspecops_t *hwspecops) +{ + hwspecops->request_io = unican_request_io; + hwspecops->release_io = unican_release_io; + hwspecops->reset = unican_vme_reset; + hwspecops->init_hw_data = unican_init_hw_data; + hwspecops->init_chip_data = unican_init_chip_data; + hwspecops->init_obj_data = unican_init_obj_data; + hwspecops->write_register = NULL; + hwspecops->read_register = NULL; + hwspecops->program_irq = unican_program_irq; + return 0; +} + +#endif /*CAN_ENABLE_VME_SUPPORT*/