2 * Platform CAN bus driver for Bosch C_CAN controller
4 * Copyright (C) 2010 ST Microelectronics
5 * Bhupesh Sharma <bhupesh.sharma@st.com>
7 * Borrowed heavily from the C_CAN driver originally written by:
9 * - Sascha Hauer, Marc Kleine-Budde, Pengutronix <s.hauer@pengutronix.de>
10 * - Simon Kallweit, intefo AG <simon.kallweit@intefo.ch>
12 * Bosch C_CAN controller is compliant to CAN protocol version 2.0 part A and B.
13 * Bosch C_CAN user manual can be obtained from:
14 * http://www.semiconductors.bosch.de/media/en/pdf/ipmodules_1/c_can/
15 * users_manual_c_can.pdf
17 * This file is licensed under the terms of the GNU General Public
18 * License version 2. This program is licensed "as is" without any
19 * warranty of any kind, whether express or implied.
22 #include <linux/kernel.h>
23 #include <linux/module.h>
24 #include <linux/interrupt.h>
25 #include <linux/delay.h>
26 #include <linux/netdevice.h>
27 #include <linux/if_arp.h>
28 #include <linux/if_ether.h>
29 #include <linux/list.h>
31 #include <linux/platform_device.h>
32 #include <linux/clk.h>
34 #include <linux/of_device.h>
36 #include <linux/can/dev.h>
40 #define CAN_RAMINIT_START_MASK(i) (0x001 << (i))
41 #define CAN_RAMINIT_DONE_MASK(i) (0x100 << (i))
42 #define CAN_RAMINIT_ALL_MASK(i) (0x101 << (i))
43 #define DCAN_RAM_INIT_BIT (1 << 3)
44 static DEFINE_SPINLOCK(raminit_lock
);
46 * 16-bit c_can registers can be arranged differently in the memory
47 * architecture of different implementations. For example: 16-bit
48 * registers can be aligned to a 16-bit boundary or 32-bit boundary etc.
49 * Handle the same by providing a common read/write interface.
51 static u16
c_can_plat_read_reg_aligned_to_16bit(const struct c_can_priv
*priv
,
54 return readw(priv
->base
+ priv
->regs
[index
]);
57 static void c_can_plat_write_reg_aligned_to_16bit(const struct c_can_priv
*priv
,
58 enum reg index
, u16 val
)
60 writew(val
, priv
->base
+ priv
->regs
[index
]);
63 static u16
c_can_plat_read_reg_aligned_to_32bit(const struct c_can_priv
*priv
,
66 return readw(priv
->base
+ 2 * priv
->regs
[index
]);
69 static void c_can_plat_write_reg_aligned_to_32bit(const struct c_can_priv
*priv
,
70 enum reg index
, u16 val
)
72 writew(val
, priv
->base
+ 2 * priv
->regs
[index
]);
75 static void c_can_hw_raminit_wait_ti(const struct c_can_priv
*priv
, u32 mask
,
78 /* We look only at the bits of our instance. */
80 while ((readl(priv
->raminit_ctrlreg
) & mask
) != val
)
84 static void c_can_hw_raminit_ti(const struct c_can_priv
*priv
, bool enable
)
86 u32 mask
= CAN_RAMINIT_ALL_MASK(priv
->instance
);
89 spin_lock(&raminit_lock
);
91 ctrl
= readl(priv
->raminit_ctrlreg
);
92 /* We clear the done and start bit first. The start bit is
93 * looking at the 0 -> transition, but is not self clearing;
94 * And we clear the init done bit as well.
96 ctrl
&= ~CAN_RAMINIT_START_MASK(priv
->instance
);
97 ctrl
|= CAN_RAMINIT_DONE_MASK(priv
->instance
);
98 writel(ctrl
, priv
->raminit_ctrlreg
);
99 ctrl
&= ~CAN_RAMINIT_DONE_MASK(priv
->instance
);
100 c_can_hw_raminit_wait_ti(priv
, ctrl
, mask
);
103 /* Set start bit and wait for the done bit. */
104 ctrl
|= CAN_RAMINIT_START_MASK(priv
->instance
);
105 writel(ctrl
, priv
->raminit_ctrlreg
);
106 ctrl
|= CAN_RAMINIT_DONE_MASK(priv
->instance
);
107 c_can_hw_raminit_wait_ti(priv
, ctrl
, mask
);
109 spin_unlock(&raminit_lock
);
112 static u32
c_can_plat_read_reg32(const struct c_can_priv
*priv
, enum reg index
)
116 val
= priv
->read_reg(priv
, index
);
117 val
|= ((u32
) priv
->read_reg(priv
, index
+ 1)) << 16;
122 static void c_can_plat_write_reg32(const struct c_can_priv
*priv
, enum reg index
,
125 priv
->write_reg(priv
, index
+ 1, val
>> 16);
126 priv
->write_reg(priv
, index
, val
);
129 static u32
d_can_plat_read_reg32(const struct c_can_priv
*priv
, enum reg index
)
131 return readl(priv
->base
+ priv
->regs
[index
]);
134 static void d_can_plat_write_reg32(const struct c_can_priv
*priv
, enum reg index
,
137 writel(val
, priv
->base
+ priv
->regs
[index
]);
140 static void c_can_hw_raminit_wait(const struct c_can_priv
*priv
, u32 mask
)
142 while (priv
->read_reg32(priv
, C_CAN_FUNCTION_REG
) & mask
)
146 static void c_can_hw_raminit(const struct c_can_priv
*priv
, bool enable
)
150 ctrl
= priv
->read_reg32(priv
, C_CAN_FUNCTION_REG
);
151 ctrl
&= ~DCAN_RAM_INIT_BIT
;
152 priv
->write_reg32(priv
, C_CAN_FUNCTION_REG
, ctrl
);
153 c_can_hw_raminit_wait(priv
, ctrl
);
156 ctrl
|= DCAN_RAM_INIT_BIT
;
157 priv
->write_reg32(priv
, C_CAN_FUNCTION_REG
, ctrl
);
158 c_can_hw_raminit_wait(priv
, ctrl
);
162 static struct platform_device_id c_can_id_table
[] = {
163 [BOSCH_C_CAN_PLATFORM
] = {
164 .name
= KBUILD_MODNAME
,
165 .driver_data
= BOSCH_C_CAN
,
169 .driver_data
= BOSCH_C_CAN
,
173 .driver_data
= BOSCH_D_CAN
,
177 MODULE_DEVICE_TABLE(platform
, c_can_id_table
);
179 static const struct of_device_id c_can_of_table
[] = {
180 { .compatible
= "bosch,c_can", .data
= &c_can_id_table
[BOSCH_C_CAN
] },
181 { .compatible
= "bosch,d_can", .data
= &c_can_id_table
[BOSCH_D_CAN
] },
184 MODULE_DEVICE_TABLE(of
, c_can_of_table
);
186 static int c_can_plat_probe(struct platform_device
*pdev
)
190 struct net_device
*dev
;
191 struct c_can_priv
*priv
;
192 const struct of_device_id
*match
;
193 const struct platform_device_id
*id
;
194 struct resource
*mem
, *res
;
198 if (pdev
->dev
.of_node
) {
199 match
= of_match_device(c_can_of_table
, &pdev
->dev
);
201 dev_err(&pdev
->dev
, "Failed to find matching dt id\n");
207 id
= platform_get_device_id(pdev
);
210 /* get the appropriate clk */
211 clk
= clk_get(&pdev
->dev
, NULL
);
213 dev_err(&pdev
->dev
, "no clock defined\n");
218 /* get the platform data */
219 mem
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
220 irq
= platform_get_irq(pdev
, 0);
221 if (!mem
|| irq
<= 0) {
226 if (!request_mem_region(mem
->start
, resource_size(mem
),
228 dev_err(&pdev
->dev
, "resource unavailable\n");
233 addr
= ioremap(mem
->start
, resource_size(mem
));
235 dev_err(&pdev
->dev
, "failed to map can port\n");
237 goto exit_release_mem
;
240 /* allocate the c_can device */
241 dev
= alloc_c_can_dev();
247 priv
= netdev_priv(dev
);
248 switch (id
->driver_data
) {
250 priv
->regs
= reg_map_c_can
;
251 switch (mem
->flags
& IORESOURCE_MEM_TYPE_MASK
) {
252 case IORESOURCE_MEM_32BIT
:
253 priv
->read_reg
= c_can_plat_read_reg_aligned_to_32bit
;
254 priv
->write_reg
= c_can_plat_write_reg_aligned_to_32bit
;
255 priv
->read_reg32
= c_can_plat_read_reg32
;
256 priv
->write_reg32
= c_can_plat_write_reg32
;
258 case IORESOURCE_MEM_16BIT
:
260 priv
->read_reg
= c_can_plat_read_reg_aligned_to_16bit
;
261 priv
->write_reg
= c_can_plat_write_reg_aligned_to_16bit
;
262 priv
->read_reg32
= c_can_plat_read_reg32
;
263 priv
->write_reg32
= c_can_plat_write_reg32
;
268 priv
->regs
= reg_map_d_can
;
269 priv
->can
.ctrlmode_supported
|= CAN_CTRLMODE_3_SAMPLES
;
270 priv
->read_reg
= c_can_plat_read_reg_aligned_to_16bit
;
271 priv
->write_reg
= c_can_plat_write_reg_aligned_to_16bit
;
272 priv
->read_reg32
= d_can_plat_read_reg32
;
273 priv
->write_reg32
= d_can_plat_write_reg32
;
275 if (pdev
->dev
.of_node
)
276 priv
->instance
= of_alias_get_id(pdev
->dev
.of_node
, "d_can");
278 priv
->instance
= pdev
->id
;
280 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 1);
281 /* Not all D_CAN modules have a separate register for the D_CAN
282 * RAM initialization. Use default RAM init bit in D_CAN module
283 * if not specified in DT.
286 priv
->raminit
= c_can_hw_raminit
;
290 priv
->raminit_ctrlreg
= devm_ioremap(&pdev
->dev
, res
->start
,
292 if (IS_ERR(priv
->raminit_ctrlreg
) || priv
->instance
< 0)
293 dev_info(&pdev
->dev
, "control memory is not used for raminit\n");
295 priv
->raminit
= c_can_hw_raminit_ti
;
299 goto exit_free_device
;
304 priv
->device
= &pdev
->dev
;
305 priv
->can
.clock
.freq
= clk_get_rate(clk
);
307 priv
->type
= id
->driver_data
;
309 platform_set_drvdata(pdev
, dev
);
310 SET_NETDEV_DEV(dev
, &pdev
->dev
);
312 ret
= register_c_can_dev(dev
);
314 dev_err(&pdev
->dev
, "registering %s failed (err=%d)\n",
315 KBUILD_MODNAME
, ret
);
316 goto exit_free_device
;
319 dev_info(&pdev
->dev
, "%s device registered (regs=%p, irq=%d)\n",
320 KBUILD_MODNAME
, priv
->base
, dev
->irq
);
328 release_mem_region(mem
->start
, resource_size(mem
));
332 dev_err(&pdev
->dev
, "probe failed\n");
337 static int c_can_plat_remove(struct platform_device
*pdev
)
339 struct net_device
*dev
= platform_get_drvdata(pdev
);
340 struct c_can_priv
*priv
= netdev_priv(dev
);
341 struct resource
*mem
;
343 unregister_c_can_dev(dev
);
348 mem
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
349 release_mem_region(mem
->start
, resource_size(mem
));
357 static int c_can_suspend(struct platform_device
*pdev
, pm_message_t state
)
360 struct net_device
*ndev
= platform_get_drvdata(pdev
);
361 struct c_can_priv
*priv
= netdev_priv(ndev
);
363 if (priv
->type
!= BOSCH_D_CAN
) {
364 dev_warn(&pdev
->dev
, "Not supported\n");
368 if (netif_running(ndev
)) {
369 netif_stop_queue(ndev
);
370 netif_device_detach(ndev
);
373 ret
= c_can_power_down(ndev
);
375 netdev_err(ndev
, "failed to enter power down mode\n");
379 priv
->can
.state
= CAN_STATE_SLEEPING
;
384 static int c_can_resume(struct platform_device
*pdev
)
387 struct net_device
*ndev
= platform_get_drvdata(pdev
);
388 struct c_can_priv
*priv
= netdev_priv(ndev
);
390 if (priv
->type
!= BOSCH_D_CAN
) {
391 dev_warn(&pdev
->dev
, "Not supported\n");
395 ret
= c_can_power_up(ndev
);
397 netdev_err(ndev
, "Still in power down mode\n");
401 priv
->can
.state
= CAN_STATE_ERROR_ACTIVE
;
403 if (netif_running(ndev
)) {
404 netif_device_attach(ndev
);
405 netif_start_queue(ndev
);
411 #define c_can_suspend NULL
412 #define c_can_resume NULL
415 static struct platform_driver c_can_plat_driver
= {
417 .name
= KBUILD_MODNAME
,
418 .owner
= THIS_MODULE
,
419 .of_match_table
= c_can_of_table
,
421 .probe
= c_can_plat_probe
,
422 .remove
= c_can_plat_remove
,
423 .suspend
= c_can_suspend
,
424 .resume
= c_can_resume
,
425 .id_table
= c_can_id_table
,
428 module_platform_driver(c_can_plat_driver
);
430 MODULE_AUTHOR("Bhupesh Sharma <bhupesh.sharma@st.com>");
431 MODULE_LICENSE("GPL v2");
432 MODULE_DESCRIPTION("Platform CAN bus driver for Bosch C_CAN controller");