2 * arch/ubicom32/mach-common/usb_tio.c
3 * Linux side Ubicom USB TIO driver
5 * (C) Copyright 2009, Ubicom, Inc.
7 * This file is part of the Ubicom32 Linux Kernel Port.
9 * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10 * it and/or modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation, either version 2 of the
12 * License, or (at your option) any later version.
14 * The Ubicom32 Linux Kernel Port is distributed in the hope that it
15 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with the Ubicom32 Linux Kernel Port. If not,
21 * see <http://www.gnu.org/licenses/>.
23 * Ubicom32 implementation derived from (with many thanks):
28 #include <linux/module.h>
29 #include <linux/spinlock.h>
30 #include <linux/slab.h>
31 #include <asm/devtree.h>
35 static DEFINE_SPINLOCK(tio_lock);
36 #define USB_TIO_LOCK(lock, flag) spin_lock_irqsave(lock, flag)
37 #define USB_TIO_UNLOCK(lock, flag) spin_unlock_irqrestore(lock, flag)
38 #define USB_TIO_LOCK_ISLOCKED(lock) spin_try_lock(lock)
40 #define USB_TIO_LOCK(lock, flag) local_irq_save(flag)
41 #define USB_TIO_UNLOCK(lock, flag) local_irq_restore(flag)
44 spinlock_t usb_tio_lock;
47 * usb_tio_set_hrt_interrupt()
49 static inline void usb_tio_set_hrt_interrupt(void)
51 ubicom32_set_interrupt(usb_node->dn.sendirq);
54 static inline void usb_tio_wait_hrt(void)
56 while (unlikely(usb_node->pdesc));
59 #if defined(USB_TIO_DEBUG)
60 static void usb_tio_request_verify_magic(volatile struct usb_tio_request *req)
62 BUG_ON(req->magic != USB_TIO_REQUEST_MAGIC2);
65 static void usb_tio_request_clear_magic(volatile struct usb_tio_request *req)
71 static void usb_tio_request_set_magic(volatile struct usb_tio_request *req)
73 req->magic = USB_TIO_REQUEST_MAGIC1;
77 * usb_tio_commit_request()
79 static inline void usb_tio_commit_request(volatile struct usb_tio_request *request)
82 usb_node->pdesc = request;
85 * next thing to do is alway checking if (usb_node->pdesc == NULL)
86 * to see if the request is done, so add a mb() here
89 usb_tio_set_hrt_interrupt();
94 * Synchronously read 16 bits.
96 u8_t usb_tio_read_u16(u32_t address, u16_t *data)
98 volatile struct usb_tio_request *tio_req = &usb_node->request;
102 * Wait for any previous request to complete and then make this request.
104 USB_TIO_LOCK(&tio_lock, flag);
108 * Fill in the request.
110 tio_req->address = address;
111 tio_req->cmd = USB_TIO_READ16_SYNC;
112 USB_TIO_REQUEST_SET_MAGIC(tio_req);
113 usb_tio_commit_request(tio_req);
116 * Wait for the result to show up.
119 USB_TIO_REQUEST_VERIFY_MAGIC(tio_req);
120 *data = (u16_t)tio_req->data;
121 USB_TIO_REQUEST_CLEAR_MAGIC(tio_req);
122 USB_TIO_UNLOCK(&tio_lock, flag);
128 * Synchronously read 16 bits.
130 u8_t usb_tio_read_u8(u32_t address, u8_t *data)
132 volatile struct usb_tio_request *tio_req = &usb_node->request;
136 * Wait for any previous request to complete and then make this request.
138 USB_TIO_LOCK(&tio_lock, flag);
142 * Fill in the request.
144 tio_req->address = address;
145 tio_req->cmd = USB_TIO_READ8_SYNC;
146 USB_TIO_REQUEST_SET_MAGIC(tio_req);
151 usb_tio_commit_request(tio_req);
154 * Wait for the result to show up.
157 USB_TIO_REQUEST_VERIFY_MAGIC(tio_req);
158 *data = (u8_t)tio_req->data;
159 USB_TIO_REQUEST_CLEAR_MAGIC(tio_req);
160 USB_TIO_UNLOCK(&tio_lock, flag);
165 * usb_tio_write_u16()
166 * Asynchronously write 16 bits.
168 u8_t usb_tio_write_u16(u32_t address, u16_t data)
170 volatile struct usb_tio_request *tio_req = &usb_node->request;
174 * Wait for any previous write or pending read to complete.
176 USB_TIO_LOCK(&tio_lock, flag);
179 tio_req->address = address;
180 tio_req->data = data;
181 tio_req->cmd = USB_TIO_WRITE16_ASYNC;
182 USB_TIO_REQUEST_SET_MAGIC(tio_req);
187 usb_tio_commit_request(tio_req);
188 USB_TIO_UNLOCK(&tio_lock, flag);
194 * Asynchronously write 8 bits.
196 u8_t usb_tio_write_u8(u32_t address, u8_t data)
198 volatile struct usb_tio_request *tio_req = &usb_node->request;
202 * Wait for any previous write or pending read to complete.
204 USB_TIO_LOCK(&tio_lock, flag);
207 tio_req->address = address;
208 tio_req->data = data;
209 tio_req->cmd = USB_TIO_WRITE8_ASYNC;
210 USB_TIO_REQUEST_SET_MAGIC(tio_req);
215 usb_tio_commit_request(tio_req);
216 USB_TIO_UNLOCK(&tio_lock, flag);
221 * usb_tio_read_fifo()
222 * Synchronously read FIFO.
224 u8_t usb_tio_read_fifo(u32_t address, u32_t buffer, u32_t bytes)
226 volatile struct usb_tio_request *tio_req = &usb_node->request;
230 * Wait for any previous request to complete and then make this request.
232 USB_TIO_LOCK(&tio_lock, flag);
236 * Fill in the request.
238 tio_req->address = address;
239 tio_req->cmd = USB_TIO_READ_FIFO_SYNC;
240 tio_req->buffer = buffer;
241 tio_req->transfer_length = bytes;
242 USB_TIO_REQUEST_SET_MAGIC(tio_req);
247 usb_tio_commit_request(tio_req);
250 * Wait for the result to show up.
253 USB_TIO_REQUEST_VERIFY_MAGIC(tio_req);
254 USB_TIO_REQUEST_CLEAR_MAGIC(tio_req);
255 USB_TIO_UNLOCK(&tio_lock, flag);
260 * usb_tio_write_fifo()
261 * Synchronously write 32 bits.
263 u8_t usb_tio_write_fifo(u32_t address, u32_t buffer, u32_t bytes)
265 volatile struct usb_tio_request *tio_req = &usb_node->request;
268 USB_TIO_LOCK(&tio_lock, flag);
271 tio_req->address = address;
272 tio_req->buffer = buffer;
273 tio_req->cmd = USB_TIO_WRITE_FIFO_SYNC;
274 tio_req->transfer_length = bytes;
275 USB_TIO_REQUEST_SET_MAGIC(tio_req);
279 usb_tio_commit_request(tio_req);
282 * Wait for the result to show up.
285 USB_TIO_REQUEST_VERIFY_MAGIC(tio_req);
286 USB_TIO_REQUEST_CLEAR_MAGIC(tio_req);
287 USB_TIO_UNLOCK(&tio_lock, flag);
292 * usb_tio_write_fifo_async()
293 * Asynchronously write 32 bits.
295 u8_t usb_tio_write_fifo_async(u32_t address, u32_t buffer, u32_t bytes)
297 volatile struct usb_tio_request *tio_req = &usb_node->request;
300 USB_TIO_LOCK(&tio_lock, flag);
303 tio_req->address = address;
306 * Is it necessary to make a local copy of the buffer? Any chance the URB is aborted before TIO finished the FIFO write?
308 tio_req->buffer = buffer;
309 tio_req->cmd = USB_TIO_WRITE_FIFO_SYNC;
310 tio_req->transfer_length = bytes;
311 USB_TIO_REQUEST_SET_MAGIC(tio_req);
315 usb_tio_commit_request(tio_req);
316 USB_TIO_UNLOCK(&tio_lock, flag);
321 * usb_tio_read_int_status()
322 * read and clear the interrupt status registers
324 void usb_tio_read_int_status(u8_t *int_usb, u16_t *int_tx, u16_t *int_rx)
328 * clear the interrupt must be syncronized with the TIO thread to prevent the racing condiiton
329 * that TIO thread try to set it at same time
332 "1: bset (%0), (%0), #0 \n\t" \
335 : "a" (&usb_node->usb_vp_control)
339 *int_usb = usb_node->usb_vp_hw_int_usb;
340 *int_tx = cpu_to_le16(usb_node->usb_vp_hw_int_tx);
341 *int_rx = cpu_to_le16(usb_node->usb_vp_hw_int_rx);
343 //printk(KERN_INFO "int read %x, %x, %x\n", *int_usb, *int_tx, *int_rx);
346 * The interrupt status register is read-clean, so clear it now
348 usb_node->usb_vp_hw_int_usb = 0;
349 usb_node->usb_vp_hw_int_tx = 0;
350 usb_node->usb_vp_hw_int_rx = 0;
353 * release the lock bit
355 usb_node->usb_vp_control &= 0xfffe;