2 EIB PXA serial port driver
4 Copyright (C) 2000 Bernd Thallner <bernd@kangaroo.at>
5 Copyright (C) 2005-2008 Martin Koegler <mkoegler@auto.tuwien.ac.at>
6 Ported to PXA by Pascual Pérez based in PXA.c of kernel 2.6.19
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/device.h>
26 #include <linux/version.h>
28 #include <linux/serial_reg.h>
29 #include <linux/interrupt.h>
30 #include <linux/sched.h>
32 #include <asm/arch/pxa-regs.h>
33 #include <asm/arch/hardware.h>
35 #include "eib-common.h"
45 #define to_eib_config(d) container_of(d, eib_config, dev)
47 #define MAX_DEVICE_COUNT 3
49 /* private minor number use count */
50 static eib_config devs
[MAX_DEVICE_COUNT
] = {
51 {.port
= 0x40100000,.irq
= 22,.base
= 14745600},
52 {.port
= 0x40200000,.irq
= 21,.base
= 14745600},
53 {.port
= 0x40700000,.irq
= 20,.base
= 14745600},
56 /* These macros receive the base address and offset toghether but in PXA
57 the offset must be word aligned */
60 #define OUTB(dato,dir) *( (volatile unsigned int *) (io_p2v(( ((dir)&0xFFFFFFF0)+(((dir)&0x0000000F)<<2) )) ))= (unsigned int)dato
61 #define INB(dir) *((volatile unsigned int *) (io_p2v((((dir)&0xFFFFFFF0)+(((dir)&0x0000000F)<<2) ))))
65 show_port (struct device
*dev
, struct device_attribute
*attr
, char *buf
)
67 eib_config
*conf
= to_eib_config (dev
);
71 return snprintf (buf
, PAGE_SIZE
, "%x\n", conf
->port
);
75 store_port (struct device
*dev
, struct device_attribute
*attr
,
76 const char *buf
, size_t count
)
78 eib_config
*conf
= to_eib_config (dev
);
82 conf
->port
= (int) simple_strtol (buf
, NULL
, 16);
87 show_irq (struct device
*dev
, struct device_attribute
*attr
, char *buf
)
89 eib_config
*conf
= to_eib_config (dev
);
93 return snprintf (buf
, PAGE_SIZE
, "%d\n", conf
->irq
);
97 store_irq (struct device
*dev
, struct device_attribute
*attr
, const char *buf
,
100 eib_config
*conf
= to_eib_config (dev
);
104 conf
->irq
= (int) simple_strtol (buf
, NULL
, 10);
109 show_base (struct device
*dev
, struct device_attribute
*attr
, char *buf
)
111 eib_config
*conf
= to_eib_config (dev
);
115 return snprintf (buf
, PAGE_SIZE
, "%ld\n", conf
->base
);
119 store_base (struct device
*dev
, struct device_attribute
*attr
,
120 const char *buf
, size_t count
)
122 eib_config
*conf
= to_eib_config (dev
);
126 conf
->base
= (int) simple_strtol (buf
, NULL
, 10);
134 show_porttype (struct device
*dev
, struct device_attribute
*attr
, char *buf
)
136 eib_config
*conf
= to_eib_config (dev
);
140 return snprintf (buf
, PAGE_SIZE
, "pxa\n");
143 static DEVICE_ATTR (port
, S_IRUGO
| S_IWUSR
, show_port
, store_port
);
144 static DEVICE_ATTR (irq
, S_IRUGO
| S_IWUSR
, show_irq
, store_irq
);
145 static DEVICE_ATTR (base
, S_IRUGO
| S_IWUSR
, show_base
, store_base
);
146 static DEVICE_ATTR (porttype
, S_IRUGO
| S_IWUSR
, show_porttype
, NULL
);
154 eib_handler_t handler
;
158 unsigned char old_dll
;
159 unsigned char old_dlh
;
160 unsigned char old_lcr
;
161 unsigned char old_mcr
;
165 eib_setRTS (eib_lowlevel
* dev
)
167 OUTB (UART_MCR_DTR
| UART_MCR_RTS
| UART_MCR_OUT2
, dev
->port
+ UART_MCR
);
171 eib_clrRTS (eib_lowlevel
* dev
)
173 OUTB (UART_MCR_DTR
| UART_MCR_OUT2
, dev
->port
+ UART_MCR
);
177 eib_getCTS (eib_lowlevel
* dev
)
179 return INB (dev
->port
+ UART_MSR
) & UART_MSR_CTS
;
183 eib_send (eib_lowlevel
* dev
, uint8_t val
)
185 OUTB (val
, dev
->port
+ UART_TX
);
189 eib_recv (eib_lowlevel
* dev
)
191 return INB (dev
->port
+ UART_RX
);
195 eib_overrun (eib_lowlevel
* dev
)
197 return INB (dev
->port
+ UART_LSR
) & UART_LSR_OE
;
201 eib_send_finished (eib_lowlevel
* dev
)
203 return (INB (dev
->port
+ UART_LSR
) & UART_LSR_TEMT
);
206 static enum eib_reason
207 eib_getserialint (eib_lowlevel
* dev
)
209 int id
= INB (dev
->port
+ UART_IIR
);
211 if (~id
& UART_IIR_NO_INT
)
213 if ((id
& UART_IIR_ID
) == UART_IIR_RDI
)
216 if ((id
& UART_IIR_MSI
) == UART_IIR_MSI
)
217 if (INB (dev
->port
+ UART_MSR
) & UART_MSR_DCTS
)
226 /*********************************************************************
227 ** Name : init_serial
228 ** Purpose : No serial driver used/this module programs the UART
229 ** itself (Speed: 9600Baud, 8 Databits, 1 Stoppbit)
230 ********************************************************************/
232 eib_init_serial (eib_lowlevel
* dev
)
234 int divisor
= dev
->base
/ (16 * 9600);
235 OUTB (0x00, dev
->port
+ UART_IER
);
236 dev
->old_lcr
= INB (dev
->port
+ UART_LCR
); /* save old line control reg */
238 OUTB (UART_LCR_DLAB
, dev
->port
+ UART_LCR
); /* set divisor latch access bit in line control reg */
239 dev
->old_dll
= INB (dev
->port
+ UART_DLL
); /* save divisor latch low */
240 dev
->old_dlh
= INB (dev
->port
+ UART_DLM
); /* save divisor latch high
241 * 115200 / Divisorlatch = speed
243 OUTB (divisor
& 0xff, dev
->port
+ UART_DLL
); /* write 0x0c to divisor latch low */
244 OUTB ((divisor
>> 8) & 0xff, dev
->port
+ UART_DLM
); /* write 0x00 to divisor latch high
248 OUTB (UART_LCR_WLEN8
, dev
->port
+ UART_LCR
); /* 8 Databits in the line control reg */
249 OUTB (0x00, dev
->port
+ UART_FCR
); /* disable Fifo control reg */
250 dev
->old_mcr
= INB (dev
->port
+ UART_MCR
); /* save modem control reg */
252 OUTB (UART_MCR_DTR
| UART_MCR_OUT2
, dev
->port
+ UART_MCR
);
253 /* Set RTS, Enable GP02 neccessary for UART ints */
254 /* enable UART on PXA 0x40 */
255 OUTB (UART_IER_MSI
| UART_IER_RDI
| 0x40, dev
->port
+ UART_IER
);
256 /* Enable modem status int and receiver data int */
261 /*********************************************************************
262 ** Name : restore_serial
263 ** Purpose : Restores the settings of the UART control regs from the
264 ** variables explained above
265 ********************************************************************/
267 eib_restore_serial (eib_lowlevel
* dev
)
269 OUTB (0x00, dev
->port
+ UART_IER
);
270 OUTB (UART_LCR_DLAB
, dev
->port
+ UART_LCR
); /* enable divisor latch access */
271 OUTB (dev
->old_dll
, dev
->port
+ UART_DLL
);
272 OUTB (dev
->old_dlh
, dev
->port
+ UART_DLM
);
273 OUTB (dev
->old_lcr
, dev
->port
+ UART_LCR
);
274 OUTB (dev
->old_mcr
, dev
->port
+ UART_MCR
);
278 eib_free_serial (eib_lowlevel
* dev
)
282 free_irq (dev
->irq
, dev
);
283 release_region (dev
->port
, 0x08);
284 eib_port_free (&dev
->conf
->dev
);
288 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
290 eib_interrupt_handler (int irq
, void *dev_id
, struct pt_regs
*regs
)
293 eib_interrupt_handler (int irq
, void *dev_id
)
296 eib_lowlevel
*dev
= (eib_lowlevel
*) dev_id
;
297 enum eib_reason reason
;
299 spin_lock (&dev
->irqlock
);
301 reason
= eib_getserialint (dev
);
302 if (reason
!= EIB_OTHER
)
303 dev
->handler (dev
->data
, reason
);
304 spin_unlock (&dev
->irqlock
);
306 return (reason
== EIB_OTHER
? IRQ_NONE
: IRQ_HANDLED
);
309 static eib_lowlevel
*
310 eib_create_serial (struct device
*device
, const char *name
,
311 eib_handler_t handler
, void *data
)
315 eib_config
*d
= to_eib_config (device
);
317 dev
= (void *) kmalloc (sizeof (eib_lowlevel
), GFP_KERNEL
);
319 return ERR_PTR (-ENOMEM
);
325 dev
->handler
= handler
;
327 spin_lock_init (&dev
->irqlock
);
329 if (!request_region (dev
->port
, 0x08, name
))
333 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
334 (dev
->irq
, eib_interrupt_handler
, SA_INTERRUPT
| SA_SHIRQ
, name
,
336 (dev
->irq
, eib_interrupt_handler
, IRQF_DISABLED
| IRQF_SHARED
, name
,
340 release_region (dev
->port
, 0x08);
348 return ERR_PTR (-ENODEV
);
351 static eib_port eib_serial
= {
352 .setRTS
= eib_setRTS
,
353 .clrRTS
= eib_clrRTS
,
354 .getCTS
= eib_getCTS
,
357 .open_port
= eib_init_serial
,
358 .close_port
= eib_restore_serial
,
359 .getserialint
= eib_getserialint
,
360 .overrun
= eib_overrun
,
361 .send_finished
= eib_send_finished
,
362 .free_serial
= eib_free_serial
,
363 .owner
= THIS_MODULE
,
367 register_port (struct device
*dev
)
371 ret
= eib_port_register (dev
, &eib_create_serial
, &eib_serial
);
374 ret
= device_create_file (dev
, &dev_attr_port
);
377 ret
= device_create_file (dev
, &dev_attr_irq
);
380 ret
= device_create_file (dev
, &dev_attr_base
);
383 ret
= device_create_file (dev
, &dev_attr_porttype
);
389 device_remove_file (dev
, &dev_attr_base
);
391 device_remove_file (dev
, &dev_attr_irq
);
393 device_remove_file (dev
, &dev_attr_port
);
395 eib_port_unregister (dev
);
400 deregister_port (struct device
*dev
)
402 device_remove_file (dev
, &dev_attr_porttype
);
403 device_remove_file (dev
, &dev_attr_base
);
404 device_remove_file (dev
, &dev_attr_irq
);
405 device_remove_file (dev
, &dev_attr_port
);
406 eib_port_unregister (dev
);
414 for (i
= 0; i
< MAX_DEVICE_COUNT
; i
++)
416 retval
= register_port (&devs
[i
].dev
);
423 deregister_port (&devs
[i
].dev
);
428 eib_pxa_cleanup (void)
431 for (i
= 0; i
< MAX_DEVICE_COUNT
; i
++)
432 deregister_port (&devs
[i
].dev
);
435 MODULE_LICENSE ("GPL");
436 MODULE_AUTHOR ("Bernd Thallner, bernd@kangaroo.at");
437 MODULE_AUTHOR ("Martin Kögler <mkoegler@auto.tuwien.ac.at>");
438 MODULE_AUTHOR ("Pascual Pérez <pperez@disca.upv.es>");
439 MODULE_DESCRIPTION ("EIB port driver for PXA");
441 module_init (eib_pxa_init
);
442 module_exit (eib_pxa_cleanup
);