1 /**************************************************************************/
2 /* File: i82527.c - Intel i82527 CAN controller support */
4 /* LinCAN - (Not only) Linux CAN bus driver */
5 /* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
6 /* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
7 /* Funded by OCERA and FRESCOR IST projects */
8 /* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl> */
10 /* LinCAN is free software; you can redistribute it and/or modify it */
11 /* under terms of the GNU General Public License as published by the */
12 /* Free Software Foundation; either version 2, or (at your option) any */
13 /* later version. LinCAN is distributed in the hope that it will be */
14 /* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
15 /* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
16 /* General Public License for more details. You should have received a */
17 /* copy of the GNU General Public License along with LinCAN; see file */
18 /* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
19 /* Cambridge, MA 02139, USA. */
21 /* To allow use of LinCAN in the compact embedded systems firmware */
22 /* and RT-executives (RTEMS for example), main authors agree with next */
23 /* special exception: */
25 /* Including LinCAN header files in a file, instantiating LinCAN generics */
26 /* or templates, or linking other files with LinCAN objects to produce */
27 /* an application image/executable, does not by itself cause the */
28 /* resulting application image/executable to be covered by */
29 /* the GNU General Public License. */
30 /* This exception does not however invalidate any other reasons */
31 /* why the executable file might be covered by the GNU Public License. */
32 /* Publication of enhanced or derived LinCAN files is required although. */
33 /**************************************************************************/
35 #include "../include/can.h"
36 #include "../include/can_sysdep.h"
37 #include "../include/main.h"
38 #include "../include/i82527.h"
40 void i82527_irq_rtr_handler(struct canchip_t *chip, struct msgobj_t *obj,
41 struct rtr_id *rtr_search, unsigned long message_id);
48 /* helper functions for segmented cards read and write configuration and status registers
51 void i82527_seg_write_reg(const struct canchip_t *chip, unsigned char data, unsigned address)
53 if((address > 0xf) && (chip->flags & CHIP_SEGMENTED))
54 canobj_write_reg(chip, chip->msgobj[(address>>4)-1],data, address & 0xf);
56 can_write_reg(chip, data, address);
59 unsigned i82527_seg_read_reg(const struct canchip_t *chip, unsigned address)
61 if((address > 0xf) && (chip->flags & CHIP_SEGMENTED))
62 return canobj_read_reg(chip, chip->msgobj[(address>>4)-1], address & 0xf);
64 return can_read_reg(chip, address);
67 int i82527_enable_configuration(struct canchip_t *chip)
69 unsigned short flags=0;
71 flags = can_read_reg(chip, iCTL) & (iCTL_IE|iCTL_SIE|iCTL_EIE);
72 can_write_reg(chip, flags|iCTL_CCE, iCTL);
77 int i82527_disable_configuration(struct canchip_t *chip)
79 unsigned short flags=0;
81 flags = can_read_reg(chip, iCTL) & (iCTL_IE|iCTL_SIE|iCTL_EIE);
82 can_write_reg(chip, flags, iCTL);
87 int i82527_chip_config(struct canchip_t *chip)
89 can_write_reg(chip,chip->int_cpu_reg,iCPU); // Configure cpu interface
90 can_write_reg(chip,(iCTL_CCE|iCTL_INI),iCTL); // Enable configuration
91 i82527_seg_write_reg(chip,chip->int_clk_reg,iCLK); // Set clock out slew rates
92 i82527_seg_write_reg(chip,chip->int_bus_reg,iBUS); /* Bus configuration */
93 can_write_reg(chip,0x00,iSTAT); /* Clear error status register */
95 /* Check if we can at least read back some arbitrary data from the
96 * card. If we can not, the card is not properly configured!
98 canobj_write_reg(chip,chip->msgobj[1],0x25,iMSGDAT1);
99 canobj_write_reg(chip,chip->msgobj[2],0x52,iMSGDAT3);
100 canobj_write_reg(chip,chip->msgobj[10],0xc3,iMSGDAT6);
101 if ( (canobj_read_reg(chip,chip->msgobj[1],iMSGDAT1) != 0x25) ||
102 (canobj_read_reg(chip,chip->msgobj[2],iMSGDAT3) != 0x52) ||
103 (canobj_read_reg(chip,chip->msgobj[10],iMSGDAT6) != 0xc3) ) {
104 CANMSG("Could not read back from the hardware.\n");
105 CANMSG("This probably means that your hardware is not correctly configured!\n");
109 DEBUGMSG("Could read back, hardware is probably configured correctly\n");
111 if (chip->baudrate == 0)
112 chip->baudrate=1000000;
114 if (i82527_baud_rate(chip,chip->baudrate,chip->clock,0,75,0)) {
115 CANMSG("Error configuring baud rate\n");
118 if (i82527_standard_mask(chip,0x0000,stdmask)) {
119 CANMSG("Error configuring standard mask\n");
122 if (i82527_extended_mask(chip,0x00000000,extmask)) {
123 CANMSG("Error configuring extended mask\n");
126 if (i82527_message15_mask(chip,0x00000000,mo15mask)) {
127 CANMSG("Error configuring message 15 mask\n");
130 if (i82527_clear_objects(chip)) {
131 CANMSG("Error clearing message objects\n");
134 if (i82527_config_irqs(chip,iCTL_IE|iCTL_EIE)) { /* has been 0x0a */
135 CANMSG("Error configuring interrupts\n");
142 /* Set communication parameters.
143 * param rate baud rate in Hz
144 * param clock frequency of i82527 clock in Hz (ISA osc is 14318000)
145 * param sjw synchronization jump width (0-3) prescaled clock cycles
146 * param sampl_pt sample point in % (0-100) sets (TSEG1+2)/(TSEG1+TSEG2+3) ratio
147 * param flags fields BTR1_SAM, OCMODE, OCPOL, OCTP, OCTN, CLK_OFF, CBP
149 int i82527_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw,
150 int sampl_pt, int flags)
152 int best_error = 1000000000, error;
153 int best_tseg=0, best_brp=0, best_rate=0, brp=0;
154 int tseg=0, tseg1=0, tseg2=0;
156 if (i82527_enable_configuration(chip))
159 if(chip->int_cpu_reg & iCPU_DSC)
162 /* tseg even = round down, odd = round up */
163 for (tseg=(0+0+2)*2; tseg<=(MAX_TSEG2+MAX_TSEG1+2)*2+1; tseg++) {
164 brp = clock/((1+tseg/2)*rate)+tseg%2;
165 if (brp == 0 || brp > 64)
167 error = rate - clock/(brp*(1+tseg/2));
170 if (error <= best_error) {
174 best_rate = clock/(brp*(1+tseg/2));
177 if (best_error && (rate/best_error < 10)) {
178 CANMSG("baud rate %d is not possible with %d Hz clock\n",
180 CANMSG("%d bps. brp=%d, best_tseg=%d, tseg1=%d, tseg2=%d\n",
181 best_rate, best_brp, best_tseg, tseg1, tseg2);
184 tseg2 = best_tseg-(sampl_pt*(best_tseg+1))/100;
187 if (tseg2 > MAX_TSEG2)
190 tseg1 = best_tseg-tseg2-2;
191 if (tseg1>MAX_TSEG1) {
193 tseg2 = best_tseg-tseg1-2;
196 DEBUGMSG("Setting %d bps.\n", best_rate);
197 DEBUGMSG("brp=%d, best_tseg=%d, tseg1=%d, tseg2=%d, sampl_pt=%d\n",
198 best_brp, best_tseg, tseg1, tseg2,
199 (100*(best_tseg-tseg2)/(best_tseg+1)));
202 i82527_seg_write_reg(chip, sjw<<6 | best_brp, iBT0);
203 can_write_reg(chip, ((flags & BTR1_SAM) != 0)<<7 | tseg2<<4 | tseg1,
205 DEBUGMSG("Writing 0x%x to iBT0\n",(sjw<<6 | best_brp));
206 DEBUGMSG("Writing 0x%x to iBT1\n",((flags & BTR1_SAM) != 0)<<7 |
209 i82527_disable_configuration(chip);
214 int i82527_standard_mask(struct canchip_t *chip, unsigned short code, unsigned short mask)
216 unsigned char mask0, mask1;
218 mask0 = (unsigned char) (mask >> 3);
219 mask1 = (unsigned char) (mask << 5);
221 can_write_reg(chip,mask0,iSGM0);
222 can_write_reg(chip,mask1,iSGM1);
224 DEBUGMSG("Setting standard mask to 0x%lx\n",(unsigned long)mask);
229 int i82527_extended_mask(struct canchip_t *chip, unsigned long code, unsigned long mask)
231 unsigned char mask0, mask1, mask2, mask3;
233 mask0 = (unsigned char) (mask >> 21);
234 mask1 = (unsigned char) (mask >> 13);
235 mask2 = (unsigned char) (mask >> 5);
236 mask3 = (unsigned char) (mask << 3);
238 can_write_reg(chip,mask0,iEGM0);
239 can_write_reg(chip,mask1,iEGM1);
240 can_write_reg(chip,mask2,iEGM2);
241 can_write_reg(chip,mask3,iEGM3);
243 DEBUGMSG("Setting extended mask to 0x%lx\n",(unsigned long)mask);
248 int i82527_message15_mask(struct canchip_t *chip, unsigned long code, unsigned long mask)
250 unsigned char mask0, mask1, mask2, mask3;
252 mask0 = (unsigned char) (mask >> 21);
253 mask1 = (unsigned char) (mask >> 13);
254 mask2 = (unsigned char) (mask >> 5);
255 mask3 = (unsigned char) (mask << 3);
257 can_write_reg(chip,mask0,i15M0);
258 can_write_reg(chip,mask1,i15M1);
259 can_write_reg(chip,mask2,i15M2);
260 can_write_reg(chip,mask3,i15M3);
262 DEBUGMSG("Setting message 15 mask to 0x%lx\n",mask);
269 int i82527_clear_objects(struct canchip_t *chip)
272 struct msgobj_t *obj;
274 DEBUGMSG("Cleared all message objects on chip\n");
276 for (i=0; i<chip->max_objects; i++) {
278 canobj_write_reg(chip,obj,(INTPD_RES|RXIE_RES|TXIE_RES|MVAL_RES),iMSGCTL0);
279 canobj_write_reg(chip,obj,(NEWD_RES|MLST_RES|TXRQ_RES|RMPD_RES), iMSGCTL1);
280 for (data=0x07; data<0x0f; data++)
281 canobj_write_reg(chip,obj,0x00,data);
282 for (id=2; id<6; id++) {
283 canobj_write_reg(chip,obj,0x00,id);
286 canobj_write_reg(chip,obj,0x00,iMSGCFG);
289 canobj_write_reg(chip,obj,MCFG_XTD,iMSGCFG);
293 DEBUGMSG("All message ID's set to standard\n");
295 DEBUGMSG("All message ID's set to extended\n");
300 int i82527_config_irqs(struct canchip_t *chip, short irqs)
302 can_write_reg(chip,irqs,iCTL);
303 DEBUGMSG("Configured hardware interrupt delivery\n");
307 int i82527_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj)
309 unsigned long id=obj->rx_preconfig_id;
311 can_msgobj_set_fl(obj,RX_MODE);
313 if (extended || can_msgobj_test_fl(obj,RX_MODE_EXT)) {
315 canobj_write_reg(chip,obj,id,iMSGID3);
316 canobj_write_reg(chip,obj,id>>8,iMSGID2);
317 canobj_write_reg(chip,obj,id>>16,iMSGID1);
318 canobj_write_reg(chip,obj,id>>24,iMSGID0);
319 canobj_write_reg(chip,obj,MCFG_XTD,iMSGCFG);
322 canobj_write_reg(chip,obj,id,iMSGID1);
323 canobj_write_reg(chip,obj,id>>8,iMSGID0);
324 canobj_write_reg(chip,obj,0x00,iMSGCFG);
327 canobj_write_reg(chip,obj,(NEWD_RES|MLST_RES|TXRQ_RES|RMPD_RES), iMSGCTL1);
328 canobj_write_reg(chip,obj,(MVAL_SET|TXIE_RES|RXIE_SET|INTPD_RES),iMSGCTL0);
330 DEBUGMSG("i82527_pre_read_config: configured obj at 0x%08lx\n",obj->obj_base_addr);
335 int i82527_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj,
336 struct canmsg_t *msg)
338 int i=0,id0=0,id1=0,id2=0,id3=0;
342 if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
344 can_msgobj_clear_fl(obj,RX_MODE);
346 canobj_write_reg(chip,obj,(MVAL_SET|TXIE_SET|RXIE_RES|INTPD_RES),iMSGCTL0);
347 canobj_write_reg(chip,obj,(RMPD_RES|TXRQ_RES|CPUU_SET|NEWD_RES),iMSGCTL1);
349 if (extended || (msg->flags&MSG_EXT)) {
350 canobj_write_reg(chip,obj,(len<<4)|(MCFG_DIR|MCFG_XTD),iMSGCFG);
351 id0 = (unsigned char) (msg->id<<3);
352 id1 = (unsigned char) (msg->id>>5);
353 id2 = (unsigned char) (msg->id>>13);
354 id3 = (unsigned char) (msg->id>>21);
355 canobj_write_reg(chip,obj,id0,iMSGID3);
356 canobj_write_reg(chip,obj,id1,iMSGID2);
357 canobj_write_reg(chip,obj,id2,iMSGID1);
358 canobj_write_reg(chip,obj,id3,iMSGID0);
361 canobj_write_reg(chip,obj,(len<<4)|MCFG_DIR,iMSGCFG);
362 id1 = (unsigned char) (msg->id<<5);
363 id0 = (unsigned char) (msg->id>>3);
364 canobj_write_reg(chip,obj,id1,iMSGID1);
365 canobj_write_reg(chip,obj,id0,iMSGID0);
367 canobj_write_reg(chip,obj,RMPD_UNC|TXRQ_UNC|CPUU_SET|NEWD_SET,iMSGCTL1);
368 for (i=0; i<len; i++) {
369 canobj_write_reg(chip,obj,msg->data[i],iMSGDAT0+i);
375 int i82527_send_msg(struct canchip_t *chip, struct msgobj_t *obj,
376 struct canmsg_t *msg)
378 canobj_write_reg(chip,obj,(MVAL_SET|TXIE_SET|RXIE_RES|INTPD_RES),iMSGCTL0);
380 if (msg->flags & MSG_RTR) {
381 canobj_write_reg(chip,obj,(RMPD_RES|TXRQ_RES|CPUU_RES|NEWD_SET),iMSGCTL1);
384 canobj_write_reg(chip,obj,(RMPD_RES|TXRQ_SET|CPUU_RES|NEWD_SET),iMSGCTL1);
390 int i82527_check_tx_stat(struct canchip_t *chip)
392 if (can_read_reg(chip,iSTAT) & iSTAT_TXOK) {
393 can_write_reg(chip,0x0,iSTAT);
397 can_write_reg(chip,0x0,iSTAT);
402 int i82527_remote_request(struct canchip_t *chip, struct msgobj_t *obj)
404 canobj_write_reg(chip,obj,(MVAL_SET|TXIE_RES|RXIE_SET|INTPD_RES),iMSGCTL0);
405 canobj_write_reg(chip,obj,(RMPD_RES|TXRQ_SET|MLST_RES|NEWD_RES),iMSGCTL1);
410 int i82527_set_btregs(struct canchip_t *chip, unsigned short btr0,
413 if (i82527_enable_configuration(chip))
416 i82527_seg_write_reg(chip, btr0, iBT0);
417 i82527_seg_write_reg(chip, btr1, iBT1);
419 i82527_disable_configuration(chip);
424 int i82527_start_chip(struct canchip_t *chip)
426 unsigned short flags = 0;
428 flags = can_read_reg(chip, iCTL) & (iCTL_IE|iCTL_SIE|iCTL_EIE);
429 can_write_reg(chip, flags, iCTL);
434 int i82527_stop_chip(struct canchip_t *chip)
436 unsigned short flags = 0;
438 flags = can_read_reg(chip, iCTL) & (iCTL_IE|iCTL_SIE|iCTL_EIE);
439 can_write_reg(chip, flags|(iCTL_CCE|iCTL_INI), iCTL);
444 int i82527_attach_to_chip(struct canchip_t *chip)
449 int i82527_release_chip(struct canchip_t *chip)
451 i82527_stop_chip(chip);
452 can_write_reg(chip, (iCTL_CCE|iCTL_INI), iCTL);
458 void i82527_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj)
462 canobj_write_reg(chip,obj,(MVAL_RES|TXIE_RES|RXIE_RES|INTPD_RES),iMSGCTL0);
465 /* Do local transmitted message distribution if enabled */
467 /* fill CAN message timestamp */
468 can_filltimestamp(&obj->tx_slot->msg.timestamp);
470 obj->tx_slot->msg.flags |= MSG_LOCAL;
471 canque_filter_msg2edges(obj->qends, &obj->tx_slot->msg);
473 /* Free transmitted slot */
474 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
478 cmd=canque_test_outslot(obj->qends, &obj->tx_qedge, &obj->tx_slot);
482 if (chip->chipspecops->pre_write_config(chip, obj, &obj->tx_slot->msg)) {
484 canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_PREP);
485 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
489 if (chip->chipspecops->send_msg(chip, obj, &obj->tx_slot->msg)) {
491 canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_SEND);
492 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
500 void i82527_irq_read_handler(struct canchip_t *chip, struct msgobj_t *obj, int objnum)
503 unsigned long message_id;
506 msgctl1=canobj_read_reg(chip,obj,iMSGCTL1);
507 if(msgctl1 & NEWD_RES)
512 canobj_write_reg(chip,obj,(RMPD_RES|TXRQ_RES|MLST_UNC|NEWD_RES),iMSGCTL1);
513 canobj_write_reg(chip,obj,(MVAL_SET|TXIE_RES|RXIE_SET|INTPD_RES),iMSGCTL0);
516 msgcfg = canobj_read_reg(chip,obj,iMSGCFG);
518 if (msgcfg&MCFG_XTD) {
519 message_id =canobj_read_reg(chip,obj,iMSGID3);
520 message_id|=canobj_read_reg(chip,obj,iMSGID2)<<8;
521 message_id|=canobj_read_reg(chip,obj,iMSGID1)<<16;
522 message_id|=canobj_read_reg(chip,obj,iMSGID0)<<24;
524 obj->rx_msg.flags = MSG_EXT;
528 message_id =canobj_read_reg(chip,obj,iMSGID1);
529 message_id|=canobj_read_reg(chip,obj,iMSGID0)<<8;
531 obj->rx_msg.flags = 0;
534 obj->rx_msg.length = (msgcfg >> 4) & 0xf;
535 if(obj->rx_msg.length > CAN_MSG_LENGTH) obj->rx_msg.length = CAN_MSG_LENGTH;
537 obj->rx_msg.id = message_id;
539 for (i=0; i < obj->rx_msg.length; i++)
540 obj->rx_msg.data[i] = canobj_read_reg(chip,obj,iMSGDAT0+i);
544 /* if NEWD is set after data read, then read data are likely inconsistent */
545 msgctl1=canobj_read_reg(chip,obj,iMSGCTL1);
546 if(msgctl1 & NEWD_SET) {
547 CANMSG("i82527_irq_read_handler: object %d data overwritten\n",objnum);
552 /* this object is special and data are queued in the shadow register */
553 canobj_write_reg(chip,obj,(MVAL_SET|TXIE_RES|RXIE_SET|INTPD_RES),iMSGCTL0);
554 canobj_write_reg(chip,obj,(RMPD_RES|TXRQ_RES|MLST_UNC|NEWD_RES),iMSGCTL1);
555 msgctl1=canobj_read_reg(chip,obj,iMSGCTL1);
559 /* fill CAN message timestamp */
560 can_filltimestamp(&obj->rx_msg.timestamp);
562 canque_filter_msg2edges(obj->qends, &obj->rx_msg);
564 if (msgctl1 & NEWD_SET)
567 if (msgctl1 & MLST_SET) {
568 canobj_write_reg(chip,obj,(RMPD_UNC|TXRQ_UNC|MLST_RES|NEWD_UNC),iMSGCTL1);
569 CANMSG("i82527_irq_read_handler: object %d message lost\n",objnum);
578 if (msgcfg&MCFG_XTD) {
579 message_id =canobj_read_reg(chip,obj,iMSGID3);
580 message_id|=canobj_read_reg(chip,obj,iMSGID2)<<8;
581 message_id|=canobj_read_reg(chip,obj,iMSGID1)<<16;
582 message_id|=canobj_read_reg(chip,obj,iMSGID0)<<24;
586 message_id =canobj_read_reg(chip,obj,iMSGID1);
587 message_id|=canobj_read_reg(chip,obj,iMSGID0)<<8;
591 can_spin_lock(&hardware_p->rtr_lock);
592 rtr_search=hardware_p->rtr_queue;
593 while (rtr_search != NULL) {
594 if (rtr_search->id == message_id)
596 rtr_search=rtr_search->next;
598 can_spin_unlock(&hardware_p->rtr_lock);
599 if ((rtr_search!=NULL) && (rtr_search->id==message_id))
600 i82527_irq_rtr_handler(chip, obj, rtr_search, message_id);
602 i82527_irq_read_handler(chip, obj, message_id);
607 void i82527_irq_update_filter(struct canchip_t *chip, struct msgobj_t *obj)
609 struct canfilt_t filt;
611 if(canqueue_ends_filt_conjuction(obj->qends, &filt)) {
612 obj->rx_preconfig_id=filt.id;
613 canobj_write_reg(chip,obj,(MVAL_RES|TXIE_RES|RXIE_RES|INTPD_RES),iMSGCTL0);
614 if(obj->object == 15) {
615 i82527_message15_mask(chip,filt.id,filt.mask);
617 if (filt.flags&MSG_EXT)
618 can_msgobj_set_fl(obj,RX_MODE_EXT);
620 can_msgobj_clear_fl(obj,RX_MODE_EXT);
622 i82527_pre_read_config(chip, obj);
624 CANMSG("i82527_irq_update_filter: obj at 0x%08lx\n",
625 can_ioptr2ulong(obj->obj_base_addr));
630 int i82527_irq_sync_activities(struct canchip_t *chip, struct msgobj_t *obj)
634 while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)) {
636 if(can_msgobj_test_and_clear_fl(obj,TX_REQUEST)) {
637 if(canobj_read_reg(chip,obj,iMSGCTL1)&TXRQ_RES)
638 i82527_irq_write_handler(chip, obj);
642 if(can_msgobj_test_and_clear_fl(obj,FILTCH_REQUEST)) {
643 i82527_irq_update_filter(chip, obj);
651 can_msgobj_clear_fl(obj,TX_LOCK);
652 if(can_msgobj_test_fl(obj,TX_REQUEST))
654 if(can_msgobj_test_fl(obj,FILTCH_REQUEST) && !obj->tx_slot)
662 int i82527_irq_handler(int irq, struct canchip_t *chip)
664 unsigned char msgcfg;
666 unsigned irq_register;
667 unsigned status_register;
669 struct msgobj_t *obj;
670 int loop_cnt=CHIP_MAX_IRQLOOP;
672 /*put_reg=device->hwspecops->write_register;*/
673 /*get_reg=device->hwspecops->read_register;*/
675 irq_register = i82527_seg_read_reg(chip, iIRQ);
678 DEBUGMSG("i82527: spurious IRQ\n");
679 return CANCHIP_IRQ_NONE;
686 CANMSG("i82527_irq_handler IRQ %d stuck\n",irq);
687 CANMSG("i82527_irq_register 0x%x\n",irq_register);
688 return CANCHIP_IRQ_STUCK;
691 DEBUGMSG("i82527: iIRQ 0x%02x\n",irq_register);
693 if (irq_register == 0x01) {
694 status_register=can_read_reg(chip, iSTAT);
695 CANMSG("Status register: 0x%x\n",status_register);
697 /*return CANCHIP_IRQ_NONE;*/
700 if (irq_register == 0x02)
702 else if(irq_register <= 13+3)
703 object = irq_register-3;
705 return CANCHIP_IRQ_NONE;
707 obj=chip->msgobj[object];
709 msgcfg = canobj_read_reg(chip,obj,iMSGCFG);
710 if (msgcfg & MCFG_DIR) {
711 can_msgobj_set_fl(obj,TX_REQUEST);
713 /* calls i82527_irq_write_handler synchronized with other invocations */
714 if(i82527_irq_sync_activities(chip, obj)<=0){
715 /* The interrupt has to be cleared anyway */
716 canobj_write_reg(chip,obj,(MVAL_UNC|TXIE_UNC|RXIE_UNC|INTPD_RES),iMSGCTL0);
719 * Rerun for case, that parallel activity on SMP or fully-preemptive
720 * kernel result in preparation and finished sending of message
721 * between above if and canobj_write_reg.
723 i82527_irq_sync_activities(chip, obj);
728 i82527_irq_read_handler(chip, obj, object);
731 } while((irq_register=i82527_seg_read_reg(chip, iIRQ)) != 0);
733 return CANCHIP_IRQ_HANDLED;
736 void i82527_irq_rtr_handler(struct canchip_t *chip, struct msgobj_t *obj,
737 struct rtr_id *rtr_search, unsigned long message_id)
741 canobj_write_reg(chip,obj,(MVAL_RES|TXIE_RES|RXIE_RES|INTPD_RES),iMSGCTL0);
742 canobj_write_reg(chip,obj,(RMPD_RES|TXRQ_RES|MLST_RES|NEWD_RES),iMSGCTL1);
744 can_spin_lock(&hardware_p->rtr_lock);
746 rtr_search->rtr_message->id=message_id;
747 rtr_search->rtr_message->length=(canobj_read_reg(chip,obj,iMSGCFG) & 0xf0)>>4;
748 for (i=0; i<rtr_search->rtr_message->length; i++)
749 rtr_search->rtr_message->data[i]=canobj_read_reg(chip,obj,iMSGDAT0+i);
751 can_spin_unlock(&hardware_p->rtr_lock);
753 if (waitqueue_active(&rtr_search->rtr_wq))
754 wake_up(&rtr_search->rtr_wq);
758 * i82527_wakeup_tx: - wakeups TX processing
759 * @chip: pointer to chip state structure
760 * @obj: pointer to message object structure
762 * Function is responsible for initiating message transmition.
763 * It is responsible for clearing of object TX_REQUEST flag
765 * Return Value: negative value reports error.
768 int i82527_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj)
770 can_preempt_disable();
772 can_msgobj_set_fl(obj,TX_REQUEST);
774 /* calls i82527_irq_write_handler synchronized with other invocations
775 from kernel and IRQ context */
776 i82527_irq_sync_activities(chip, obj);
778 can_preempt_enable();
782 int i82527_filtch_rq(struct canchip_t *chip, struct msgobj_t *obj)
784 can_preempt_disable();
786 can_msgobj_set_fl(obj,FILTCH_REQUEST);
788 /* setups filter synchronized with other invocations from kernel and IRQ context */
789 i82527_irq_sync_activities(chip, obj);
791 can_preempt_enable();
795 int i82527_register(struct chipspecops_t *chipspecops)
797 chipspecops->chip_config = i82527_chip_config;
798 chipspecops->baud_rate = i82527_baud_rate;
799 chipspecops->standard_mask = i82527_standard_mask;
800 chipspecops->extended_mask = i82527_extended_mask;
801 chipspecops->message15_mask = i82527_message15_mask;
802 chipspecops->clear_objects = i82527_clear_objects;
803 chipspecops->config_irqs = i82527_config_irqs;
804 chipspecops->pre_read_config = i82527_pre_read_config;
805 chipspecops->pre_write_config = i82527_pre_write_config;
806 chipspecops->send_msg = i82527_send_msg;
807 chipspecops->check_tx_stat = i82527_check_tx_stat;
808 chipspecops->wakeup_tx = i82527_wakeup_tx;
809 chipspecops->filtch_rq = i82527_filtch_rq;
810 chipspecops->remote_request = i82527_remote_request;
811 chipspecops->enable_configuration = i82527_enable_configuration;
812 chipspecops->disable_configuration = i82527_disable_configuration;
813 chipspecops->set_btregs = i82527_set_btregs;
814 chipspecops->attach_to_chip = i82527_attach_to_chip;
815 chipspecops->release_chip = i82527_release_chip;
816 chipspecops->start_chip = i82527_start_chip;
817 chipspecops->stop_chip = i82527_stop_chip;
818 chipspecops->irq_handler = i82527_irq_handler;
819 chipspecops->irq_accept = NULL;
823 int i82527_fill_chipspecops(struct canchip_t *chip)
825 chip->chip_type="i82527";
826 chip->max_objects=15;
827 i82527_register(chip->chipspecops);