4 * Copyright (C) 2005, 2006 Nokia Corporation
5 * Written by: Paul Mundt <paul.mundt@nokia.com> and
6 * Roman Tereshonkov <roman.tereshonkov@nokia.com>
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
12 #include <linux/init.h>
13 #include <linux/interrupt.h>
14 #include <linux/err.h>
15 #include <linux/module.h>
16 #include <asm/arch/sti.h>
18 #define STI_READ_BUFFER_SIZE 1024
19 #define sti_buf_pos(pos) ((sti_crb->bufpos + (pos)) % \
22 static struct sti_cycle_buffer {
29 * sti_read_packet - STI read packet (read an entire STI packet)
30 * @buf: Buffer to store the packet.
31 * @maxsize: Maximum size requested.
33 * This reads in a single completed STI packet from the RX FIFOs and
34 * places it in @buf for further processing.
36 * The return value is < 0 on error, and >= 0 for the number of bytes
37 * actually read. As per the STI specification, we require a 0xC1 to
38 * indicate the end of the packet, and we don't return the packet until
39 * we've read the entire thing in.
41 * Due to the size of the FIFOs, it's unrealistic to constantly drain
42 * this for 1 or 2 bytes at a time, so we assemble it here and return
45 int sti_read_packet(unsigned char *buf, int maxsize)
51 if (!sti_crb->datalen)
54 pos = sti_buf_pos(sti_crb->datalen - 1);
56 if (sti_crb->buf[pos] == 0xC1) {
59 for (i = 0; i < sti_crb->datalen && i < maxsize; i++) {
61 buf[i] = sti_crb->buf[pos];
64 sti_crb->bufpos = sti_buf_pos(i);
65 sti_crb->datalen -= i;
72 EXPORT_SYMBOL(sti_read_packet);
74 static void sti_fifo_irq(unsigned long arg)
76 /* If there is data read it */
77 while (!(sti_readl(STI_RX_STATUS) & STI_RXFIFO_EMPTY)) {
78 unsigned int pos = sti_buf_pos(sti_crb->datalen);
80 sti_crb->buf[pos] = sti_readl(STI_RX_DR);
84 sti_ack_irq(STI_RX_INT);
87 static int __init sti_fifo_init(void)
92 size = sizeof(struct sti_cycle_buffer) + STI_READ_BUFFER_SIZE;
93 sti_crb = kmalloc(size, GFP_KERNEL);
97 sti_crb->bufpos = sti_crb->datalen = 0;
98 sti_crb->buf = (unsigned char *)(sti_crb + sizeof(*sti_crb));
100 ret = sti_request_irq(STI_RX_INT, sti_fifo_irq, 0);
107 static void __exit sti_fifo_exit(void)
109 sti_free_irq(STI_RX_INT);
113 module_init(sti_fifo_init);
114 module_exit(sti_fifo_exit);
116 MODULE_AUTHOR("Paul Mundt, Roman Tereshonkov");
117 MODULE_LICENSE("GPL");