]> rtime.felk.cvut.cz Git - lincan.git/blob - lincan/src/sh7760.c
Merge branch 'master' into can-usb1
[lincan.git] / lincan / src / sh7760.c
1 /* sh7760.c
2 * Linux CAN-bus device driver.
3 * This software is released under the GPL-License.
4 */ 
5
6 #include "../include/can.h"
7 #include "../include/can_sysdep.h"
8 #include "../include/main.h"
9 #include "../include/sh7760.h"
10 #include "../include/hcan2.h"
11
12 int sh7760_request_io(struct candevice_t *candev)
13 {
14         if (!can_request_io_region(candev->io_addr, candev->nr_all_chips * IO_RANGE, DEVICE_NAME)) {
15                 CANMSG("Unable to open port: 0x%lx\n",candev->io_addr);
16                 return -ENODEV;
17         }
18
19         DEBUGMSG("Registered IO-memory: 0x%lx - 0x%lx\n", candev->io_addr, candev->io_addr + candev->nr_all_chips * IO_RANGE - 1);
20         return 0;
21 }
22
23 int sh7760_release_io(struct candevice_t *candev)
24 {
25         can_release_io_region(candev->io_addr, candev->nr_all_chips * IO_RANGE);
26
27         return 0;
28 }
29
30 int sh7760_reset(struct candevice_t *candev)
31 {
32         int i; 
33         DEBUGMSG("Resetting HCAN2 chips ...\n");
34
35         for (i = 0; i < candev->nr_all_chips; i++)
36         {
37             /* !!! Assuming this card has ONLY HCAN2 chips !!! */
38             if (hcan2_reset_chip(candev->chip[i])) return -ENODEV;
39         }
40
41         return 0;
42 }
43
44 int sh7760_init_hw_data(struct candevice_t *candev) 
45 {
46         /* candev->res_addr = RESET_ADDR; */
47         candev->nr_82527_chips = NR_82527;
48         candev->nr_sja1000_chips = NR_SJA1000;
49         candev->nr_all_chips = NR_ALL;
50         /* candev->flags |= CANDEV_PROGRAMMABLE_IRQ; */
51
52         return 0;
53 }
54 int sh7760_init_chip_data(struct candevice_t *candev, int chipnr)
55 {
56         hcan2_fill_chipspecops(candev->chip[chipnr]);
57
58         candev->chip[chipnr]->chip_base_addr = can_ioport2ioptr(candev->io_addr) + chipnr * SH7760_CAN_CHIP_OFFSET; /* one chip with 2 interfaces */
59         candev->chip[chipnr]->clock = SH7760_CAN_CLOCK;
60         candev->chip[chipnr]->chip_irq = SH7760_CAN_IRQ + chipnr;
61         candev->chip[chipnr]->hostdevice = candev;
62
63         return 0;
64 }
65
66 int sh7760_init_obj_data(struct canchip_t *chip, int objnr)
67 {
68         chip->msgobj[objnr]->obj_base_addr = (can_ioptr_t) HCAN2_MB0 + HCAN2_MB_OFFSET * objnr;
69
70         return 0;
71 }
72
73 int sh7760_program_irq(struct candevice_t *candev)
74 {
75         /* sh7760 doesn't use programmable interrupt */ 
76         return 0;
77 }
78
79
80 void sh7760_write_register(unsigned data, can_ioptr_t address)
81 {
82         /* address is an absolute address */
83         writew(data, address);
84 }
85
86 unsigned sh7760_read_register(can_ioptr_t address)
87 {
88         /* address is an absolute address */
89         return readw(address);
90 }
91
92 int sh7760_register(struct hwspecops_t *hwspecops)
93 {
94         hwspecops->request_io = sh7760_request_io;
95         hwspecops->release_io = sh7760_release_io;
96         hwspecops->reset = sh7760_reset;
97         hwspecops->init_hw_data = sh7760_init_hw_data;
98         hwspecops->init_chip_data = sh7760_init_chip_data;
99         hwspecops->init_obj_data = sh7760_init_obj_data;
100         hwspecops->program_irq = sh7760_program_irq;
101         hwspecops->write_register = sh7760_write_register;
102         hwspecops->read_register = sh7760_read_register;
103         return 0;
104 }