1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (C) 2005 Sascha Hauer, Pengutronix |
4 | * Copyright (C) 2007 Wolfgang Grandegger <wg@grandegger.com> |
5 | */ |
6 | |
7 | #include <linux/kernel.h> |
8 | #include <linux/module.h> |
9 | #include <linux/interrupt.h> |
10 | #include <linux/netdevice.h> |
11 | #include <linux/delay.h> |
12 | #include <linux/pci.h> |
13 | #include <linux/platform_device.h> |
14 | #include <linux/irq.h> |
15 | #include <linux/can/dev.h> |
16 | #include <linux/can/platform/sja1000.h> |
17 | #include <linux/clk.h> |
18 | #include <linux/io.h> |
19 | #include <linux/of.h> |
20 | |
21 | #include "sja1000.h" |
22 | |
23 | #define DRV_NAME "sja1000_platform" |
24 | #define SP_CAN_CLOCK (16000000 / 2) |
25 | |
26 | MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>" ); |
27 | MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>" ); |
28 | MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the platform bus" ); |
29 | MODULE_ALIAS("platform:" DRV_NAME); |
30 | MODULE_LICENSE("GPL v2" ); |
31 | |
32 | struct sja1000_of_data { |
33 | size_t priv_sz; |
34 | void (*init)(struct sja1000_priv *priv, struct device_node *of); |
35 | }; |
36 | |
37 | struct technologic_priv { |
38 | spinlock_t io_lock; |
39 | }; |
40 | |
41 | static u8 sp_read_reg8(const struct sja1000_priv *priv, int reg) |
42 | { |
43 | return ioread8(priv->reg_base + reg); |
44 | } |
45 | |
46 | static void sp_write_reg8(const struct sja1000_priv *priv, int reg, u8 val) |
47 | { |
48 | iowrite8(val, priv->reg_base + reg); |
49 | } |
50 | |
51 | static u8 sp_read_reg16(const struct sja1000_priv *priv, int reg) |
52 | { |
53 | return ioread8(priv->reg_base + reg * 2); |
54 | } |
55 | |
56 | static void sp_write_reg16(const struct sja1000_priv *priv, int reg, u8 val) |
57 | { |
58 | iowrite8(val, priv->reg_base + reg * 2); |
59 | } |
60 | |
61 | static u8 sp_read_reg32(const struct sja1000_priv *priv, int reg) |
62 | { |
63 | return ioread8(priv->reg_base + reg * 4); |
64 | } |
65 | |
66 | static void sp_write_reg32(const struct sja1000_priv *priv, int reg, u8 val) |
67 | { |
68 | iowrite8(val, priv->reg_base + reg * 4); |
69 | } |
70 | |
71 | static u8 sp_technologic_read_reg16(const struct sja1000_priv *priv, int reg) |
72 | { |
73 | struct technologic_priv *tp = priv->priv; |
74 | unsigned long flags; |
75 | u8 val; |
76 | |
77 | spin_lock_irqsave(&tp->io_lock, flags); |
78 | iowrite16(reg, priv->reg_base + 0); |
79 | val = ioread16(priv->reg_base + 2); |
80 | spin_unlock_irqrestore(lock: &tp->io_lock, flags); |
81 | |
82 | return val; |
83 | } |
84 | |
85 | static void sp_technologic_write_reg16(const struct sja1000_priv *priv, |
86 | int reg, u8 val) |
87 | { |
88 | struct technologic_priv *tp = priv->priv; |
89 | unsigned long flags; |
90 | |
91 | spin_lock_irqsave(&tp->io_lock, flags); |
92 | iowrite16(reg, priv->reg_base + 0); |
93 | iowrite16(val, priv->reg_base + 2); |
94 | spin_unlock_irqrestore(lock: &tp->io_lock, flags); |
95 | } |
96 | |
97 | static void sp_technologic_init(struct sja1000_priv *priv, struct device_node *of) |
98 | { |
99 | struct technologic_priv *tp = priv->priv; |
100 | |
101 | priv->read_reg = sp_technologic_read_reg16; |
102 | priv->write_reg = sp_technologic_write_reg16; |
103 | spin_lock_init(&tp->io_lock); |
104 | } |
105 | |
106 | static void sp_rzn1_init(struct sja1000_priv *priv, struct device_node *of) |
107 | { |
108 | priv->flags = SJA1000_QUIRK_NO_CDR_REG | SJA1000_QUIRK_RESET_ON_OVERRUN; |
109 | } |
110 | |
111 | static void sp_populate(struct sja1000_priv *priv, |
112 | struct sja1000_platform_data *pdata, |
113 | unsigned long resource_mem_flags) |
114 | { |
115 | /* The CAN clock frequency is half the oscillator clock frequency */ |
116 | priv->can.clock.freq = pdata->osc_freq / 2; |
117 | priv->ocr = pdata->ocr; |
118 | priv->cdr = pdata->cdr; |
119 | |
120 | switch (resource_mem_flags & IORESOURCE_MEM_TYPE_MASK) { |
121 | case IORESOURCE_MEM_32BIT: |
122 | priv->read_reg = sp_read_reg32; |
123 | priv->write_reg = sp_write_reg32; |
124 | break; |
125 | case IORESOURCE_MEM_16BIT: |
126 | priv->read_reg = sp_read_reg16; |
127 | priv->write_reg = sp_write_reg16; |
128 | break; |
129 | case IORESOURCE_MEM_8BIT: |
130 | default: |
131 | priv->read_reg = sp_read_reg8; |
132 | priv->write_reg = sp_write_reg8; |
133 | break; |
134 | } |
135 | } |
136 | |
137 | static void sp_populate_of(struct sja1000_priv *priv, struct device_node *of) |
138 | { |
139 | int err; |
140 | u32 prop; |
141 | |
142 | err = of_property_read_u32(np: of, propname: "reg-io-width" , out_value: &prop); |
143 | if (err) |
144 | prop = 1; /* 8 bit is default */ |
145 | |
146 | switch (prop) { |
147 | case 4: |
148 | priv->read_reg = sp_read_reg32; |
149 | priv->write_reg = sp_write_reg32; |
150 | break; |
151 | case 2: |
152 | priv->read_reg = sp_read_reg16; |
153 | priv->write_reg = sp_write_reg16; |
154 | break; |
155 | case 1: |
156 | default: |
157 | priv->read_reg = sp_read_reg8; |
158 | priv->write_reg = sp_write_reg8; |
159 | } |
160 | |
161 | if (!priv->can.clock.freq) { |
162 | err = of_property_read_u32(np: of, propname: "nxp,external-clock-frequency" , out_value: &prop); |
163 | if (!err) |
164 | priv->can.clock.freq = prop / 2; |
165 | else |
166 | priv->can.clock.freq = SP_CAN_CLOCK; /* default */ |
167 | } |
168 | |
169 | err = of_property_read_u32(np: of, propname: "nxp,tx-output-mode" , out_value: &prop); |
170 | if (!err) |
171 | priv->ocr |= prop & OCR_MODE_MASK; |
172 | else |
173 | priv->ocr |= OCR_MODE_NORMAL; /* default */ |
174 | |
175 | err = of_property_read_u32(np: of, propname: "nxp,tx-output-config" , out_value: &prop); |
176 | if (!err) |
177 | priv->ocr |= (prop << OCR_TX_SHIFT) & OCR_TX_MASK; |
178 | else |
179 | priv->ocr |= OCR_TX0_PULLDOWN; /* default */ |
180 | |
181 | err = of_property_read_u32(np: of, propname: "nxp,clock-out-frequency" , out_value: &prop); |
182 | if (!err && prop) { |
183 | u32 divider = priv->can.clock.freq * 2 / prop; |
184 | |
185 | if (divider > 1) |
186 | priv->cdr |= divider / 2 - 1; |
187 | else |
188 | priv->cdr |= CDR_CLKOUT_MASK; |
189 | } else { |
190 | priv->cdr |= CDR_CLK_OFF; /* default */ |
191 | } |
192 | |
193 | if (!of_property_read_bool(np: of, propname: "nxp,no-comparator-bypass" )) |
194 | priv->cdr |= CDR_CBP; /* default */ |
195 | } |
196 | |
197 | static struct sja1000_of_data technologic_data = { |
198 | .priv_sz = sizeof(struct technologic_priv), |
199 | .init = sp_technologic_init, |
200 | }; |
201 | |
202 | static struct sja1000_of_data renesas_data = { |
203 | .init = sp_rzn1_init, |
204 | }; |
205 | |
206 | static const struct of_device_id sp_of_table[] = { |
207 | { .compatible = "nxp,sja1000" , .data = NULL, }, |
208 | { .compatible = "renesas,rzn1-sja1000" , .data = &renesas_data, }, |
209 | { .compatible = "technologic,sja1000" , .data = &technologic_data, }, |
210 | { /* sentinel */ }, |
211 | }; |
212 | MODULE_DEVICE_TABLE(of, sp_of_table); |
213 | |
214 | static int sp_probe(struct platform_device *pdev) |
215 | { |
216 | int err, irq = 0; |
217 | void __iomem *addr; |
218 | struct net_device *dev; |
219 | struct sja1000_priv *priv; |
220 | struct resource *res_mem, *res_irq = NULL; |
221 | struct sja1000_platform_data *pdata; |
222 | struct device_node *of = pdev->dev.of_node; |
223 | const struct sja1000_of_data *of_data = NULL; |
224 | size_t priv_sz = 0; |
225 | struct clk *clk; |
226 | |
227 | pdata = dev_get_platdata(dev: &pdev->dev); |
228 | if (!pdata && !of) { |
229 | dev_err(&pdev->dev, "No platform data provided!\n" ); |
230 | return -ENODEV; |
231 | } |
232 | |
233 | res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
234 | if (!res_mem) |
235 | return -ENODEV; |
236 | |
237 | if (!devm_request_mem_region(&pdev->dev, res_mem->start, |
238 | resource_size(res_mem), DRV_NAME)) |
239 | return -EBUSY; |
240 | |
241 | addr = devm_ioremap(dev: &pdev->dev, offset: res_mem->start, |
242 | size: resource_size(res: res_mem)); |
243 | if (!addr) |
244 | return -ENOMEM; |
245 | |
246 | if (of) { |
247 | irq = platform_get_irq(pdev, 0); |
248 | if (irq < 0) |
249 | return irq; |
250 | |
251 | clk = devm_clk_get_optional_enabled(dev: &pdev->dev, NULL); |
252 | if (IS_ERR(ptr: clk)) |
253 | return dev_err_probe(dev: &pdev->dev, err: PTR_ERR(ptr: clk), |
254 | fmt: "CAN clk operation failed" ); |
255 | } else { |
256 | res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
257 | if (!res_irq) |
258 | return -ENODEV; |
259 | } |
260 | |
261 | of_data = device_get_match_data(dev: &pdev->dev); |
262 | if (of_data) |
263 | priv_sz = of_data->priv_sz; |
264 | |
265 | dev = alloc_sja1000dev(sizeof_priv: priv_sz); |
266 | if (!dev) |
267 | return -ENOMEM; |
268 | priv = netdev_priv(dev); |
269 | |
270 | if (res_irq) { |
271 | irq = res_irq->start; |
272 | priv->irq_flags = res_irq->flags & IRQF_TRIGGER_MASK; |
273 | if (res_irq->flags & IORESOURCE_IRQ_SHAREABLE) |
274 | priv->irq_flags |= IRQF_SHARED; |
275 | } else { |
276 | priv->irq_flags = IRQF_SHARED; |
277 | } |
278 | |
279 | if (priv->flags & SJA1000_QUIRK_RESET_ON_OVERRUN) |
280 | priv->irq_flags |= IRQF_ONESHOT; |
281 | |
282 | dev->irq = irq; |
283 | priv->reg_base = addr; |
284 | |
285 | if (of) { |
286 | if (clk) { |
287 | priv->can.clock.freq = clk_get_rate(clk) / 2; |
288 | if (!priv->can.clock.freq) { |
289 | err = -EINVAL; |
290 | dev_err(&pdev->dev, "Zero CAN clk rate" ); |
291 | goto exit_free; |
292 | } |
293 | } |
294 | |
295 | sp_populate_of(priv, of); |
296 | |
297 | if (of_data && of_data->init) |
298 | of_data->init(priv, of); |
299 | } else { |
300 | sp_populate(priv, pdata, resource_mem_flags: res_mem->flags); |
301 | } |
302 | |
303 | platform_set_drvdata(pdev, data: dev); |
304 | SET_NETDEV_DEV(dev, &pdev->dev); |
305 | |
306 | err = register_sja1000dev(dev); |
307 | if (err) { |
308 | dev_err(&pdev->dev, "registering %s failed (err=%d)\n" , |
309 | DRV_NAME, err); |
310 | goto exit_free; |
311 | } |
312 | |
313 | dev_info(&pdev->dev, "%s device registered (reg_base=%p, irq=%d)\n" , |
314 | DRV_NAME, priv->reg_base, dev->irq); |
315 | return 0; |
316 | |
317 | exit_free: |
318 | free_sja1000dev(dev); |
319 | return err; |
320 | } |
321 | |
322 | static void sp_remove(struct platform_device *pdev) |
323 | { |
324 | struct net_device *dev = platform_get_drvdata(pdev); |
325 | |
326 | unregister_sja1000dev(dev); |
327 | free_sja1000dev(dev); |
328 | } |
329 | |
330 | static struct platform_driver sp_driver = { |
331 | .probe = sp_probe, |
332 | .remove_new = sp_remove, |
333 | .driver = { |
334 | .name = DRV_NAME, |
335 | .of_match_table = sp_of_table, |
336 | }, |
337 | }; |
338 | |
339 | module_platform_driver(sp_driver); |
340 | |