aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-pxa/generic.c18
-rw-r--r--arch/arm/mach-pxa/lubbock.c20
-rw-r--r--arch/arm/mach-pxa/mainstone.c25
-rw-r--r--drivers/net/irda/Kconfig10
-rw-r--r--drivers/net/irda/Makefile1
-rw-r--r--drivers/net/irda/pxaficp_ir.c871
-rw-r--r--include/asm-arm/arch-pxa/irda.h17
-rw-r--r--include/asm-arm/arch-pxa/pxa-regs.h2
8 files changed, 962 insertions, 2 deletions
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index 218eb9671fa3..3248bc9b9495 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -34,6 +34,7 @@
34#include <asm/arch/udc.h> 34#include <asm/arch/udc.h>
35#include <asm/arch/pxafb.h> 35#include <asm/arch/pxafb.h>
36#include <asm/arch/mmc.h> 36#include <asm/arch/mmc.h>
37#include <asm/arch/irda.h>
37#include <asm/arch/i2c.h> 38#include <asm/arch/i2c.h>
38 39
39#include "generic.h" 40#include "generic.h"
@@ -301,6 +302,22 @@ static struct platform_device i2s_device = {
301 .num_resources = ARRAY_SIZE(i2s_resources), 302 .num_resources = ARRAY_SIZE(i2s_resources),
302}; 303};
303 304
305static u64 pxaficp_dmamask = ~(u32)0;
306
307static struct platform_device pxaficp_device = {
308 .name = "pxa2xx-ir",
309 .id = -1,
310 .dev = {
311 .dma_mask = &pxaficp_dmamask,
312 .coherent_dma_mask = 0xffffffff,
313 },
314};
315
316void __init pxa_set_ficp_info(struct pxaficp_platform_data *info)
317{
318 pxaficp_device.dev.platform_data = info;
319}
320
304static struct platform_device *devices[] __initdata = { 321static struct platform_device *devices[] __initdata = {
305 &pxamci_device, 322 &pxamci_device,
306 &udc_device, 323 &udc_device,
@@ -308,6 +325,7 @@ static struct platform_device *devices[] __initdata = {
308 &ffuart_device, 325 &ffuart_device,
309 &btuart_device, 326 &btuart_device,
310 &stuart_device, 327 &stuart_device,
328 &pxaficp_device,
311 &i2c_device, 329 &i2c_device,
312 &i2s_device, 330 &i2s_device,
313}; 331};
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 69abc7f61ed0..beccf455f796 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -35,6 +35,7 @@
35#include <asm/arch/pxa-regs.h> 35#include <asm/arch/pxa-regs.h>
36#include <asm/arch/lubbock.h> 36#include <asm/arch/lubbock.h>
37#include <asm/arch/udc.h> 37#include <asm/arch/udc.h>
38#include <asm/arch/irda.h>
38#include <asm/arch/pxafb.h> 39#include <asm/arch/pxafb.h>
39#include <asm/arch/mmc.h> 40#include <asm/arch/mmc.h>
40 41
@@ -237,11 +238,30 @@ static struct pxamci_platform_data lubbock_mci_platform_data = {
237 .init = lubbock_mci_init, 238 .init = lubbock_mci_init,
238}; 239};
239 240
241static void lubbock_irda_transceiver_mode(struct device *dev, int mode)
242{
243 unsigned long flags;
244
245 local_irq_save(flags);
246 if (mode & IR_SIRMODE) {
247 LUB_MISC_WR &= ~(1 << 4);
248 } else if (mode & IR_FIRMODE) {
249 LUB_MISC_WR |= 1 << 4;
250 }
251 local_irq_restore(flags);
252}
253
254static struct pxaficp_platform_data lubbock_ficp_platform_data = {
255 .transceiver_cap = IR_SIRMODE | IR_FIRMODE,
256 .transceiver_mode = lubbock_irda_transceiver_mode,
257};
258
240static void __init lubbock_init(void) 259static void __init lubbock_init(void)
241{ 260{
242 pxa_set_udc_info(&udc_info); 261 pxa_set_udc_info(&udc_info);
243 set_pxa_fb_info(&sharp_lm8v31); 262 set_pxa_fb_info(&sharp_lm8v31);
244 pxa_set_mci_info(&lubbock_mci_platform_data); 263 pxa_set_mci_info(&lubbock_mci_platform_data);
264 pxa_set_ficp_info(&lubbock_ficp_platform_data);
245 (void) platform_add_devices(devices, ARRAY_SIZE(devices)); 265 (void) platform_add_devices(devices, ARRAY_SIZE(devices));
246} 266}
247 267
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index 8b4a21623fc0..a48c64026e1f 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -37,6 +37,7 @@
37#include <asm/arch/audio.h> 37#include <asm/arch/audio.h>
38#include <asm/arch/pxafb.h> 38#include <asm/arch/pxafb.h>
39#include <asm/arch/mmc.h> 39#include <asm/arch/mmc.h>
40#include <asm/arch/irda.h>
40 41
41#include "generic.h" 42#include "generic.h"
42 43
@@ -294,6 +295,29 @@ static struct pxamci_platform_data mainstone_mci_platform_data = {
294 .exit = mainstone_mci_exit, 295 .exit = mainstone_mci_exit,
295}; 296};
296 297
298static void mainstone_irda_transceiver_mode(struct device *dev, int mode)
299{
300 unsigned long flags;
301
302 local_irq_save(flags);
303 if (mode & IR_SIRMODE) {
304 MST_MSCWR1 &= ~MST_MSCWR1_IRDA_FIR;
305 } else if (mode & IR_FIRMODE) {
306 MST_MSCWR1 |= MST_MSCWR1_IRDA_FIR;
307 }
308 if (mode & IR_OFF) {
309 MST_MSCWR1 = (MST_MSCWR1 & ~MST_MSCWR1_IRDA_MASK) | MST_MSCWR1_IRDA_OFF;
310 } else {
311 MST_MSCWR1 = (MST_MSCWR1 & ~MST_MSCWR1_IRDA_MASK) | MST_MSCWR1_IRDA_FULL;
312 }
313 local_irq_restore(flags);
314}
315
316static struct pxaficp_platform_data mainstone_ficp_platform_data = {
317 .transceiver_cap = IR_SIRMODE | IR_FIRMODE | IR_OFF,
318 .transceiver_mode = mainstone_irda_transceiver_mode,
319};
320
297static void __init mainstone_init(void) 321static void __init mainstone_init(void)
298{ 322{
299 /* 323 /*
@@ -313,6 +337,7 @@ static void __init mainstone_init(void)
313 set_pxa_fb_info(&toshiba_ltm035a776c); 337 set_pxa_fb_info(&toshiba_ltm035a776c);
314 338
315 pxa_set_mci_info(&mainstone_mci_platform_data); 339 pxa_set_mci_info(&mainstone_mci_platform_data);
340 pxa_set_ficp_info(&mainstone_ficp_platform_data);
316} 341}
317 342
318 343
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig
index ca5914091d3a..d54156f11e61 100644
--- a/drivers/net/irda/Kconfig
+++ b/drivers/net/irda/Kconfig
@@ -400,5 +400,15 @@ config VIA_FIR
400 To compile it as a module, choose M here: the module will be called 400 To compile it as a module, choose M here: the module will be called
401 via-ircc. 401 via-ircc.
402 402
403config PXA_FICP
404 tristate "Intel PXA2xx Internal FICP"
405 depends on ARCH_PXA && IRDA
406 help
407 Say Y or M here if you want to build support for the PXA2xx
408 built-in IRDA interface which can support both SIR and FIR.
409 This driver relies on platform specific helper routines so
410 available capabilities may vary from one PXA2xx target to
411 another.
412
403endmenu 413endmenu
404 414
diff --git a/drivers/net/irda/Makefile b/drivers/net/irda/Makefile
index 29a8bd812b21..e7a8b7f7f5dd 100644
--- a/drivers/net/irda/Makefile
+++ b/drivers/net/irda/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_SMC_IRCC_FIR) += smsc-ircc2.o
18obj-$(CONFIG_ALI_FIR) += ali-ircc.o 18obj-$(CONFIG_ALI_FIR) += ali-ircc.o
19obj-$(CONFIG_VLSI_FIR) += vlsi_ir.o 19obj-$(CONFIG_VLSI_FIR) += vlsi_ir.o
20obj-$(CONFIG_VIA_FIR) += via-ircc.o 20obj-$(CONFIG_VIA_FIR) += via-ircc.o
21obj-$(CONFIG_PXA_FICP) += pxaficp_ir.o
21# Old dongle drivers for old SIR drivers 22# Old dongle drivers for old SIR drivers
22obj-$(CONFIG_ESI_DONGLE_OLD) += esi.o 23obj-$(CONFIG_ESI_DONGLE_OLD) += esi.o
23obj-$(CONFIG_TEKRAM_DONGLE_OLD) += tekram.o 24obj-$(CONFIG_TEKRAM_DONGLE_OLD) += tekram.o
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
new file mode 100644
index 000000000000..aef80f5e7c9c
--- /dev/null
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -0,0 +1,871 @@
1/*
2 * linux/drivers/net/irda/pxaficp_ir.c
3 *
4 * Based on sa1100_ir.c by Russell King
5 *
6 * Changes copyright (C) 2003-2005 MontaVista Software, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * Infra-red driver (SIR/FIR) for the PXA2xx embedded microprocessor
13 *
14 */
15#include <linux/config.h>
16#include <linux/module.h>
17#include <linux/types.h>
18#include <linux/init.h>
19#include <linux/errno.h>
20#include <linux/netdevice.h>
21#include <linux/slab.h>
22#include <linux/rtnetlink.h>
23#include <linux/interrupt.h>
24#include <linux/dma-mapping.h>
25#include <linux/pm.h>
26
27#include <net/irda/irda.h>
28#include <net/irda/irmod.h>
29#include <net/irda/wrapper.h>
30#include <net/irda/irda_device.h>
31
32#include <asm/irq.h>
33#include <asm/dma.h>
34#include <asm/delay.h>
35#include <asm/hardware.h>
36#include <asm/arch/irda.h>
37#include <asm/arch/pxa-regs.h>
38
39#ifdef CONFIG_MACH_MAINSTONE
40#include <asm/arch/mainstone.h>
41#endif
42
43#define IrSR_RXPL_NEG_IS_ZERO (1<<4)
44#define IrSR_RXPL_POS_IS_ZERO 0x0
45#define IrSR_TXPL_NEG_IS_ZERO (1<<3)
46#define IrSR_TXPL_POS_IS_ZERO 0x0
47#define IrSR_XMODE_PULSE_1_6 (1<<2)
48#define IrSR_XMODE_PULSE_3_16 0x0
49#define IrSR_RCVEIR_IR_MODE (1<<1)
50#define IrSR_RCVEIR_UART_MODE 0x0
51#define IrSR_XMITIR_IR_MODE (1<<0)
52#define IrSR_XMITIR_UART_MODE 0x0
53
54#define IrSR_IR_RECEIVE_ON (\
55 IrSR_RXPL_NEG_IS_ZERO | \
56 IrSR_TXPL_POS_IS_ZERO | \
57 IrSR_XMODE_PULSE_3_16 | \
58 IrSR_RCVEIR_IR_MODE | \
59 IrSR_XMITIR_UART_MODE)
60
61#define IrSR_IR_TRANSMIT_ON (\
62 IrSR_RXPL_NEG_IS_ZERO | \
63 IrSR_TXPL_POS_IS_ZERO | \
64 IrSR_XMODE_PULSE_3_16 | \
65 IrSR_RCVEIR_UART_MODE | \
66 IrSR_XMITIR_IR_MODE)
67
68struct pxa_irda {
69 int speed;
70 int newspeed;
71 unsigned long last_oscr;
72
73 unsigned char *dma_rx_buff;
74 unsigned char *dma_tx_buff;
75 dma_addr_t dma_rx_buff_phy;
76 dma_addr_t dma_tx_buff_phy;
77 unsigned int dma_tx_buff_len;
78 int txdma;
79 int rxdma;
80
81 struct net_device_stats stats;
82 struct irlap_cb *irlap;
83 struct qos_info qos;
84
85 iobuff_t tx_buff;
86 iobuff_t rx_buff;
87
88 struct device *dev;
89 struct pxaficp_platform_data *pdata;
90};
91
92
93#define IS_FIR(si) ((si)->speed >= 4000000)
94#define IRDA_FRAME_SIZE_LIMIT 2047
95
96inline static void pxa_irda_fir_dma_rx_start(struct pxa_irda *si)
97{
98 DCSR(si->rxdma) = DCSR_NODESC;
99 DSADR(si->rxdma) = __PREG(ICDR);
100 DTADR(si->rxdma) = si->dma_rx_buff_phy;
101 DCMD(si->rxdma) = DCMD_INCTRGADDR | DCMD_FLOWSRC | DCMD_WIDTH1 | DCMD_BURST32 | IRDA_FRAME_SIZE_LIMIT;
102 DCSR(si->rxdma) |= DCSR_RUN;
103}
104
105inline static void pxa_irda_fir_dma_tx_start(struct pxa_irda *si)
106{
107 DCSR(si->txdma) = DCSR_NODESC;
108 DSADR(si->txdma) = si->dma_tx_buff_phy;
109 DTADR(si->txdma) = __PREG(ICDR);
110 DCMD(si->txdma) = DCMD_INCSRCADDR | DCMD_FLOWTRG | DCMD_ENDIRQEN | DCMD_WIDTH1 | DCMD_BURST32 | si->dma_tx_buff_len;
111 DCSR(si->txdma) |= DCSR_RUN;
112}
113
114/*
115 * Set the IrDA communications speed.
116 */
117static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
118{
119 unsigned long flags;
120 unsigned int divisor;
121
122 switch (speed) {
123 case 9600: case 19200: case 38400:
124 case 57600: case 115200:
125
126 /* refer to PXA250/210 Developer's Manual 10-7 */
127 /* BaudRate = 14.7456 MHz / (16*Divisor) */
128 divisor = 14745600 / (16 * speed);
129
130 local_irq_save(flags);
131
132 if (IS_FIR(si)) {
133 /* stop RX DMA */
134 DCSR(si->rxdma) &= ~DCSR_RUN;
135 /* disable FICP */
136 ICCR0 = 0;
137 pxa_set_cken(CKEN13_FICP, 0);
138
139 /* set board transceiver to SIR mode */
140 si->pdata->transceiver_mode(si->dev, IR_SIRMODE);
141
142 /* configure GPIO46/47 */
143 pxa_gpio_mode(GPIO46_STRXD_MD);
144 pxa_gpio_mode(GPIO47_STTXD_MD);
145
146 /* enable the STUART clock */
147 pxa_set_cken(CKEN5_STUART, 1);
148 }
149
150 /* disable STUART first */
151 STIER = 0;
152
153 /* access DLL & DLH */
154 STLCR |= LCR_DLAB;
155 STDLL = divisor & 0xff;
156 STDLH = divisor >> 8;
157 STLCR &= ~LCR_DLAB;
158
159 si->speed = speed;
160 STISR = IrSR_IR_RECEIVE_ON | IrSR_XMODE_PULSE_1_6;
161 STIER = IER_UUE | IER_RLSE | IER_RAVIE | IER_RTIOE;
162
163 local_irq_restore(flags);
164 break;
165
166 case 4000000:
167 local_irq_save(flags);
168
169 /* disable STUART */
170 STIER = 0;
171 STISR = 0;
172 pxa_set_cken(CKEN5_STUART, 0);
173
174 /* disable FICP first */
175 ICCR0 = 0;
176
177 /* set board transceiver to FIR mode */
178 si->pdata->transceiver_mode(si->dev, IR_FIRMODE);
179
180 /* configure GPIO46/47 */
181 pxa_gpio_mode(GPIO46_ICPRXD_MD);
182 pxa_gpio_mode(GPIO47_ICPTXD_MD);
183
184 /* enable the FICP clock */
185 pxa_set_cken(CKEN13_FICP, 1);
186
187 si->speed = speed;
188 pxa_irda_fir_dma_rx_start(si);
189 ICCR0 = ICCR0_ITR | ICCR0_RXE;
190
191 local_irq_restore(flags);
192 break;
193
194 default:
195 return -EINVAL;
196 }
197
198 return 0;
199}
200
201/* SIR interrupt service routine. */
202static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id, struct pt_regs *regs)
203{
204 struct net_device *dev = dev_id;
205 struct pxa_irda *si = netdev_priv(dev);
206 int iir, lsr, data;
207
208 iir = STIIR;
209
210 switch (iir & 0x0F) {
211 case 0x06: /* Receiver Line Status */
212 lsr = STLSR;
213 while (lsr & LSR_FIFOE) {
214 data = STRBR;
215 if (lsr & (LSR_OE | LSR_PE | LSR_FE | LSR_BI)) {
216 printk(KERN_DEBUG "pxa_ir: sir receiving error\n");
217 si->stats.rx_errors++;
218 if (lsr & LSR_FE)
219 si->stats.rx_frame_errors++;
220 if (lsr & LSR_OE)
221 si->stats.rx_fifo_errors++;
222 } else {
223 si->stats.rx_bytes++;
224 async_unwrap_char(dev, &si->stats, &si->rx_buff, data);
225 }
226 lsr = STLSR;
227 }
228 dev->last_rx = jiffies;
229 si->last_oscr = OSCR;
230 break;
231
232 case 0x04: /* Received Data Available */
233 /* forth through */
234
235 case 0x0C: /* Character Timeout Indication */
236 do {
237 si->stats.rx_bytes++;
238 async_unwrap_char(dev, &si->stats, &si->rx_buff, STRBR);
239 } while (STLSR & LSR_DR);
240 dev->last_rx = jiffies;
241 si->last_oscr = OSCR;
242 break;
243
244 case 0x02: /* Transmit FIFO Data Request */
245 while ((si->tx_buff.len) && (STLSR & LSR_TDRQ)) {
246 STTHR = *si->tx_buff.data++;
247 si->tx_buff.len -= 1;
248 }
249
250 if (si->tx_buff.len == 0) {
251 si->stats.tx_packets++;
252 si->stats.tx_bytes += si->tx_buff.data -
253 si->tx_buff.head;
254
255 /* We need to ensure that the transmitter has finished. */
256 while ((STLSR & LSR_TEMT) == 0)
257 cpu_relax();
258 si->last_oscr = OSCR;
259
260 /*
261 * Ok, we've finished transmitting. Now enable
262 * the receiver. Sometimes we get a receive IRQ
263 * immediately after a transmit...
264 */
265 if (si->newspeed) {
266 pxa_irda_set_speed(si, si->newspeed);
267 si->newspeed = 0;
268 } else {
269 /* enable IR Receiver, disable IR Transmitter */
270 STISR = IrSR_IR_RECEIVE_ON | IrSR_XMODE_PULSE_1_6;
271 /* enable STUART and receive interrupts */
272 STIER = IER_UUE | IER_RLSE | IER_RAVIE | IER_RTIOE;
273 }
274 /* I'm hungry! */
275 netif_wake_queue(dev);
276 }
277 break;
278 }
279
280 return IRQ_HANDLED;
281}
282
283/* FIR Receive DMA interrupt handler */
284static void pxa_irda_fir_dma_rx_irq(int channel, void *data, struct pt_regs *regs)
285{
286 int dcsr = DCSR(channel);
287
288 DCSR(channel) = dcsr & ~DCSR_RUN;
289
290 printk(KERN_DEBUG "pxa_ir: fir rx dma bus error %#x\n", dcsr);
291}
292
293/* FIR Transmit DMA interrupt handler */
294static void pxa_irda_fir_dma_tx_irq(int channel, void *data, struct pt_regs *regs)
295{
296 struct net_device *dev = data;
297 struct pxa_irda *si = netdev_priv(dev);
298 int dcsr;
299
300 dcsr = DCSR(channel);
301 DCSR(channel) = dcsr & ~DCSR_RUN;
302
303 if (dcsr & DCSR_ENDINTR) {
304 si->stats.tx_packets++;
305 si->stats.tx_bytes += si->dma_tx_buff_len;
306 } else {
307 si->stats.tx_errors++;
308 }
309
310 while (ICSR1 & ICSR1_TBY)
311 cpu_relax();
312 si->last_oscr = OSCR;
313
314 /*
315 * HACK: It looks like the TBY bit is dropped too soon.
316 * Without this delay things break.
317 */
318 udelay(120);
319
320 if (si->newspeed) {
321 pxa_irda_set_speed(si, si->newspeed);
322 si->newspeed = 0;
323 } else {
324 ICCR0 = 0;
325 pxa_irda_fir_dma_rx_start(si);
326 ICCR0 = ICCR0_ITR | ICCR0_RXE;
327 }
328 netif_wake_queue(dev);
329}
330
331/* EIF(Error in FIFO/End in Frame) handler for FIR */
332static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev)
333{
334 unsigned int len, stat, data;
335
336 /* Get the current data position. */
337 len = DTADR(si->rxdma) - si->dma_rx_buff_phy;
338
339 do {
340 /* Read Status, and then Data. */
341 stat = ICSR1;
342 rmb();
343 data = ICDR;
344
345 if (stat & (ICSR1_CRE | ICSR1_ROR)) {
346 si->stats.rx_errors++;
347 if (stat & ICSR1_CRE) {
348 printk(KERN_DEBUG "pxa_ir: fir receive CRC error\n");
349 si->stats.rx_crc_errors++;
350 }
351 if (stat & ICSR1_ROR) {
352 printk(KERN_DEBUG "pxa_ir: fir receive overrun\n");
353 si->stats.rx_frame_errors++;
354 }
355 } else {
356 si->dma_rx_buff[len++] = data;
357 }
358 /* If we hit the end of frame, there's no point in continuing. */
359 if (stat & ICSR1_EOF)
360 break;
361 } while (ICSR0 & ICSR0_EIF);
362
363 if (stat & ICSR1_EOF) {
364 /* end of frame. */
365 struct sk_buff *skb = alloc_skb(len+1,GFP_ATOMIC);
366 if (!skb) {
367 printk(KERN_ERR "pxa_ir: fir out of memory for receive skb\n");
368 si->stats.rx_dropped++;
369 return;
370 }
371
372 /* Align IP header to 20 bytes */
373 skb_reserve(skb, 1);
374 memcpy(skb->data, si->dma_rx_buff, len);
375 skb_put(skb, len);
376
377 /* Feed it to IrLAP */
378 skb->dev = dev;
379 skb->mac.raw = skb->data;
380 skb->protocol = htons(ETH_P_IRDA);
381 netif_rx(skb);
382
383 si->stats.rx_packets++;
384 si->stats.rx_bytes += len;
385
386 dev->last_rx = jiffies;
387 }
388}
389
390/* FIR interrupt handler */
391static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id, struct pt_regs *regs)
392{
393 struct net_device *dev = dev_id;
394 struct pxa_irda *si = netdev_priv(dev);
395 int icsr0;
396
397 /* stop RX DMA */
398 DCSR(si->rxdma) &= ~DCSR_RUN;
399 si->last_oscr = OSCR;
400 icsr0 = ICSR0;
401
402 if (icsr0 & (ICSR0_FRE | ICSR0_RAB)) {
403 if (icsr0 & ICSR0_FRE) {
404 printk(KERN_DEBUG "pxa_ir: fir receive frame error\n");
405 si->stats.rx_frame_errors++;
406 } else {
407 printk(KERN_DEBUG "pxa_ir: fir receive abort\n");
408 si->stats.rx_errors++;
409 }
410 ICSR0 = icsr0 & (ICSR0_FRE | ICSR0_RAB);
411 }
412
413 if (icsr0 & ICSR0_EIF) {
414 /* An error in FIFO occured, or there is a end of frame */
415 pxa_irda_fir_irq_eif(si, dev);
416 }
417
418 ICCR0 = 0;
419 pxa_irda_fir_dma_rx_start(si);
420 ICCR0 = ICCR0_ITR | ICCR0_RXE;
421
422 return IRQ_HANDLED;
423}
424
425/* hard_xmit interface of irda device */
426static int pxa_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
427{
428 struct pxa_irda *si = netdev_priv(dev);
429 int speed = irda_get_next_speed(skb);
430
431 /*
432 * Does this packet contain a request to change the interface
433 * speed? If so, remember it until we complete the transmission
434 * of this frame.
435 */
436 if (speed != si->speed && speed != -1)
437 si->newspeed = speed;
438
439 /*
440 * If this is an empty frame, we can bypass a lot.
441 */
442 if (skb->len == 0) {
443 if (si->newspeed) {
444 si->newspeed = 0;
445 pxa_irda_set_speed(si, speed);
446 }
447 dev_kfree_skb(skb);
448 return 0;
449 }
450
451 netif_stop_queue(dev);
452
453 if (!IS_FIR(si)) {
454 si->tx_buff.data = si->tx_buff.head;
455 si->tx_buff.len = async_wrap_skb(skb, si->tx_buff.data, si->tx_buff.truesize);
456
457 /* Disable STUART interrupts and switch to transmit mode. */
458 STIER = 0;
459 STISR = IrSR_IR_TRANSMIT_ON | IrSR_XMODE_PULSE_1_6;
460
461 /* enable STUART and transmit interrupts */
462 STIER = IER_UUE | IER_TIE;
463 } else {
464 unsigned long mtt = irda_get_mtt(skb);
465
466 si->dma_tx_buff_len = skb->len;
467 memcpy(si->dma_tx_buff, skb->data, skb->len);
468
469 if (mtt)
470 while ((unsigned)(OSCR - si->last_oscr)/4 < mtt)
471 cpu_relax();
472
473 /* stop RX DMA, disable FICP */
474 DCSR(si->rxdma) &= ~DCSR_RUN;
475 ICCR0 = 0;
476
477 pxa_irda_fir_dma_tx_start(si);
478 ICCR0 = ICCR0_ITR | ICCR0_TXE;
479 }
480
481 dev_kfree_skb(skb);
482 dev->trans_start = jiffies;
483 return 0;
484}
485
486static int pxa_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)
487{
488 struct if_irda_req *rq = (struct if_irda_req *)ifreq;
489 struct pxa_irda *si = netdev_priv(dev);
490 int ret;
491
492 switch (cmd) {
493 case SIOCSBANDWIDTH:
494 ret = -EPERM;
495 if (capable(CAP_NET_ADMIN)) {
496 /*
497 * We are unable to set the speed if the
498 * device is not running.
499 */
500 if (netif_running(dev)) {
501 ret = pxa_irda_set_speed(si,
502 rq->ifr_baudrate);
503 } else {
504 printk(KERN_INFO "pxa_ir: SIOCSBANDWIDTH: !netif_running\n");
505 ret = 0;
506 }
507 }
508 break;
509
510 case SIOCSMEDIABUSY:
511 ret = -EPERM;
512 if (capable(CAP_NET_ADMIN)) {
513 irda_device_set_media_busy(dev, TRUE);
514 ret = 0;
515 }
516 break;
517
518 case SIOCGRECEIVING:
519 ret = 0;
520 rq->ifr_receiving = IS_FIR(si) ? 0
521 : si->rx_buff.state != OUTSIDE_FRAME;
522 break;
523
524 default:
525 ret = -EOPNOTSUPP;
526 break;
527 }
528
529 return ret;
530}
531
532static struct net_device_stats *pxa_irda_stats(struct net_device *dev)
533{
534 struct pxa_irda *si = netdev_priv(dev);
535 return &si->stats;
536}
537
538static void pxa_irda_startup(struct pxa_irda *si)
539{
540 /* Disable STUART interrupts */
541 STIER = 0;
542 /* enable STUART interrupt to the processor */
543 STMCR = MCR_OUT2;
544 /* configure SIR frame format: StartBit - Data 7 ... Data 0 - Stop Bit */
545 STLCR = LCR_WLS0 | LCR_WLS1;
546 /* enable FIFO, we use FIFO to improve performance */
547 STFCR = FCR_TRFIFOE | FCR_ITL_32;
548
549 /* disable FICP */
550 ICCR0 = 0;
551 /* configure FICP ICCR2 */
552 ICCR2 = ICCR2_TXP | ICCR2_TRIG_32;
553
554 /* configure DMAC */
555 DRCMR17 = si->rxdma | DRCMR_MAPVLD;
556 DRCMR18 = si->txdma | DRCMR_MAPVLD;
557
558 /* force SIR reinitialization */
559 si->speed = 4000000;
560 pxa_irda_set_speed(si, 9600);
561
562 printk(KERN_DEBUG "pxa_ir: irda startup\n");
563}
564
565static void pxa_irda_shutdown(struct pxa_irda *si)
566{
567 unsigned long flags;
568
569 local_irq_save(flags);
570
571 /* disable STUART and interrupt */
572 STIER = 0;
573 /* disable STUART SIR mode */
574 STISR = 0;
575 /* disable the STUART clock */
576 pxa_set_cken(CKEN5_STUART, 0);
577
578 /* disable DMA */
579 DCSR(si->txdma) &= ~DCSR_RUN;
580 DCSR(si->rxdma) &= ~DCSR_RUN;
581 /* disable FICP */
582 ICCR0 = 0;
583 /* disable the FICP clock */
584 pxa_set_cken(CKEN13_FICP, 0);
585
586 DRCMR17 = 0;
587 DRCMR18 = 0;
588
589 local_irq_restore(flags);
590
591 /* power off board transceiver */
592 si->pdata->transceiver_mode(si->dev, IR_OFF);
593
594 printk(KERN_DEBUG "pxa_ir: irda shutdown\n");
595}
596
597static int pxa_irda_start(struct net_device *dev)
598{
599 struct pxa_irda *si = netdev_priv(dev);
600 int err;
601
602 si->speed = 9600;
603
604 err = request_irq(IRQ_STUART, pxa_irda_sir_irq, 0, dev->name, dev);
605 if (err)
606 goto err_irq1;
607
608 err = request_irq(IRQ_ICP, pxa_irda_fir_irq, 0, dev->name, dev);
609 if (err)
610 goto err_irq2;
611
612 /*
613 * The interrupt must remain disabled for now.
614 */
615 disable_irq(IRQ_STUART);
616 disable_irq(IRQ_ICP);
617
618 err = -EBUSY;
619 si->rxdma = pxa_request_dma("FICP_RX",DMA_PRIO_LOW, pxa_irda_fir_dma_rx_irq, dev);
620 if (si->rxdma < 0)
621 goto err_rx_dma;
622
623 si->txdma = pxa_request_dma("FICP_TX",DMA_PRIO_LOW, pxa_irda_fir_dma_tx_irq, dev);
624 if (si->txdma < 0)
625 goto err_tx_dma;
626
627 err = -ENOMEM;
628 si->dma_rx_buff = dma_alloc_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT,
629 &si->dma_rx_buff_phy, GFP_KERNEL );
630 if (!si->dma_rx_buff)
631 goto err_dma_rx_buff;
632
633 si->dma_tx_buff = dma_alloc_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT,
634 &si->dma_tx_buff_phy, GFP_KERNEL );
635 if (!si->dma_tx_buff)
636 goto err_dma_tx_buff;
637
638 /* Setup the serial port for the initial speed. */
639 pxa_irda_startup(si);
640
641 /*
642 * Open a new IrLAP layer instance.
643 */
644 si->irlap = irlap_open(dev, &si->qos, "pxa");
645 err = -ENOMEM;
646 if (!si->irlap)
647 goto err_irlap;
648
649 /*
650 * Now enable the interrupt and start the queue
651 */
652 enable_irq(IRQ_STUART);
653 enable_irq(IRQ_ICP);
654 netif_start_queue(dev);
655
656 printk(KERN_DEBUG "pxa_ir: irda driver opened\n");
657
658 return 0;
659
660err_irlap:
661 pxa_irda_shutdown(si);
662 dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_tx_buff, si->dma_tx_buff_phy);
663err_dma_tx_buff:
664 dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_rx_buff, si->dma_rx_buff_phy);
665err_dma_rx_buff:
666 pxa_free_dma(si->txdma);
667err_tx_dma:
668 pxa_free_dma(si->rxdma);
669err_rx_dma:
670 free_irq(IRQ_ICP, dev);
671err_irq2:
672 free_irq(IRQ_STUART, dev);
673err_irq1:
674
675 return err;
676}
677
678static int pxa_irda_stop(struct net_device *dev)
679{
680 struct pxa_irda *si = netdev_priv(dev);
681
682 netif_stop_queue(dev);
683
684 pxa_irda_shutdown(si);
685
686 /* Stop IrLAP */
687 if (si->irlap) {
688 irlap_close(si->irlap);
689 si->irlap = NULL;
690 }
691
692 free_irq(IRQ_STUART, dev);
693 free_irq(IRQ_ICP, dev);
694
695 pxa_free_dma(si->rxdma);
696 pxa_free_dma(si->txdma);
697
698 if (si->dma_rx_buff)
699 dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_tx_buff, si->dma_tx_buff_phy);
700 if (si->dma_tx_buff)
701 dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_rx_buff, si->dma_rx_buff_phy);
702
703 printk(KERN_DEBUG "pxa_ir: irda driver closed\n");
704 return 0;
705}
706
707static int pxa_irda_suspend(struct device *_dev, pm_message_t state, u32 level)
708{
709 struct net_device *dev = dev_get_drvdata(_dev);
710 struct pxa_irda *si;
711
712 if (!dev || level != SUSPEND_DISABLE)
713 return 0;
714
715 if (netif_running(dev)) {
716 si = netdev_priv(dev);
717 netif_device_detach(dev);
718 pxa_irda_shutdown(si);
719 }
720
721 return 0;
722}
723
724static int pxa_irda_resume(struct device *_dev, u32 level)
725{
726 struct net_device *dev = dev_get_drvdata(_dev);
727 struct pxa_irda *si;
728
729 if (!dev || level != RESUME_ENABLE)
730 return 0;
731
732 if (netif_running(dev)) {
733 si = netdev_priv(dev);
734 pxa_irda_startup(si);
735 netif_device_attach(dev);
736 netif_wake_queue(dev);
737 }
738
739 return 0;
740}
741
742
743static int pxa_irda_init_iobuf(iobuff_t *io, int size)
744{
745 io->head = kmalloc(size, GFP_KERNEL | GFP_DMA);
746 if (io->head != NULL) {
747 io->truesize = size;
748 io->in_frame = FALSE;
749 io->state = OUTSIDE_FRAME;
750 io->data = io->head;
751 }
752 return io->head ? 0 : -ENOMEM;
753}
754
755static int pxa_irda_probe(struct device *_dev)
756{
757 struct platform_device *pdev = to_platform_device(_dev);
758 struct net_device *dev;
759 struct pxa_irda *si;
760 unsigned int baudrate_mask;
761 int err;
762
763 if (!pdev->dev.platform_data)
764 return -ENODEV;
765
766 err = request_mem_region(__PREG(STUART), 0x24, "IrDA") ? 0 : -EBUSY;
767 if (err)
768 goto err_mem_1;
769
770 err = request_mem_region(__PREG(FICP), 0x1c, "IrDA") ? 0 : -EBUSY;
771 if (err)
772 goto err_mem_2;
773
774 dev = alloc_irdadev(sizeof(struct pxa_irda));
775 if (!dev)
776 goto err_mem_3;
777
778 si = netdev_priv(dev);
779 si->dev = &pdev->dev;
780 si->pdata = pdev->dev.platform_data;
781
782 /*
783 * Initialise the SIR buffers
784 */
785 err = pxa_irda_init_iobuf(&si->rx_buff, 14384);
786 if (err)
787 goto err_mem_4;
788 err = pxa_irda_init_iobuf(&si->tx_buff, 4000);
789 if (err)
790 goto err_mem_5;
791
792 dev->hard_start_xmit = pxa_irda_hard_xmit;
793 dev->open = pxa_irda_start;
794 dev->stop = pxa_irda_stop;
795 dev->do_ioctl = pxa_irda_ioctl;
796 dev->get_stats = pxa_irda_stats;
797
798 irda_init_max_qos_capabilies(&si->qos);
799
800 baudrate_mask = 0;
801 if (si->pdata->transceiver_cap & IR_SIRMODE)
802 baudrate_mask |= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
803 if (si->pdata->transceiver_cap & IR_FIRMODE)
804 baudrate_mask |= IR_4000000 << 8;
805
806 si->qos.baud_rate.bits &= baudrate_mask;
807 si->qos.min_turn_time.bits = 7; /* 1ms or more */
808
809 irda_qos_bits_to_value(&si->qos);
810
811 err = register_netdev(dev);
812
813 if (err == 0)
814 dev_set_drvdata(&pdev->dev, dev);
815
816 if (err) {
817 kfree(si->tx_buff.head);
818err_mem_5:
819 kfree(si->rx_buff.head);
820err_mem_4:
821 free_netdev(dev);
822err_mem_3:
823 release_mem_region(__PREG(FICP), 0x1c);
824err_mem_2:
825 release_mem_region(__PREG(STUART), 0x24);
826 }
827err_mem_1:
828 return err;
829}
830
831static int pxa_irda_remove(struct device *_dev)
832{
833 struct net_device *dev = dev_get_drvdata(_dev);
834
835 if (dev) {
836 struct pxa_irda *si = netdev_priv(dev);
837 unregister_netdev(dev);
838 kfree(si->tx_buff.head);
839 kfree(si->rx_buff.head);
840 free_netdev(dev);
841 }
842
843 release_mem_region(__PREG(STUART), 0x24);
844 release_mem_region(__PREG(FICP), 0x1c);
845
846 return 0;
847}
848
849static struct device_driver pxa_ir_driver = {
850 .name = "pxa2xx-ir",
851 .bus = &platform_bus_type,
852 .probe = pxa_irda_probe,
853 .remove = pxa_irda_remove,
854 .suspend = pxa_irda_suspend,
855 .resume = pxa_irda_resume,
856};
857
858static int __init pxa_irda_init(void)
859{
860 return driver_register(&pxa_ir_driver);
861}
862
863static void __exit pxa_irda_exit(void)
864{
865 driver_unregister(&pxa_ir_driver);
866}
867
868module_init(pxa_irda_init);
869module_exit(pxa_irda_exit);
870
871MODULE_LICENSE("GPL");
diff --git a/include/asm-arm/arch-pxa/irda.h b/include/asm-arm/arch-pxa/irda.h
new file mode 100644
index 000000000000..748406f384c2
--- /dev/null
+++ b/include/asm-arm/arch-pxa/irda.h
@@ -0,0 +1,17 @@
1#ifndef ASMARM_ARCH_IRDA_H
2#define ASMARM_ARCH_IRDA_H
3
4/* board specific transceiver capabilities */
5
6#define IR_OFF 1
7#define IR_SIRMODE 2
8#define IR_FIRMODE 4
9
10struct pxaficp_platform_data {
11 int transceiver_cap;
12 void (*transceiver_mode)(struct device *dev, int mode);
13};
14
15extern void pxa_set_ficp_info(struct pxaficp_platform_data *info);
16
17#endif
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
index 75f085dc9894..a75a2470f4f5 100644
--- a/include/asm-arm/arch-pxa/pxa-regs.h
+++ b/include/asm-arm/arch-pxa/pxa-regs.h
@@ -1032,14 +1032,12 @@
1032#define ICCR0_LBM (1 << 1) /* Loopback mode */ 1032#define ICCR0_LBM (1 << 1) /* Loopback mode */
1033#define ICCR0_ITR (1 << 0) /* IrDA transmission */ 1033#define ICCR0_ITR (1 << 0) /* IrDA transmission */
1034 1034
1035#ifdef CONFIG_PXA27x
1036#define ICCR2_RXP (1 << 3) /* Receive Pin Polarity select */ 1035#define ICCR2_RXP (1 << 3) /* Receive Pin Polarity select */
1037#define ICCR2_TXP (1 << 2) /* Transmit Pin Polarity select */ 1036#define ICCR2_TXP (1 << 2) /* Transmit Pin Polarity select */
1038#define ICCR2_TRIG (3 << 0) /* Receive FIFO Trigger threshold */ 1037#define ICCR2_TRIG (3 << 0) /* Receive FIFO Trigger threshold */
1039#define ICCR2_TRIG_8 (0 << 0) /* >= 8 bytes */ 1038#define ICCR2_TRIG_8 (0 << 0) /* >= 8 bytes */
1040#define ICCR2_TRIG_16 (1 << 0) /* >= 16 bytes */ 1039#define ICCR2_TRIG_16 (1 << 0) /* >= 16 bytes */
1041#define ICCR2_TRIG_32 (2 << 0) /* >= 32 bytes */ 1040#define ICCR2_TRIG_32 (2 << 0) /* >= 32 bytes */
1042#endif
1043 1041
1044#ifdef CONFIG_PXA27x 1042#ifdef CONFIG_PXA27x
1045#define ICSR0_EOC (1 << 6) /* DMA End of Descriptor Chain */ 1043#define ICSR0_EOC (1 << 6) /* DMA End of Descriptor Chain */