2 * Linux CAN-bus device driver.
3 * Written for new CAN driver version by Pavel Pisa - OCERA team member
4 * email:pisa@cmp.felk.cvut.cz
5 * This software is released under the GPL-License.
6 * Version lincan-0.3 17 Jun 2004
9 #include "../include/can.h"
10 #include "../include/can_sysdep.h"
11 #include "../include/main.h"
14 long virtual_bus_latency(struct msgobj_t *obj)
17 latency=obj->hostchip->baudrate;
19 latency=(long)HZ*1000/latency;
25 /* * * Virtual Chip Functionality * * */
27 int virtual_enable_configuration(struct canchip_t *chip)
32 int virtual_disable_configuration(struct canchip_t *chip)
38 * virtual_chip_config: - can chip configuration
39 * @chip: pointer to chip state structure
41 * Return Value: negative value reports error.
44 int virtual_chip_config(struct canchip_t *chip)
50 * virtual_extended_mask: - setup of extended mask for message filtering
51 * @chip: pointer to chip state structure
52 * @code: can message acceptance code
53 * @mask: can message acceptance mask
55 * Return Value: negative value reports error.
58 int virtual_extended_mask(struct canchip_t *chip, unsigned long code, unsigned long mask)
64 * virtual_baud_rate: - set communication parameters.
65 * @chip: pointer to chip state structure
66 * @rate: baud rate in Hz
67 * @clock: frequency of sja1000 clock in Hz (ISA osc is 14318000)
68 * @sjw: synchronization jump width (0-3) prescaled clock cycles
69 * @sampl_pt: sample point in % (0-100) sets (TSEG1+1)/(TSEG1+TSEG2+2) ratio
70 * @flags: fields %BTR1_SAM, %OCMODE, %OCPOL, %OCTP, %OCTN, %CLK_OFF, %CBP
72 * Return Value: negative value reports error.
75 int virtual_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw,
76 int sampl_pt, int flags)
82 * virtual_read: - reads and distributes one or more received messages
83 * @chip: pointer to chip state structure
84 * @obj: pinter to CAN message queue information
88 void virtual_read(struct canchip_t *chip, struct msgobj_t *obj) {
93 * virtual_pre_read_config: - prepares message object for message reception
94 * @chip: pointer to chip state structure
95 * @obj: pointer to message object state structure
97 * Return Value: negative value reports error.
98 * Positive value indicates immediate reception of message.
101 int virtual_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj)
106 #define MAX_TRANSMIT_WAIT_LOOPS 10
108 * virtual_pre_write_config: - prepares message object for message transmission
109 * @chip: pointer to chip state structure
110 * @obj: pointer to message object state structure
111 * @msg: pointer to CAN message
113 * Return Value: negative value reports error.
114 * File: src/virtual.c
116 int virtual_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj,
117 struct canmsg_t *msg)
123 * virtual_send_msg: - initiate message transmission
124 * @chip: pointer to chip state structure
125 * @obj: pointer to message object state structure
126 * @msg: pointer to CAN message
128 * This function is called after virtual_pre_write_config() function,
129 * which prepares data in chip buffer.
130 * Return Value: negative value reports error.
131 * File: src/virtual.c
133 int virtual_send_msg(struct canchip_t *chip, struct msgobj_t *obj,
134 struct canmsg_t *msg)
140 * virtual_check_tx_stat: - checks state of transmission engine
141 * @chip: pointer to chip state structure
143 * Return Value: negative value reports error.
144 * Positive return value indicates transmission under way status.
145 * Zero value indicates finishing of all issued transmission requests.
146 * File: src/virtual.c
148 int virtual_check_tx_stat(struct canchip_t *chip)
154 * virtual_set_btregs: - configures bitrate registers
155 * @chip: pointer to chip state structure
156 * @btr0: bitrate register 0
157 * @btr1: bitrate register 1
159 * Return Value: negative value reports error.
160 * File: src/virtual.c
162 int virtual_set_btregs(struct canchip_t *chip, unsigned short btr0,
169 * virtual_stop_chip: - starts chip message processing
170 * @chip: pointer to chip state structure
172 * Return Value: negative value reports error.
173 * File: src/virtual.c
175 int virtual_start_chip(struct canchip_t *chip)
181 * virtual_stop_chip: - stops chip message processing
182 * @chip: pointer to chip state structure
184 * Return Value: negative value reports error.
185 * File: src/virtual.c
187 int virtual_stop_chip(struct canchip_t *chip)
193 * virtual_attach_to_chip: - attaches to the chip, setups registers and state
194 * @chip: pointer to chip state structure
196 * Return Value: negative value reports error.
197 * File: src/virtual.c
199 int virtual_attach_to_chip(struct canchip_t *chip)
205 * virtual_release_chip: - called before chip structure removal if %CHIP_ATTACHED is set
206 * @chip: pointer to chip state structure
208 * Return Value: negative value reports error.
209 * File: src/virtual.c
211 int virtual_release_chip(struct canchip_t *chip)
213 virtual_stop_chip(chip);
218 * virtual_remote_request: - configures message object and asks for RTR message
219 * @chip: pointer to chip state structure
220 * @obj: pointer to message object structure
222 * Return Value: negative value reports error.
223 * File: src/virtual.c
225 int virtual_remote_request(struct canchip_t *chip, struct msgobj_t *obj)
227 CANMSG("virtual_remote_request not implemented\n");
232 * virtual_standard_mask: - setup of mask for message filtering
233 * @chip: pointer to chip state structure
234 * @code: can message acceptance code
235 * @mask: can message acceptance mask
237 * Return Value: negative value reports error.
238 * File: src/virtual.c
240 int virtual_standard_mask(struct canchip_t *chip, unsigned short code,
243 CANMSG("virtual_standard_mask not implemented\n");
248 * virtual_clear_objects: - clears state of all message object residing in chip
249 * @chip: pointer to chip state structure
251 * Return Value: negative value reports error.
252 * File: src/virtual.c
254 int virtual_clear_objects(struct canchip_t *chip)
256 CANMSG("virtual_clear_objects not implemented\n");
261 * virtual_config_irqs: - tunes chip hardware interrupt delivery
262 * @chip: pointer to chip state structure
263 * @irqs: requested chip IRQ configuration
265 * Return Value: negative value reports error.
266 * File: src/virtual.c
268 int virtual_config_irqs(struct canchip_t *chip, short irqs)
270 CANMSG("virtual_config_irqs not implemented\n");
275 * virtual_irq_write_handler: - part of ISR code responsible for transmit events
276 * @chip: pointer to chip state structure
277 * @obj: pointer to attached queue description
279 * The main purpose of this function is to read message from attached queues
280 * and transfer message contents into CAN controller chip.
281 * This subroutine is called by
282 * virtual_irq_write_handler() for transmit events.
283 * File: src/virtual.c
285 void virtual_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj)
293 * virtual_irq_handler: - interrupt service routine
294 * @irq: interrupt vector number, this value is system specific
295 * @dev_id: driver private pointer registered at time of request_irq() call.
296 * The CAN driver uses this pointer to store relationship of interrupt
297 * to chip state structure - @struct canchip_t
298 * @regs: system dependent value pointing to registers stored in exception frame
300 * Interrupt handler is activated when state of CAN controller chip changes,
301 * there is message to be read or there is more space for new messages or
302 * error occurs. The receive events results in reading of the message from
303 * CAN controller chip and distribution of message through attached
305 * File: src/virtual.c
307 int virtual_irq_handler(int irq, struct canchip_t *chip)
309 return CANCHIP_IRQ_HANDLED;
313 void virtual_schedule_next(struct msgobj_t *obj)
317 can_preempt_disable();
319 can_msgobj_set_fl(obj,TX_REQUEST);
321 while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
323 can_msgobj_clear_fl(obj,TX_REQUEST);
325 cmd=canque_test_outslot(obj->qends, &obj->tx_qedge, &obj->tx_slot);
327 mod_timer(&obj->tx_timeout,
328 jiffies+virtual_bus_latency(obj));
329 DEBUGMSG("virtual: scheduled delivery\n");
332 can_msgobj_clear_fl(obj,TX_LOCK);
334 if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
335 DEBUGMSG("TX looping in virtual_schedule_next\n");
338 can_preempt_enable();
342 void virtual_do_tx_timeout(unsigned long data)
344 struct msgobj_t *obj=(struct msgobj_t *)data;
347 /* fill CAN message timestamp */
348 can_filltimestamp(&obj->tx_slot->msg.timestamp);
350 /* Deliver message to edges */
351 canque_filter_msg2edges(obj->qends, &obj->tx_slot->msg);
352 /* Free transmitted slot */
353 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
355 DEBUGMSG("virtual: delayed delivery\n");
357 can_msgobj_clear_fl(obj,TX_LOCK);
359 virtual_schedule_next(obj);
363 * virtual_wakeup_tx: - wakeups TX processing
364 * @chip: pointer to chip state structure
365 * @obj: pointer to message object structure
367 * Function is responsible for initiating message transmition.
368 * It is responsible for clearing of object TX_REQUEST flag
370 * Return Value: negative value reports error.
371 * File: src/virtual.c
373 int virtual_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj)
375 /* can_msgobj_set_fl(obj,TX_REQUEST); */
377 struct canque_edge_t *qedge;
378 struct canque_slot_t *slot;
381 can_msgobj_clear_fl(obj,TX_REQUEST);
384 if(!virtual_bus_latency(obj)) {
385 #endif /*CAN_WITH_RTL*/
386 /* Ensure delivery of all ready slots */
387 while((cmd=canque_test_outslot(obj->qends, &qedge, &slot)) >= 0){
389 /* fill CAN message timestamp */
390 can_filltimestamp(&slot->msg.timestamp);
392 canque_filter_msg2edges(obj->qends, &slot->msg);
393 DEBUGMSG("virtual: direct delivery\n");
395 canque_free_outslot(obj->qends, qedge, slot);
399 virtual_schedule_next(obj);
401 #endif /*CAN_WITH_RTL*/
407 /* * * Virtual Board Functionality * * */
410 * virtual_request_io: - reserve io or memory range for can board
411 * @candev: pointer to candevice/board which asks for io. Field @io_addr
412 * of @candev is used in most cases to define start of the range
414 * Return Value: The function returns zero on success or %-ENODEV on failure
415 * File: src/virtual.c
417 int virtual_request_io(struct candevice_t *candev)
423 * virtual_elease_io - free reserved io memory range
424 * @candev: pointer to candevice/board which releases io
426 * Return Value: The function always returns zero
427 * File: src/virtual.c
429 int virtual_release_io(struct candevice_t *candev)
435 * virtual_reset - hardware reset routine
436 * @candev: Pointer to candevice/board structure
438 * Return Value: The function returns zero on success or %-ENODEV on failure
439 * File: src/virtual.c
441 int virtual_reset(struct candevice_t *candev)
447 * virtual_init_hw_data - Initialize hardware cards
448 * @candev: Pointer to candevice/board structure
450 * Return Value: The function always returns zero
451 * File: src/virtual.c
453 int virtual_init_hw_data(struct candevice_t *candev)
456 candev->nr_82527_chips=0;
457 candev->nr_sja1000_chips=0;
458 candev->nr_all_chips=1;
459 candev->flags |= CANDEV_PROGRAMMABLE_IRQ*0;
464 #define CHIP_TYPE "virtual"
467 * virtual_init_chip_data - Initialize chips
468 * @candev: Pointer to candevice/board structure
469 * @chipnr: Number of the CAN chip on the hardware card
471 * Return Value: The function always returns zero
472 * File: src/virtual.c
474 int virtual_init_chip_data(struct candevice_t *candev, int chipnr)
476 struct canchip_t *chip = candev->chip[chipnr];
477 chip->chip_type = CHIP_TYPE;
478 chip->chip_base_addr = 0;
479 chip->clock = 10000000;
480 chip->int_clk_reg = 0x0;
481 chip->int_bus_reg = 0x0;
482 chip->max_objects = 1;
484 CANMSG("initializing virtual chip operations\n");
485 chip->chipspecops->chip_config=virtual_chip_config;
486 chip->chipspecops->baud_rate=virtual_baud_rate;
487 chip->chipspecops->standard_mask=virtual_standard_mask;
488 chip->chipspecops->extended_mask=virtual_extended_mask;
489 chip->chipspecops->message15_mask=virtual_extended_mask;
490 chip->chipspecops->clear_objects=virtual_clear_objects;
491 chip->chipspecops->config_irqs=virtual_config_irqs;
492 chip->chipspecops->pre_read_config=virtual_pre_read_config;
493 chip->chipspecops->pre_write_config=virtual_pre_write_config;
494 chip->chipspecops->send_msg=virtual_send_msg;
495 chip->chipspecops->check_tx_stat=virtual_check_tx_stat;
496 chip->chipspecops->wakeup_tx=virtual_wakeup_tx;
497 chip->chipspecops->remote_request=virtual_remote_request;
498 chip->chipspecops->enable_configuration=virtual_enable_configuration;
499 chip->chipspecops->disable_configuration=virtual_disable_configuration;
500 chip->chipspecops->attach_to_chip=virtual_attach_to_chip;
501 chip->chipspecops->release_chip=virtual_release_chip;
502 chip->chipspecops->set_btregs=virtual_set_btregs;
503 chip->chipspecops->start_chip=virtual_start_chip;
504 chip->chipspecops->stop_chip=virtual_stop_chip;
505 chip->chipspecops->irq_handler=NULL;
506 chip->chipspecops->irq_accept=NULL;
512 * virtual_init_obj_data - Initialize message buffers
513 * @chip: Pointer to chip specific structure
514 * @objnr: Number of the message buffer
516 * Return Value: The function always returns zero
517 * File: src/virtual.c
519 int virtual_init_obj_data(struct canchip_t *chip, int objnr)
521 struct msgobj_t *obj=chip->msgobj[objnr];
522 obj->obj_base_addr=chip->chip_base_addr;
523 obj->tx_timeout.function=virtual_do_tx_timeout;
524 obj->tx_timeout.data=(unsigned long)obj;
529 * virtual_program_irq - program interrupts
530 * @candev: Pointer to candevice/board structure
532 * Return value: The function returns zero on success or %-ENODEV on failure
533 * File: src/virtual.c
535 int virtual_program_irq(struct candevice_t *candev)
540 int virtual_register(struct hwspecops_t *hwspecops)
542 hwspecops->request_io = virtual_request_io;
543 hwspecops->release_io = virtual_release_io;
544 hwspecops->reset = virtual_reset;
545 hwspecops->init_hw_data = virtual_init_hw_data;
546 hwspecops->init_chip_data = virtual_init_chip_data;
547 hwspecops->init_obj_data = virtual_init_obj_data;
548 hwspecops->write_register = NULL;
549 hwspecops->read_register = NULL;
550 hwspecops->program_irq = virtual_program_irq;