2 * Linux CAN-bus device driver.
3 * Written by Arnaud Westenberg email:arnaud@wanadoo.nl
4 * Rewritten for new CAN queues by Pavel Pisa - OCERA team member
5 * email:pisa@cmp.felk.cvut.cz
6 * This software is released under the GPL-License.
7 * Version lincan-0.3 17 Jun 2004
10 #include "../include/can.h"
11 #include "../include/can_sysdep.h"
12 #include "../include/main.h"
13 #include "../include/smartcan.h"
14 #include "../include/i82527.h"
17 unsigned long smartcan_base=0x0;
19 static can_spinlock_t smartcan_port_lock=SPIN_LOCK_UNLOCKED;
21 int smartcan_request_io(struct candevice_t *candev)
23 if (!can_request_io_region(candev->io_addr,0x04,DEVICE_NAME)) {
24 CANMSG("Unable to open port: 0x%lx\n",candev->io_addr);
27 DEBUGMSG("Registered IO-memory: 0x%lx - 0x%lx\n", candev->io_addr, candev->io_addr + 0x04 - 1);
32 int smartcan_release_io(struct candevice_t *candev)
34 can_release_io_region(candev->io_addr,0x04);
39 int smartcan_reset(struct candevice_t *candev)
43 DEBUGMSG("Resetting smartcan hardware ...\n");
44 outb(0x00,candev->res_addr);
47 outb(0x01,candev->res_addr);
49 outb(0x00,candev->res_addr);
51 /* Check hardware reset status */
53 outb(candev->io_addr+iCPU,candev->io_addr);
54 while ( (inb(candev->io_addr+1)&0x80) && (i<=15) ) {
59 CANMSG("Reset status timeout!\n");
60 CANMSG("Please check your hardware.\n");
64 DEBUGMSG("Chip0 reset status ok.\n");
69 int smartcan_init_hw_data(struct candevice_t *candev)
71 candev->res_addr=candev->io_addr+0x02;
72 candev->nr_82527_chips=1;
73 candev->nr_sja1000_chips=0;
74 candev->nr_all_chips=1;
79 int smartcan_init_chip_data(struct candevice_t *candev, int chipnr)
81 i82527_fill_chipspecops(candev->chip[chipnr]);
82 candev->chip[chipnr]->chip_base_addr=candev->io_addr;
83 candev->chip[chipnr]->clock = 16000000;
84 candev->chip[chipnr]->int_cpu_reg = iCPU_DSC;
85 candev->chip[chipnr]->int_clk_reg = iCLK_SL1;
86 candev->chip[chipnr]->int_bus_reg = iBUS_CBY;
87 candev->chip[chipnr]->sja_cdr_reg = 0;
88 candev->chip[chipnr]->sja_ocr_reg = 0;
89 smartcan_irq=candev->chip[chipnr]->chip_irq;
90 smartcan_base=candev->chip[chipnr]->chip_base_addr;
95 int smartcan_init_obj_data(struct canchip_t *chip, int objnr)
97 chip->msgobj[objnr]->obj_base_addr=(objnr+1)*0x10;
103 void smartcan_write_register(unsigned data, unsigned long address)
105 can_spin_irqflags_t flags;
106 can_spin_lock_irqsave(&smartcan_port_lock,flags);
107 outb(address-smartcan_base,smartcan_base);
108 outb(data,smartcan_base+1);
109 can_spin_unlock_irqrestore(&smartcan_port_lock,flags);
112 unsigned smartcan_read_register(unsigned long address)
115 can_spin_irqflags_t flags;
116 can_spin_lock_irqsave(&smartcan_port_lock,flags);
117 outb(address-smartcan_base,smartcan_base);
118 ret=inb(smartcan_base+1);
119 can_spin_unlock_irqrestore(&smartcan_port_lock,flags);
123 int smartcan_program_irq(struct candevice_t *candev)
125 CANMSG("The 'smartcan' card doesn't have programmable interrupts\n");
129 /* !!! Don't change this function !!! */
130 int smartcan_register(struct hwspecops_t *hwspecops)
132 hwspecops->request_io = smartcan_request_io;
133 hwspecops->release_io = smartcan_release_io;
134 hwspecops->reset = smartcan_reset;
135 hwspecops->init_hw_data = smartcan_init_hw_data;
136 hwspecops->init_chip_data = smartcan_init_chip_data;
137 hwspecops->init_obj_data = smartcan_init_obj_data;
138 hwspecops->write_register = smartcan_write_register;
139 hwspecops->read_register = smartcan_read_register;
140 hwspecops->program_irq = smartcan_program_irq;