2 * Linux CAN-bus device driver.
3 * Written by Arnaud Westenberg email:arnaud@wanadoo.nl
4 * This software is released under the GPL-License.
5 * Version 0.7 6 Aug 2001
8 #include <linux/autoconf.h>
9 #if defined (CONFIG_MODVERSIONS) && !defined (MODVERSIONS)
13 #if defined (MODVERSIONS)
14 #include <linux/modversions.h>
17 #include <linux/sched.h>
18 #include <linux/version.h>
20 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,3,0))
21 #include <asm/spinlock.h>
23 #include <linux/spinlock.h>
26 #include "../include/main.h"
27 #include "../include/irq.h"
28 #include "../include/i82527.h"
29 #include "../include/sja1000.h"
31 void i82527_irq_rtr_handler(struct chip_t *chip, struct msgobj_t *msgobj,
32 struct rtr_id *rtr_search, unsigned long message_id);
33 void sja1000_irq_read_handler(struct chip_t *chip, struct msgobj_t *msgobj);
34 void sja1000_irq_write_handler(struct chip_t *chip, struct msgobj_t *msgobj);
36 /*struct candevice_t *device=NULL;
37 unsigned object=0,irq_register=0;
38 unsigned long msgbase=0;
39 struct canfifo_t *fifo=NULL;
40 unsigned long message_id=0;
41 struct rtr_id *rtr_search;
44 inline void i82527_irq_write_handler(struct chip_t *chip, struct msgobj_t *msgobj)
46 struct canfifo_t *fifo=msgobj->fifo;
47 unsigned long msgbase=msgobj->obj_base_addr;
48 void (*write_reg)(unsigned char data, unsigned long address);
49 unsigned (*read_reg)(unsigned long address);
50 write_reg=chip->hostdevice->hwspecops->write_register;
51 read_reg=chip->hostdevice->hwspecops->read_register;
53 (*write_reg)((MVAL_RES|TXIE_RES|RXIE_RES|INTPD_RES),msgbase+iMSGCTL0);
56 if (fifo->tx_readp >= fifo->buf_tx_entry + MAX_BUF_LENGTH)
57 fifo->tx_readp = fifo->buf_tx_entry;
58 if (fifo->tx_readp == fifo->tx_writep) { // Output buffer is empty
59 fifo->tx_in_progress = 0;
60 if (waitqueue_active(&fifo->writeq)) {
62 wake_up_interruptible(&fifo->writeq);
66 if (chip->chipspecops->pre_write_config(chip, msgobj, fifo->tx_readp)) {
67 if (waitqueue_active(&fifo->writeq)) {
69 wake_up_interruptible(&fifo->writeq);
73 if (chip->chipspecops->send_msg(chip, msgobj, fifo->tx_readp)) {
74 if (waitqueue_active(&fifo->writeq)) {
76 wake_up_interruptible(&fifo->writeq);
82 inline void i82527_irq_read_handler(struct chip_t *chip, struct msgobj_t *msgobj,
83 unsigned long message_id)
86 struct canfifo_t *fifo=msgobj->fifo;
87 unsigned long msgbase=msgobj->obj_base_addr;
88 void (*write_reg)(unsigned char data, unsigned long address);
89 unsigned (*read_reg)(unsigned long address);
90 write_reg=chip->hostdevice->hwspecops->write_register;
91 read_reg=chip->hostdevice->hwspecops->read_register;
94 (*write_reg)((RMPD_RES|TXRQ_RES|MLST_RES|NEWD_RES), msgbase +
96 (*write_reg)((MVAL_SET|TXIE_RES|RXIE_SET|INTPD_RES), msgbase +
99 fifo->rx_writep->length =((*read_reg)(msgbase+iMSGCFG) & 0xf0) >> 4;
100 fifo->rx_writep->id = message_id;
101 for (i=0; i < fifo->rx_writep->length; i++)
102 fifo->rx_writep->data[i] = (*read_reg)(msgbase+iMSGDAT0+i);
104 //FIXME: Add buffer overflow check, currently it's silently over written!
107 if (fifo->rx_writep >= fifo->buf_rx_entry + MAX_BUF_LENGTH)
108 fifo->rx_writep = fifo->buf_rx_entry;
110 if (!((tmp=(*read_reg)(msgbase + iMSGCTL1)) & NEWD_SET)) {
115 CANMSG("Message lost!\n");
118 if (waitqueue_active(&fifo->readq)) {
119 wake_up_interruptible(&fifo->readq);
123 void i82527_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
125 int id0=0, id1=0, id2=0, id3=0;
127 unsigned irq_register;
129 struct chip_t *chip=(struct chip_t *)dev_id;
130 struct msgobj_t *msgobj;
131 unsigned long msgbase;
132 unsigned long message_id;
133 struct rtr_id *rtr_search;
134 void (*write_reg)(unsigned char data, unsigned long address);
135 unsigned (*read_reg)(unsigned long address);
136 write_reg=chip->hostdevice->hwspecops->write_register;
137 read_reg=chip->hostdevice->hwspecops->read_register;
139 /*put_reg=device->hwspecops->write_register;*/
140 /*get_reg=device->hwspecops->read_register;*/
142 if ( (chip->flags & SEGMENTED) != 0)
143 irq_register = can_read_reg(chip, iIRQ+SPACING);
145 irq_register = can_read_reg(chip, iIRQ);
147 while (irq_register) {
149 if (irq_register == 0x01) {
150 DEBUGMSG("Status register: 0x%x\n",can_read_reg(chip, iSTAT));
154 if (irq_register == 0x02)
157 object = irq_register-3;
159 msgobj=chip->msgobj[object];
160 msgbase=msgobj->obj_base_addr;
162 if ((*read_reg)(msgbase+iMSGCFG) & MCFG_DIR) {
163 i82527_irq_write_handler(chip, msgobj);
168 id0=(*read_reg)(msgbase+iMSGID3);
169 id1=(*read_reg)(msgbase+iMSGID2)<<8;
170 id2=(*read_reg)(msgbase+iMSGID1)<<16;
171 id3=(*read_reg)(msgbase+iMSGID0)<<24;
172 message_id=(id0|id1|id2|id3)>>3;
175 id0=(*read_reg)(msgbase+iMSGID1);
176 id1=(*read_reg)(msgbase+iMSGID0)<<8;
177 message_id=(id0|id1)>>5;
180 spin_lock(&hardware_p->rtr_lock);
181 rtr_search=hardware_p->rtr_queue;
182 while (rtr_search != NULL) {
183 if (rtr_search->id == message_id)
185 rtr_search=rtr_search->next;
187 spin_unlock(&hardware_p->rtr_lock);
188 if ((rtr_search!=NULL) && (rtr_search->id==message_id))
189 i82527_irq_rtr_handler(chip, msgobj, rtr_search, message_id);
191 i82527_irq_read_handler(chip, msgobj, message_id);
194 if ( (chip->flags & SEGMENTED) != 0)
195 irq_register=can_read_reg(chip, iIRQ+SPACING);
197 irq_register=can_read_reg(chip, iIRQ);
202 void i82527_irq_rtr_handler(struct chip_t *chip, struct msgobj_t *msgobj,
203 struct rtr_id *rtr_search, unsigned long message_id)
206 unsigned long msgbase=msgobj->obj_base_addr;
207 void (*write_reg)(unsigned char data, unsigned long address);
208 unsigned (*read_reg)(unsigned long address);
209 write_reg=chip->hostdevice->hwspecops->write_register;
210 read_reg=chip->hostdevice->hwspecops->read_register;
212 (*write_reg)((MVAL_RES|TXIE_RES|RXIE_RES|INTPD_RES),msgbase + iMSGCTL0);
213 (*write_reg)((RMPD_RES|TXRQ_RES|MLST_RES|NEWD_RES),msgbase + iMSGCTL1);
215 spin_lock(&hardware_p->rtr_lock);
217 rtr_search->rtr_message->id=message_id;
218 rtr_search->rtr_message->length=((*read_reg)(msgbase + iMSGCFG) & 0xf0)>>4;
219 for (i=0; i<rtr_search->rtr_message->length; i++)
220 rtr_search->rtr_message->data[i]=(*read_reg)(msgbase+iMSGDAT0+i);
222 spin_unlock(&hardware_p->rtr_lock);
224 if (waitqueue_active(&rtr_search->rtr_wq))
225 wake_up_interruptible(&rtr_search->rtr_wq);
228 void sja1000_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
230 unsigned irq_register;
231 struct chip_t *chip=(struct chip_t *)dev_id;
232 struct msgobj_t *msgobj;
233 struct canfifo_t *fifo;
235 irq_register=can_read_reg(chip, SJAIR);
236 // DEBUGMSG("sja1000_irq_handler: SJAIR:%02x\n",irq_register);
237 // DEBUGMSG("sja1000_irq_handler: SJASR:%02x\n",
238 // can_read_reg(chip, SJASR));
240 if ((irq_register & (IR_WUI|IR_DOI|IR_EI|IR_TI|IR_RI)) == 0)
243 msgobj=chip->msgobj[0];
246 if ((irq_register & IR_RI) != 0)
247 sja1000_irq_read_handler(chip, msgobj);
248 if ((irq_register & IR_TI) != 0)
249 sja1000_irq_write_handler(chip, msgobj);
250 if ((irq_register & (IR_EI|IR_DOI)) != 0) {
251 // Some error happened
252 // FIXME: chip should be brought to usable state. Transmission cancelled if in progress.
253 // Reset flag set to 0 if chip is already off the bus. Full state report
254 CANMSG("Error: status register: 0x%x irq_register: 0x%02x\n",
255 can_read_reg(chip, SJASR), irq_register);
256 chip->msgobj[0]->ret=-1;
257 if (waitqueue_active(&fifo->writeq))
258 wake_up_interruptible(&fifo->writeq);
259 if (waitqueue_active(&fifo->readq))
260 wake_up_interruptible(&fifo->readq);
266 void sja1000_irq_read_handler(struct chip_t *chip, struct msgobj_t *msgobj)
269 struct canfifo_t *fifo=msgobj->fifo;
272 id = can_read_reg(chip, SJARXID0) | (can_read_reg(chip, SJARXID1)<<8);
273 fifo->rx_writep->length = id & 0x0f;
274 fifo->rx_writep->flags = id&ID0_RTR ? MSG_RTR : 0;
275 fifo->rx_writep->timestamp = 0;
276 fifo->rx_writep->cob = 0;
277 fifo->rx_writep->id = id>>5;
279 for (i=0; i<fifo->rx_writep->length; i++)
280 fifo->rx_writep->data[i]=can_read_reg(chip, SJARXDAT0 + i);
282 can_write_reg(chip, CMR_RRB, SJACMR);
285 if (fifo->rx_writep >= fifo->buf_rx_entry + MAX_BUF_LENGTH)
286 fifo->rx_writep = fifo->buf_rx_entry;
288 } while(can_read_reg(chip, SJASR) & SR_RBS);
290 if (waitqueue_active(&fifo->readq))
291 wake_up_interruptible(&fifo->readq);
294 void sja1000_irq_write_handler(struct chip_t *chip, struct msgobj_t *msgobj)
296 struct canfifo_t *fifo=msgobj->fifo;
299 if (fifo->tx_readp >= fifo->buf_tx_entry + MAX_BUF_LENGTH)
300 fifo->tx_readp = fifo->buf_tx_entry;
301 if (fifo->tx_readp == fifo->tx_writep) { // Output buffer is empty
302 fifo->tx_in_progress = 0;
303 if (waitqueue_active(&fifo->writeq)) {
305 wake_up_interruptible(&fifo->writeq);
309 if (chip->chipspecops->pre_write_config(chip, msgobj, fifo->tx_readp)) {
310 if (waitqueue_active(&fifo->writeq)) {
312 wake_up_interruptible(&fifo->writeq);
316 if (chip->chipspecops->send_msg(chip, msgobj, fifo->tx_readp)) {
317 if (waitqueue_active(&fifo->writeq)) {
319 wake_up_interruptible(&fifo->writeq);
325 void dummy_irq_handler(int irq, void *dev_id, struct pt_regs *regs) {
326 CANMSG("dummy_irq_handler called irq %d \n", irq);