]> rtime.felk.cvut.cz Git - lincan.git/blobdiff - lincan/src/unican.c
Added support for Unicontrols PCI CAN card.
[lincan.git] / lincan / src / unican.c
index efc5ac276188294976bfabc658822bb714deb670..5cab054981ba72522f06d2b2db2697e4c2828873 100644 (file)
 #include "../include/unican_cl2.h"
 #include "../include/setup.h"
 
 #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)
 {
 
 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;
 }
        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*/