1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright (C) 2008 Sebastian Haas (initial chardev implementation)
4*4882a593Smuzhiyun * Copyright (C) 2010 Markus Plessing <plessing@ems-wuensche.com>
5*4882a593Smuzhiyun * Rework for mainline by Oliver Hartkopp <socketcan@hartkopp.net>
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #include <linux/kernel.h>
9*4882a593Smuzhiyun #include <linux/module.h>
10*4882a593Smuzhiyun #include <linux/interrupt.h>
11*4882a593Smuzhiyun #include <linux/netdevice.h>
12*4882a593Smuzhiyun #include <linux/delay.h>
13*4882a593Smuzhiyun #include <linux/io.h>
14*4882a593Smuzhiyun #include <pcmcia/cistpl.h>
15*4882a593Smuzhiyun #include <pcmcia/ds.h>
16*4882a593Smuzhiyun #include <linux/can.h>
17*4882a593Smuzhiyun #include <linux/can/dev.h>
18*4882a593Smuzhiyun #include "sja1000.h"
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun #define DRV_NAME "ems_pcmcia"
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun MODULE_AUTHOR("Markus Plessing <plessing@ems-wuensche.com>");
23*4882a593Smuzhiyun MODULE_DESCRIPTION("Socket-CAN driver for EMS CPC-CARD cards");
24*4882a593Smuzhiyun MODULE_SUPPORTED_DEVICE("EMS CPC-CARD CAN card");
25*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun #define EMS_PCMCIA_MAX_CHAN 2
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun struct ems_pcmcia_card {
30*4882a593Smuzhiyun int channels;
31*4882a593Smuzhiyun struct pcmcia_device *pcmcia_dev;
32*4882a593Smuzhiyun struct net_device *net_dev[EMS_PCMCIA_MAX_CHAN];
33*4882a593Smuzhiyun void __iomem *base_addr;
34*4882a593Smuzhiyun };
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun #define EMS_PCMCIA_CAN_CLOCK (16000000 / 2)
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun /*
39*4882a593Smuzhiyun * The board configuration is probably following:
40*4882a593Smuzhiyun * RX1 is connected to ground.
41*4882a593Smuzhiyun * TX1 is not connected.
42*4882a593Smuzhiyun * CLKO is not connected.
43*4882a593Smuzhiyun * Setting the OCR register to 0xDA is a good idea.
44*4882a593Smuzhiyun * This means normal output mode , push-pull and the correct polarity.
45*4882a593Smuzhiyun */
46*4882a593Smuzhiyun #define EMS_PCMCIA_OCR (OCR_TX0_PUSHPULL | OCR_TX1_PUSHPULL)
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun /*
49*4882a593Smuzhiyun * In the CDR register, you should set CBP to 1.
50*4882a593Smuzhiyun * You will probably also want to set the clock divider value to 7
51*4882a593Smuzhiyun * (meaning direct oscillator output) because the second SJA1000 chip
52*4882a593Smuzhiyun * is driven by the first one CLKOUT output.
53*4882a593Smuzhiyun */
54*4882a593Smuzhiyun #define EMS_PCMCIA_CDR (CDR_CBP | CDR_CLKOUT_MASK)
55*4882a593Smuzhiyun #define EMS_PCMCIA_MEM_SIZE 4096 /* Size of the remapped io-memory */
56*4882a593Smuzhiyun #define EMS_PCMCIA_CAN_BASE_OFFSET 0x100 /* Offset where controllers starts */
57*4882a593Smuzhiyun #define EMS_PCMCIA_CAN_CTRL_SIZE 0x80 /* Memory size for each controller */
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun #define EMS_CMD_RESET 0x00 /* Perform a reset of the card */
60*4882a593Smuzhiyun #define EMS_CMD_MAP 0x03 /* Map CAN controllers into card' memory */
61*4882a593Smuzhiyun #define EMS_CMD_UMAP 0x02 /* Unmap CAN controllers from card' memory */
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun static struct pcmcia_device_id ems_pcmcia_tbl[] = {
64*4882a593Smuzhiyun PCMCIA_DEVICE_PROD_ID123("EMS_T_W", "CPC-Card", "V2.0", 0xeab1ea23,
65*4882a593Smuzhiyun 0xa338573f, 0xe4575800),
66*4882a593Smuzhiyun PCMCIA_DEVICE_NULL,
67*4882a593Smuzhiyun };
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun MODULE_DEVICE_TABLE(pcmcia, ems_pcmcia_tbl);
70*4882a593Smuzhiyun
ems_pcmcia_read_reg(const struct sja1000_priv * priv,int port)71*4882a593Smuzhiyun static u8 ems_pcmcia_read_reg(const struct sja1000_priv *priv, int port)
72*4882a593Smuzhiyun {
73*4882a593Smuzhiyun return readb(priv->reg_base + port);
74*4882a593Smuzhiyun }
75*4882a593Smuzhiyun
ems_pcmcia_write_reg(const struct sja1000_priv * priv,int port,u8 val)76*4882a593Smuzhiyun static void ems_pcmcia_write_reg(const struct sja1000_priv *priv, int port,
77*4882a593Smuzhiyun u8 val)
78*4882a593Smuzhiyun {
79*4882a593Smuzhiyun writeb(val, priv->reg_base + port);
80*4882a593Smuzhiyun }
81*4882a593Smuzhiyun
ems_pcmcia_interrupt(int irq,void * dev_id)82*4882a593Smuzhiyun static irqreturn_t ems_pcmcia_interrupt(int irq, void *dev_id)
83*4882a593Smuzhiyun {
84*4882a593Smuzhiyun struct ems_pcmcia_card *card = dev_id;
85*4882a593Smuzhiyun struct net_device *dev;
86*4882a593Smuzhiyun irqreturn_t retval = IRQ_NONE;
87*4882a593Smuzhiyun int i, again;
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun /* Card not present */
90*4882a593Smuzhiyun if (readw(card->base_addr) != 0xAA55)
91*4882a593Smuzhiyun return IRQ_HANDLED;
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun do {
94*4882a593Smuzhiyun again = 0;
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun /* Check interrupt for each channel */
97*4882a593Smuzhiyun for (i = 0; i < card->channels; i++) {
98*4882a593Smuzhiyun dev = card->net_dev[i];
99*4882a593Smuzhiyun if (!dev)
100*4882a593Smuzhiyun continue;
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun if (sja1000_interrupt(irq, dev) == IRQ_HANDLED)
103*4882a593Smuzhiyun again = 1;
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun /* At least one channel handled the interrupt */
106*4882a593Smuzhiyun if (again)
107*4882a593Smuzhiyun retval = IRQ_HANDLED;
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun } while (again);
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun return retval;
112*4882a593Smuzhiyun }
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun /*
115*4882a593Smuzhiyun * Check if a CAN controller is present at the specified location
116*4882a593Smuzhiyun * by trying to set 'em into the PeliCAN mode
117*4882a593Smuzhiyun */
ems_pcmcia_check_chan(struct sja1000_priv * priv)118*4882a593Smuzhiyun static inline int ems_pcmcia_check_chan(struct sja1000_priv *priv)
119*4882a593Smuzhiyun {
120*4882a593Smuzhiyun /* Make sure SJA1000 is in reset mode */
121*4882a593Smuzhiyun ems_pcmcia_write_reg(priv, SJA1000_MOD, 1);
122*4882a593Smuzhiyun ems_pcmcia_write_reg(priv, SJA1000_CDR, CDR_PELICAN);
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun /* read reset-values */
125*4882a593Smuzhiyun if (ems_pcmcia_read_reg(priv, SJA1000_CDR) == CDR_PELICAN)
126*4882a593Smuzhiyun return 1;
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun return 0;
129*4882a593Smuzhiyun }
130*4882a593Smuzhiyun
ems_pcmcia_del_card(struct pcmcia_device * pdev)131*4882a593Smuzhiyun static void ems_pcmcia_del_card(struct pcmcia_device *pdev)
132*4882a593Smuzhiyun {
133*4882a593Smuzhiyun struct ems_pcmcia_card *card = pdev->priv;
134*4882a593Smuzhiyun struct net_device *dev;
135*4882a593Smuzhiyun int i;
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun free_irq(pdev->irq, card);
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun for (i = 0; i < card->channels; i++) {
140*4882a593Smuzhiyun dev = card->net_dev[i];
141*4882a593Smuzhiyun if (!dev)
142*4882a593Smuzhiyun continue;
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun printk(KERN_INFO "%s: removing %s on channel #%d\n",
145*4882a593Smuzhiyun DRV_NAME, dev->name, i);
146*4882a593Smuzhiyun unregister_sja1000dev(dev);
147*4882a593Smuzhiyun free_sja1000dev(dev);
148*4882a593Smuzhiyun }
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun writeb(EMS_CMD_UMAP, card->base_addr);
151*4882a593Smuzhiyun iounmap(card->base_addr);
152*4882a593Smuzhiyun kfree(card);
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun pdev->priv = NULL;
155*4882a593Smuzhiyun }
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun /*
158*4882a593Smuzhiyun * Probe PCI device for EMS CAN signature and register each available
159*4882a593Smuzhiyun * CAN channel to SJA1000 Socket-CAN subsystem.
160*4882a593Smuzhiyun */
ems_pcmcia_add_card(struct pcmcia_device * pdev,unsigned long base)161*4882a593Smuzhiyun static int ems_pcmcia_add_card(struct pcmcia_device *pdev, unsigned long base)
162*4882a593Smuzhiyun {
163*4882a593Smuzhiyun struct sja1000_priv *priv;
164*4882a593Smuzhiyun struct net_device *dev;
165*4882a593Smuzhiyun struct ems_pcmcia_card *card;
166*4882a593Smuzhiyun int err, i;
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun /* Allocating card structures to hold addresses, ... */
169*4882a593Smuzhiyun card = kzalloc(sizeof(struct ems_pcmcia_card), GFP_KERNEL);
170*4882a593Smuzhiyun if (!card)
171*4882a593Smuzhiyun return -ENOMEM;
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun pdev->priv = card;
174*4882a593Smuzhiyun card->channels = 0;
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun card->base_addr = ioremap(base, EMS_PCMCIA_MEM_SIZE);
177*4882a593Smuzhiyun if (!card->base_addr) {
178*4882a593Smuzhiyun err = -ENOMEM;
179*4882a593Smuzhiyun goto failure_cleanup;
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun /* Check for unique EMS CAN signature */
183*4882a593Smuzhiyun if (readw(card->base_addr) != 0xAA55) {
184*4882a593Smuzhiyun err = -ENODEV;
185*4882a593Smuzhiyun goto failure_cleanup;
186*4882a593Smuzhiyun }
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun /* Request board reset */
189*4882a593Smuzhiyun writeb(EMS_CMD_RESET, card->base_addr);
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun /* Make sure CAN controllers are mapped into card's memory space */
192*4882a593Smuzhiyun writeb(EMS_CMD_MAP, card->base_addr);
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun /* Detect available channels */
195*4882a593Smuzhiyun for (i = 0; i < EMS_PCMCIA_MAX_CHAN; i++) {
196*4882a593Smuzhiyun dev = alloc_sja1000dev(0);
197*4882a593Smuzhiyun if (!dev) {
198*4882a593Smuzhiyun err = -ENOMEM;
199*4882a593Smuzhiyun goto failure_cleanup;
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun card->net_dev[i] = dev;
203*4882a593Smuzhiyun priv = netdev_priv(dev);
204*4882a593Smuzhiyun priv->priv = card;
205*4882a593Smuzhiyun SET_NETDEV_DEV(dev, &pdev->dev);
206*4882a593Smuzhiyun dev->dev_id = i;
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun priv->irq_flags = IRQF_SHARED;
209*4882a593Smuzhiyun dev->irq = pdev->irq;
210*4882a593Smuzhiyun priv->reg_base = card->base_addr + EMS_PCMCIA_CAN_BASE_OFFSET +
211*4882a593Smuzhiyun (i * EMS_PCMCIA_CAN_CTRL_SIZE);
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun /* Check if channel is present */
214*4882a593Smuzhiyun if (ems_pcmcia_check_chan(priv)) {
215*4882a593Smuzhiyun priv->read_reg = ems_pcmcia_read_reg;
216*4882a593Smuzhiyun priv->write_reg = ems_pcmcia_write_reg;
217*4882a593Smuzhiyun priv->can.clock.freq = EMS_PCMCIA_CAN_CLOCK;
218*4882a593Smuzhiyun priv->ocr = EMS_PCMCIA_OCR;
219*4882a593Smuzhiyun priv->cdr = EMS_PCMCIA_CDR;
220*4882a593Smuzhiyun priv->flags |= SJA1000_CUSTOM_IRQ_HANDLER;
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun /* Register SJA1000 device */
223*4882a593Smuzhiyun err = register_sja1000dev(dev);
224*4882a593Smuzhiyun if (err) {
225*4882a593Smuzhiyun free_sja1000dev(dev);
226*4882a593Smuzhiyun goto failure_cleanup;
227*4882a593Smuzhiyun }
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun card->channels++;
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun printk(KERN_INFO "%s: registered %s on channel "
232*4882a593Smuzhiyun "#%d at 0x%p, irq %d\n", DRV_NAME, dev->name,
233*4882a593Smuzhiyun i, priv->reg_base, dev->irq);
234*4882a593Smuzhiyun } else
235*4882a593Smuzhiyun free_sja1000dev(dev);
236*4882a593Smuzhiyun }
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun if (!card->channels) {
239*4882a593Smuzhiyun err = -ENODEV;
240*4882a593Smuzhiyun goto failure_cleanup;
241*4882a593Smuzhiyun }
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun err = request_irq(pdev->irq, &ems_pcmcia_interrupt, IRQF_SHARED,
244*4882a593Smuzhiyun DRV_NAME, card);
245*4882a593Smuzhiyun if (!err)
246*4882a593Smuzhiyun return 0;
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun failure_cleanup:
249*4882a593Smuzhiyun ems_pcmcia_del_card(pdev);
250*4882a593Smuzhiyun return err;
251*4882a593Smuzhiyun }
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun /*
254*4882a593Smuzhiyun * Setup PCMCIA socket and probe for EMS CPC-CARD
255*4882a593Smuzhiyun */
ems_pcmcia_probe(struct pcmcia_device * dev)256*4882a593Smuzhiyun static int ems_pcmcia_probe(struct pcmcia_device *dev)
257*4882a593Smuzhiyun {
258*4882a593Smuzhiyun int csval;
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun /* General socket configuration */
261*4882a593Smuzhiyun dev->config_flags |= CONF_ENABLE_IRQ;
262*4882a593Smuzhiyun dev->config_index = 1;
263*4882a593Smuzhiyun dev->config_regs = PRESENT_OPTION;
264*4882a593Smuzhiyun
265*4882a593Smuzhiyun /* The io structure describes IO port mapping */
266*4882a593Smuzhiyun dev->resource[0]->end = 16;
267*4882a593Smuzhiyun dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
268*4882a593Smuzhiyun dev->resource[1]->end = 16;
269*4882a593Smuzhiyun dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_16;
270*4882a593Smuzhiyun dev->io_lines = 5;
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun /* Allocate a memory window */
273*4882a593Smuzhiyun dev->resource[2]->flags =
274*4882a593Smuzhiyun (WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE);
275*4882a593Smuzhiyun dev->resource[2]->start = dev->resource[2]->end = 0;
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun csval = pcmcia_request_window(dev, dev->resource[2], 0);
278*4882a593Smuzhiyun if (csval) {
279*4882a593Smuzhiyun dev_err(&dev->dev, "pcmcia_request_window failed (err=%d)\n",
280*4882a593Smuzhiyun csval);
281*4882a593Smuzhiyun return 0;
282*4882a593Smuzhiyun }
283*4882a593Smuzhiyun
284*4882a593Smuzhiyun csval = pcmcia_map_mem_page(dev, dev->resource[2], dev->config_base);
285*4882a593Smuzhiyun if (csval) {
286*4882a593Smuzhiyun dev_err(&dev->dev, "pcmcia_map_mem_page failed (err=%d)\n",
287*4882a593Smuzhiyun csval);
288*4882a593Smuzhiyun return 0;
289*4882a593Smuzhiyun }
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun csval = pcmcia_enable_device(dev);
292*4882a593Smuzhiyun if (csval) {
293*4882a593Smuzhiyun dev_err(&dev->dev, "pcmcia_enable_device failed (err=%d)\n",
294*4882a593Smuzhiyun csval);
295*4882a593Smuzhiyun return 0;
296*4882a593Smuzhiyun }
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun ems_pcmcia_add_card(dev, dev->resource[2]->start);
299*4882a593Smuzhiyun return 0;
300*4882a593Smuzhiyun }
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun /*
303*4882a593Smuzhiyun * Release claimed resources
304*4882a593Smuzhiyun */
ems_pcmcia_remove(struct pcmcia_device * dev)305*4882a593Smuzhiyun static void ems_pcmcia_remove(struct pcmcia_device *dev)
306*4882a593Smuzhiyun {
307*4882a593Smuzhiyun ems_pcmcia_del_card(dev);
308*4882a593Smuzhiyun pcmcia_disable_device(dev);
309*4882a593Smuzhiyun }
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun static struct pcmcia_driver ems_pcmcia_driver = {
312*4882a593Smuzhiyun .name = DRV_NAME,
313*4882a593Smuzhiyun .probe = ems_pcmcia_probe,
314*4882a593Smuzhiyun .remove = ems_pcmcia_remove,
315*4882a593Smuzhiyun .id_table = ems_pcmcia_tbl,
316*4882a593Smuzhiyun };
317*4882a593Smuzhiyun module_pcmcia_driver(ems_pcmcia_driver);
318