xref: /linux/drivers/net/can/sja1000/sja1000_isa.c (revision ca55b2fef3a9373fcfc30f82fd26bc7fccbda732)
1 /*
2  * Copyright (C) 2009 Wolfgang Grandegger <wg@grandegger.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the version 2 of the GNU General Public License
6  * as published by the Free Software Foundation
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, see <http://www.gnu.org/licenses/>.
15  */
16 
17 #include <linux/kernel.h>
18 #include <linux/module.h>
19 #include <linux/platform_device.h>
20 #include <linux/interrupt.h>
21 #include <linux/netdevice.h>
22 #include <linux/delay.h>
23 #include <linux/irq.h>
24 #include <linux/io.h>
25 #include <linux/can/dev.h>
26 #include <linux/can/platform/sja1000.h>
27 
28 #include "sja1000.h"
29 
30 #define DRV_NAME "sja1000_isa"
31 
32 #define MAXDEV 8
33 
34 MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
35 MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the ISA bus");
36 MODULE_LICENSE("GPL v2");
37 
38 #define CLK_DEFAULT	16000000	/* 16 MHz */
39 #define CDR_DEFAULT	(CDR_CBP | CDR_CLK_OFF)
40 #define OCR_DEFAULT	OCR_TX0_PUSHPULL
41 
42 static unsigned long port[MAXDEV];
43 static unsigned long mem[MAXDEV];
44 static int irq[MAXDEV];
45 static int clk[MAXDEV];
46 static unsigned char cdr[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff};
47 static unsigned char ocr[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff};
48 static int indirect[MAXDEV] = {[0 ... (MAXDEV - 1)] = -1};
49 static spinlock_t indirect_lock[MAXDEV];  /* lock for indirect access mode */
50 
51 module_param_array(port, ulong, NULL, S_IRUGO);
52 MODULE_PARM_DESC(port, "I/O port number");
53 
54 module_param_array(mem, ulong, NULL, S_IRUGO);
55 MODULE_PARM_DESC(mem, "I/O memory address");
56 
57 module_param_array(indirect, int, NULL, S_IRUGO);
58 MODULE_PARM_DESC(indirect, "Indirect access via address and data port");
59 
60 module_param_array(irq, int, NULL, S_IRUGO);
61 MODULE_PARM_DESC(irq, "IRQ number");
62 
63 module_param_array(clk, int, NULL, S_IRUGO);
64 MODULE_PARM_DESC(clk, "External oscillator clock frequency "
65 		 "(default=16000000 [16 MHz])");
66 
67 module_param_array(cdr, byte, NULL, S_IRUGO);
68 MODULE_PARM_DESC(cdr, "Clock divider register "
69 		 "(default=0x48 [CDR_CBP | CDR_CLK_OFF])");
70 
71 module_param_array(ocr, byte, NULL, S_IRUGO);
72 MODULE_PARM_DESC(ocr, "Output control register "
73 		 "(default=0x18 [OCR_TX0_PUSHPULL])");
74 
75 #define SJA1000_IOSIZE          0x20
76 #define SJA1000_IOSIZE_INDIRECT 0x02
77 
78 static struct platform_device *sja1000_isa_devs[MAXDEV];
79 
80 static u8 sja1000_isa_mem_read_reg(const struct sja1000_priv *priv, int reg)
81 {
82 	return readb(priv->reg_base + reg);
83 }
84 
85 static void sja1000_isa_mem_write_reg(const struct sja1000_priv *priv,
86 				      int reg, u8 val)
87 {
88 	writeb(val, priv->reg_base + reg);
89 }
90 
91 static u8 sja1000_isa_port_read_reg(const struct sja1000_priv *priv, int reg)
92 {
93 	return inb((unsigned long)priv->reg_base + reg);
94 }
95 
96 static void sja1000_isa_port_write_reg(const struct sja1000_priv *priv,
97 				       int reg, u8 val)
98 {
99 	outb(val, (unsigned long)priv->reg_base + reg);
100 }
101 
102 static u8 sja1000_isa_port_read_reg_indirect(const struct sja1000_priv *priv,
103 					     int reg)
104 {
105 	unsigned long flags, base = (unsigned long)priv->reg_base;
106 	u8 readval;
107 
108 	spin_lock_irqsave(&indirect_lock[priv->dev->dev_id], flags);
109 	outb(reg, base);
110 	readval = inb(base + 1);
111 	spin_unlock_irqrestore(&indirect_lock[priv->dev->dev_id], flags);
112 
113 	return readval;
114 }
115 
116 static void sja1000_isa_port_write_reg_indirect(const struct sja1000_priv *priv,
117 						int reg, u8 val)
118 {
119 	unsigned long flags, base = (unsigned long)priv->reg_base;
120 
121 	spin_lock_irqsave(&indirect_lock[priv->dev->dev_id], flags);
122 	outb(reg, base);
123 	outb(val, base + 1);
124 	spin_unlock_irqrestore(&indirect_lock[priv->dev->dev_id], flags);
125 }
126 
127 static int sja1000_isa_probe(struct platform_device *pdev)
128 {
129 	struct net_device *dev;
130 	struct sja1000_priv *priv;
131 	void __iomem *base = NULL;
132 	int iosize = SJA1000_IOSIZE;
133 	int idx = pdev->id;
134 	int err;
135 
136 	dev_dbg(&pdev->dev, "probing idx=%d: port=%#lx, mem=%#lx, irq=%d\n",
137 		idx, port[idx], mem[idx], irq[idx]);
138 
139 	if (mem[idx]) {
140 		if (!request_mem_region(mem[idx], iosize, DRV_NAME)) {
141 			err = -EBUSY;
142 			goto exit;
143 		}
144 		base = ioremap_nocache(mem[idx], iosize);
145 		if (!base) {
146 			err = -ENOMEM;
147 			goto exit_release;
148 		}
149 	} else {
150 		if (indirect[idx] > 0 ||
151 		    (indirect[idx] == -1 && indirect[0] > 0))
152 			iosize = SJA1000_IOSIZE_INDIRECT;
153 		if (!request_region(port[idx], iosize, DRV_NAME)) {
154 			err = -EBUSY;
155 			goto exit;
156 		}
157 	}
158 
159 	dev = alloc_sja1000dev(0);
160 	if (!dev) {
161 		err = -ENOMEM;
162 		goto exit_unmap;
163 	}
164 	priv = netdev_priv(dev);
165 
166 	dev->irq = irq[idx];
167 	priv->irq_flags = IRQF_SHARED;
168 	if (mem[idx]) {
169 		priv->reg_base = base;
170 		dev->base_addr = mem[idx];
171 		priv->read_reg = sja1000_isa_mem_read_reg;
172 		priv->write_reg = sja1000_isa_mem_write_reg;
173 	} else {
174 		priv->reg_base = (void __iomem *)port[idx];
175 		dev->base_addr = port[idx];
176 
177 		if (iosize == SJA1000_IOSIZE_INDIRECT) {
178 			priv->read_reg = sja1000_isa_port_read_reg_indirect;
179 			priv->write_reg = sja1000_isa_port_write_reg_indirect;
180 			spin_lock_init(&indirect_lock[idx]);
181 		} else {
182 			priv->read_reg = sja1000_isa_port_read_reg;
183 			priv->write_reg = sja1000_isa_port_write_reg;
184 		}
185 	}
186 
187 	if (clk[idx])
188 		priv->can.clock.freq = clk[idx] / 2;
189 	else if (clk[0])
190 		priv->can.clock.freq = clk[0] / 2;
191 	else
192 		priv->can.clock.freq = CLK_DEFAULT / 2;
193 
194 	if (ocr[idx] != 0xff)
195 		priv->ocr = ocr[idx];
196 	else if (ocr[0] != 0xff)
197 		priv->ocr = ocr[0];
198 	else
199 		priv->ocr = OCR_DEFAULT;
200 
201 	if (cdr[idx] != 0xff)
202 		priv->cdr = cdr[idx];
203 	else if (cdr[0] != 0xff)
204 		priv->cdr = cdr[0];
205 	else
206 		priv->cdr = CDR_DEFAULT;
207 
208 	platform_set_drvdata(pdev, dev);
209 	SET_NETDEV_DEV(dev, &pdev->dev);
210 	dev->dev_id = idx;
211 
212 	err = register_sja1000dev(dev);
213 	if (err) {
214 		dev_err(&pdev->dev, "registering %s failed (err=%d)\n",
215 			DRV_NAME, err);
216 		goto exit_unmap;
217 	}
218 
219 	dev_info(&pdev->dev, "%s device registered (reg_base=0x%p, irq=%d)\n",
220 		 DRV_NAME, priv->reg_base, dev->irq);
221 	return 0;
222 
223  exit_unmap:
224 	if (mem[idx])
225 		iounmap(base);
226  exit_release:
227 	if (mem[idx])
228 		release_mem_region(mem[idx], iosize);
229 	else
230 		release_region(port[idx], iosize);
231  exit:
232 	return err;
233 }
234 
235 static int sja1000_isa_remove(struct platform_device *pdev)
236 {
237 	struct net_device *dev = platform_get_drvdata(pdev);
238 	struct sja1000_priv *priv = netdev_priv(dev);
239 	int idx = pdev->id;
240 
241 	unregister_sja1000dev(dev);
242 
243 	if (mem[idx]) {
244 		iounmap(priv->reg_base);
245 		release_mem_region(mem[idx], SJA1000_IOSIZE);
246 	} else {
247 		if (priv->read_reg == sja1000_isa_port_read_reg_indirect)
248 			release_region(port[idx], SJA1000_IOSIZE_INDIRECT);
249 		else
250 			release_region(port[idx], SJA1000_IOSIZE);
251 	}
252 	free_sja1000dev(dev);
253 
254 	return 0;
255 }
256 
257 static struct platform_driver sja1000_isa_driver = {
258 	.probe = sja1000_isa_probe,
259 	.remove = sja1000_isa_remove,
260 	.driver = {
261 		.name = DRV_NAME,
262 	},
263 };
264 
265 static int __init sja1000_isa_init(void)
266 {
267 	int idx, err;
268 
269 	for (idx = 0; idx < MAXDEV; idx++) {
270 		if ((port[idx] || mem[idx]) && irq[idx]) {
271 			sja1000_isa_devs[idx] =
272 				platform_device_alloc(DRV_NAME, idx);
273 			if (!sja1000_isa_devs[idx]) {
274 				err = -ENOMEM;
275 				goto exit_free_devices;
276 			}
277 			err = platform_device_add(sja1000_isa_devs[idx]);
278 			if (err) {
279 				platform_device_put(sja1000_isa_devs[idx]);
280 				goto exit_free_devices;
281 			}
282 			pr_debug("%s: platform device %d: port=%#lx, mem=%#lx, "
283 				 "irq=%d\n",
284 				 DRV_NAME, idx, port[idx], mem[idx], irq[idx]);
285 		} else if (idx == 0 || port[idx] || mem[idx]) {
286 				pr_err("%s: insufficient parameters supplied\n",
287 				       DRV_NAME);
288 				err = -EINVAL;
289 				goto exit_free_devices;
290 		}
291 	}
292 
293 	err = platform_driver_register(&sja1000_isa_driver);
294 	if (err)
295 		goto exit_free_devices;
296 
297 	pr_info("Legacy %s driver for max. %d devices registered\n",
298 		DRV_NAME, MAXDEV);
299 
300 	return 0;
301 
302 exit_free_devices:
303 	while (--idx >= 0) {
304 		if (sja1000_isa_devs[idx])
305 			platform_device_unregister(sja1000_isa_devs[idx]);
306 	}
307 
308 	return err;
309 }
310 
311 static void __exit sja1000_isa_exit(void)
312 {
313 	int idx;
314 
315 	platform_driver_unregister(&sja1000_isa_driver);
316 	for (idx = 0; idx < MAXDEV; idx++) {
317 		if (sja1000_isa_devs[idx])
318 			platform_device_unregister(sja1000_isa_devs[idx]);
319 	}
320 }
321 
322 module_init(sja1000_isa_init);
323 module_exit(sja1000_isa_exit);
324