diff options
| author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-03-23 23:44:19 -0500 |
|---|---|---|
| committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-03-23 23:44:19 -0500 |
| commit | 1ebbe2b20091d306453a5cf480a87e6cd28ae76f (patch) | |
| tree | f5cd7a0fa69b8b1938cb5a0faed2e7b0628072a5 /drivers/net/irda | |
| parent | ac58c9059da8886b5e8cde012a80266b18ca146e (diff) | |
| parent | 674a396c6d2ba0341ebdd7c1c9950f32f018e2dd (diff) | |
Merge branch 'linus'
Diffstat (limited to 'drivers/net/irda')
| -rw-r--r-- | drivers/net/irda/Kconfig | 8 | ||||
| -rw-r--r-- | drivers/net/irda/Makefile | 1 | ||||
| -rw-r--r-- | drivers/net/irda/donauboe.c | 2 | ||||
| -rw-r--r-- | drivers/net/irda/ep7211_ir.c | 11 | ||||
| -rw-r--r-- | drivers/net/irda/irda-usb.c | 5 | ||||
| -rw-r--r-- | drivers/net/irda/irtty-sir.c | 19 | ||||
| -rw-r--r-- | drivers/net/irda/nsc-ircc.c | 320 | ||||
| -rw-r--r-- | drivers/net/irda/nsc-ircc.h | 2 | ||||
| -rw-r--r-- | drivers/net/irda/sir_dongle.c | 19 | ||||
| -rw-r--r-- | drivers/net/irda/toim3232-sir.c | 375 | ||||
| -rw-r--r-- | drivers/net/irda/vlsi_ir.c | 2 |
11 files changed, 668 insertions, 96 deletions
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig index c81fe1c382d5..5e6d00752990 100644 --- a/drivers/net/irda/Kconfig +++ b/drivers/net/irda/Kconfig | |||
| @@ -64,6 +64,14 @@ config TEKRAM_DONGLE | |||
| 64 | dongles you will have to start irattach like this: | 64 | dongles you will have to start irattach like this: |
| 65 | "irattach -d tekram". | 65 | "irattach -d tekram". |
| 66 | 66 | ||
| 67 | config TOIM3232_DONGLE | ||
| 68 | tristate "TOIM3232 IrDa dongle" | ||
| 69 | depends on DONGLE && IRDA | ||
| 70 | help | ||
| 71 | Say Y here if you want to build support for the Vishay/Temic | ||
| 72 | TOIM3232 and TOIM4232 based dongles. | ||
| 73 | To compile it as a module, choose M here. | ||
| 74 | |||
| 67 | config LITELINK_DONGLE | 75 | config LITELINK_DONGLE |
| 68 | tristate "Parallax LiteLink dongle" | 76 | tristate "Parallax LiteLink dongle" |
| 69 | depends on DONGLE && IRDA | 77 | depends on DONGLE && IRDA |
diff --git a/drivers/net/irda/Makefile b/drivers/net/irda/Makefile index 72cbfdc9cfcc..27ab75f20799 100644 --- a/drivers/net/irda/Makefile +++ b/drivers/net/irda/Makefile | |||
| @@ -43,6 +43,7 @@ obj-$(CONFIG_OLD_BELKIN_DONGLE) += old_belkin-sir.o | |||
| 43 | obj-$(CONFIG_MCP2120_DONGLE) += mcp2120-sir.o | 43 | obj-$(CONFIG_MCP2120_DONGLE) += mcp2120-sir.o |
| 44 | obj-$(CONFIG_ACT200L_DONGLE) += act200l-sir.o | 44 | obj-$(CONFIG_ACT200L_DONGLE) += act200l-sir.o |
| 45 | obj-$(CONFIG_MA600_DONGLE) += ma600-sir.o | 45 | obj-$(CONFIG_MA600_DONGLE) += ma600-sir.o |
| 46 | obj-$(CONFIG_TOIM3232_DONGLE) += toim3232-sir.o | ||
| 46 | 47 | ||
| 47 | # The SIR helper module | 48 | # The SIR helper module |
| 48 | sir-dev-objs := sir_dev.o sir_dongle.o sir_kthread.o | 49 | sir-dev-objs := sir_dev.o sir_dongle.o sir_kthread.o |
diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c index 3137592d60c0..910c0cab35b0 100644 --- a/drivers/net/irda/donauboe.c +++ b/drivers/net/irda/donauboe.c | |||
| @@ -1778,7 +1778,7 @@ static struct pci_driver donauboe_pci_driver = { | |||
| 1778 | static int __init | 1778 | static int __init |
| 1779 | donauboe_init (void) | 1779 | donauboe_init (void) |
| 1780 | { | 1780 | { |
| 1781 | return pci_module_init(&donauboe_pci_driver); | 1781 | return pci_register_driver(&donauboe_pci_driver); |
| 1782 | } | 1782 | } |
| 1783 | 1783 | ||
| 1784 | static void __exit | 1784 | static void __exit |
diff --git a/drivers/net/irda/ep7211_ir.c b/drivers/net/irda/ep7211_ir.c index 31896262d21c..4cba38f7e4a8 100644 --- a/drivers/net/irda/ep7211_ir.c +++ b/drivers/net/irda/ep7211_ir.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include <linux/delay.h> | 8 | #include <linux/delay.h> |
| 9 | #include <linux/tty.h> | 9 | #include <linux/tty.h> |
| 10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
| 11 | #include <linux/spinlock.h> | ||
| 11 | 12 | ||
| 12 | #include <net/irda/irda.h> | 13 | #include <net/irda/irda.h> |
| 13 | #include <net/irda/irda_device.h> | 14 | #include <net/irda/irda_device.h> |
| @@ -23,6 +24,8 @@ static void ep7211_ir_close(dongle_t *self); | |||
| 23 | static int ep7211_ir_change_speed(struct irda_task *task); | 24 | static int ep7211_ir_change_speed(struct irda_task *task); |
| 24 | static int ep7211_ir_reset(struct irda_task *task); | 25 | static int ep7211_ir_reset(struct irda_task *task); |
| 25 | 26 | ||
| 27 | static DEFINE_SPINLOCK(ep7211_lock); | ||
| 28 | |||
| 26 | static struct dongle_reg dongle = { | 29 | static struct dongle_reg dongle = { |
| 27 | .type = IRDA_EP7211_IR, | 30 | .type = IRDA_EP7211_IR, |
| 28 | .open = ep7211_ir_open, | 31 | .open = ep7211_ir_open, |
| @@ -36,7 +39,7 @@ static void ep7211_ir_open(dongle_t *self, struct qos_info *qos) | |||
| 36 | { | 39 | { |
| 37 | unsigned int syscon1, flags; | 40 | unsigned int syscon1, flags; |
| 38 | 41 | ||
| 39 | save_flags(flags); cli(); | 42 | spin_lock_irqsave(&ep7211_lock, flags); |
| 40 | 43 | ||
| 41 | /* Turn on the SIR encoder. */ | 44 | /* Turn on the SIR encoder. */ |
| 42 | syscon1 = clps_readl(SYSCON1); | 45 | syscon1 = clps_readl(SYSCON1); |
| @@ -46,14 +49,14 @@ static void ep7211_ir_open(dongle_t *self, struct qos_info *qos) | |||
| 46 | /* XXX: We should disable modem status interrupts on the first | 49 | /* XXX: We should disable modem status interrupts on the first |
| 47 | UART (interrupt #14). */ | 50 | UART (interrupt #14). */ |
| 48 | 51 | ||
| 49 | restore_flags(flags); | 52 | spin_unlock_irqrestore(&ep7211_lock, flags); |
| 50 | } | 53 | } |
| 51 | 54 | ||
| 52 | static void ep7211_ir_close(dongle_t *self) | 55 | static void ep7211_ir_close(dongle_t *self) |
| 53 | { | 56 | { |
| 54 | unsigned int syscon1, flags; | 57 | unsigned int syscon1, flags; |
| 55 | 58 | ||
| 56 | save_flags(flags); cli(); | 59 | spin_lock_irqsave(&ep7211_lock, flags); |
| 57 | 60 | ||
| 58 | /* Turn off the SIR encoder. */ | 61 | /* Turn off the SIR encoder. */ |
| 59 | syscon1 = clps_readl(SYSCON1); | 62 | syscon1 = clps_readl(SYSCON1); |
| @@ -63,7 +66,7 @@ static void ep7211_ir_close(dongle_t *self) | |||
| 63 | /* XXX: If we've disabled the modem status interrupts, we should | 66 | /* XXX: If we've disabled the modem status interrupts, we should |
| 64 | reset them back to their original state. */ | 67 | reset them back to their original state. */ |
| 65 | 68 | ||
| 66 | restore_flags(flags); | 69 | spin_unlock_irqrestore(&ep7211_lock, flags); |
| 67 | } | 70 | } |
| 68 | 71 | ||
| 69 | /* | 72 | /* |
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index 8936058a3cce..6e2ec56cde0b 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c | |||
| @@ -740,7 +740,7 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) | |||
| 740 | struct sk_buff *newskb; | 740 | struct sk_buff *newskb; |
| 741 | struct sk_buff *dataskb; | 741 | struct sk_buff *dataskb; |
| 742 | struct urb *next_urb; | 742 | struct urb *next_urb; |
| 743 | int docopy; | 743 | unsigned int len, docopy; |
| 744 | 744 | ||
| 745 | IRDA_DEBUG(2, "%s(), len=%d\n", __FUNCTION__, urb->actual_length); | 745 | IRDA_DEBUG(2, "%s(), len=%d\n", __FUNCTION__, urb->actual_length); |
| 746 | 746 | ||
| @@ -851,10 +851,11 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) | |||
| 851 | dataskb->dev = self->netdev; | 851 | dataskb->dev = self->netdev; |
| 852 | dataskb->mac.raw = dataskb->data; | 852 | dataskb->mac.raw = dataskb->data; |
| 853 | dataskb->protocol = htons(ETH_P_IRDA); | 853 | dataskb->protocol = htons(ETH_P_IRDA); |
| 854 | len = dataskb->len; | ||
| 854 | netif_rx(dataskb); | 855 | netif_rx(dataskb); |
| 855 | 856 | ||
| 856 | /* Keep stats up to date */ | 857 | /* Keep stats up to date */ |
| 857 | self->stats.rx_bytes += dataskb->len; | 858 | self->stats.rx_bytes += len; |
| 858 | self->stats.rx_packets++; | 859 | self->stats.rx_packets++; |
| 859 | self->netdev->last_rx = jiffies; | 860 | self->netdev->last_rx = jiffies; |
| 860 | 861 | ||
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c index 101750bf210f..6a98b7ae4975 100644 --- a/drivers/net/irda/irtty-sir.c +++ b/drivers/net/irda/irtty-sir.c | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <asm/uaccess.h> | 33 | #include <asm/uaccess.h> |
| 34 | #include <linux/smp_lock.h> | 34 | #include <linux/smp_lock.h> |
| 35 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
| 36 | #include <linux/mutex.h> | ||
| 36 | 37 | ||
| 37 | #include <net/irda/irda.h> | 38 | #include <net/irda/irda.h> |
| 38 | #include <net/irda/irda_device.h> | 39 | #include <net/irda/irda_device.h> |
| @@ -338,7 +339,7 @@ static inline void irtty_stop_receiver(struct tty_struct *tty, int stop) | |||
| 338 | /*****************************************************************/ | 339 | /*****************************************************************/ |
| 339 | 340 | ||
| 340 | /* serialize ldisc open/close with sir_dev */ | 341 | /* serialize ldisc open/close with sir_dev */ |
| 341 | static DECLARE_MUTEX(irtty_sem); | 342 | static DEFINE_MUTEX(irtty_mutex); |
| 342 | 343 | ||
| 343 | /* notifier from sir_dev when irda% device gets opened (ifup) */ | 344 | /* notifier from sir_dev when irda% device gets opened (ifup) */ |
| 344 | 345 | ||
| @@ -348,11 +349,11 @@ static int irtty_start_dev(struct sir_dev *dev) | |||
| 348 | struct tty_struct *tty; | 349 | struct tty_struct *tty; |
| 349 | 350 | ||
| 350 | /* serialize with ldisc open/close */ | 351 | /* serialize with ldisc open/close */ |
| 351 | down(&irtty_sem); | 352 | mutex_lock(&irtty_mutex); |
| 352 | 353 | ||
| 353 | priv = dev->priv; | 354 | priv = dev->priv; |
| 354 | if (unlikely(!priv || priv->magic!=IRTTY_MAGIC)) { | 355 | if (unlikely(!priv || priv->magic!=IRTTY_MAGIC)) { |
| 355 | up(&irtty_sem); | 356 | mutex_unlock(&irtty_mutex); |
| 356 | return -ESTALE; | 357 | return -ESTALE; |
| 357 | } | 358 | } |
| 358 | 359 | ||
| @@ -363,7 +364,7 @@ static int irtty_start_dev(struct sir_dev *dev) | |||
| 363 | /* Make sure we can receive more data */ | 364 | /* Make sure we can receive more data */ |
| 364 | irtty_stop_receiver(tty, FALSE); | 365 | irtty_stop_receiver(tty, FALSE); |
| 365 | 366 | ||
| 366 | up(&irtty_sem); | 367 | mutex_unlock(&irtty_mutex); |
| 367 | return 0; | 368 | return 0; |
| 368 | } | 369 | } |
| 369 | 370 | ||
| @@ -375,11 +376,11 @@ static int irtty_stop_dev(struct sir_dev *dev) | |||
| 375 | struct tty_struct *tty; | 376 | struct tty_struct *tty; |
| 376 | 377 | ||
| 377 | /* serialize with ldisc open/close */ | 378 | /* serialize with ldisc open/close */ |
| 378 | down(&irtty_sem); | 379 | mutex_lock(&irtty_mutex); |
| 379 | 380 | ||
| 380 | priv = dev->priv; | 381 | priv = dev->priv; |
| 381 | if (unlikely(!priv || priv->magic!=IRTTY_MAGIC)) { | 382 | if (unlikely(!priv || priv->magic!=IRTTY_MAGIC)) { |
| 382 | up(&irtty_sem); | 383 | mutex_unlock(&irtty_mutex); |
| 383 | return -ESTALE; | 384 | return -ESTALE; |
| 384 | } | 385 | } |
| 385 | 386 | ||
| @@ -390,7 +391,7 @@ static int irtty_stop_dev(struct sir_dev *dev) | |||
| 390 | if (tty->driver->stop) | 391 | if (tty->driver->stop) |
| 391 | tty->driver->stop(tty); | 392 | tty->driver->stop(tty); |
| 392 | 393 | ||
| 393 | up(&irtty_sem); | 394 | mutex_unlock(&irtty_mutex); |
| 394 | 395 | ||
| 395 | return 0; | 396 | return 0; |
| 396 | } | 397 | } |
| @@ -514,13 +515,13 @@ static int irtty_open(struct tty_struct *tty) | |||
| 514 | priv->dev = dev; | 515 | priv->dev = dev; |
| 515 | 516 | ||
| 516 | /* serialize with start_dev - in case we were racing with ifup */ | 517 | /* serialize with start_dev - in case we were racing with ifup */ |
| 517 | down(&irtty_sem); | 518 | mutex_lock(&irtty_mutex); |
| 518 | 519 | ||
| 519 | dev->priv = priv; | 520 | dev->priv = priv; |
| 520 | tty->disc_data = priv; | 521 | tty->disc_data = priv; |
| 521 | tty->receive_room = 65536; | 522 | tty->receive_room = 65536; |
| 522 | 523 | ||
| 523 | up(&irtty_sem); | 524 | mutex_unlock(&irtty_mutex); |
| 524 | 525 | ||
| 525 | IRDA_DEBUG(0, "%s - %s: irda line discipline opened\n", __FUNCTION__, tty->name); | 526 | IRDA_DEBUG(0, "%s - %s: irda line discipline opened\n", __FUNCTION__, tty->name); |
| 526 | 527 | ||
diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c index ee717d0e939e..83141a3ff546 100644 --- a/drivers/net/irda/nsc-ircc.c +++ b/drivers/net/irda/nsc-ircc.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | * Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no> | 12 | * Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no> |
| 13 | * Copyright (c) 1998 Lichen Wang, <lwang@actisys.com> | 13 | * Copyright (c) 1998 Lichen Wang, <lwang@actisys.com> |
| 14 | * Copyright (c) 1998 Actisys Corp., www.actisys.com | 14 | * Copyright (c) 1998 Actisys Corp., www.actisys.com |
| 15 | * Copyright (c) 2000-2004 Jean Tourrilhes <jt@hpl.hp.com> | ||
| 15 | * All Rights Reserved | 16 | * All Rights Reserved |
| 16 | * | 17 | * |
| 17 | * This program is free software; you can redistribute it and/or | 18 | * This program is free software; you can redistribute it and/or |
| @@ -53,14 +54,13 @@ | |||
| 53 | #include <linux/init.h> | 54 | #include <linux/init.h> |
| 54 | #include <linux/rtnetlink.h> | 55 | #include <linux/rtnetlink.h> |
| 55 | #include <linux/dma-mapping.h> | 56 | #include <linux/dma-mapping.h> |
| 57 | #include <linux/pnp.h> | ||
| 58 | #include <linux/platform_device.h> | ||
| 56 | 59 | ||
| 57 | #include <asm/io.h> | 60 | #include <asm/io.h> |
| 58 | #include <asm/dma.h> | 61 | #include <asm/dma.h> |
| 59 | #include <asm/byteorder.h> | 62 | #include <asm/byteorder.h> |
| 60 | 63 | ||
| 61 | #include <linux/pm.h> | ||
| 62 | #include <linux/pm_legacy.h> | ||
| 63 | |||
| 64 | #include <net/irda/wrapper.h> | 64 | #include <net/irda/wrapper.h> |
| 65 | #include <net/irda/irda.h> | 65 | #include <net/irda/irda.h> |
| 66 | #include <net/irda/irda_device.h> | 66 | #include <net/irda/irda_device.h> |
| @@ -72,14 +72,27 @@ | |||
| 72 | 72 | ||
| 73 | static char *driver_name = "nsc-ircc"; | 73 | static char *driver_name = "nsc-ircc"; |
| 74 | 74 | ||
| 75 | /* Power Management */ | ||
| 76 | #define NSC_IRCC_DRIVER_NAME "nsc-ircc" | ||
| 77 | static int nsc_ircc_suspend(struct platform_device *dev, pm_message_t state); | ||
| 78 | static int nsc_ircc_resume(struct platform_device *dev); | ||
| 79 | |||
| 80 | static struct platform_driver nsc_ircc_driver = { | ||
| 81 | .suspend = nsc_ircc_suspend, | ||
| 82 | .resume = nsc_ircc_resume, | ||
| 83 | .driver = { | ||
| 84 | .name = NSC_IRCC_DRIVER_NAME, | ||
| 85 | }, | ||
| 86 | }; | ||
| 87 | |||
| 75 | /* Module parameters */ | 88 | /* Module parameters */ |
| 76 | static int qos_mtt_bits = 0x07; /* 1 ms or more */ | 89 | static int qos_mtt_bits = 0x07; /* 1 ms or more */ |
| 77 | static int dongle_id; | 90 | static int dongle_id; |
| 78 | 91 | ||
| 79 | /* Use BIOS settions by default, but user may supply module parameters */ | 92 | /* Use BIOS settions by default, but user may supply module parameters */ |
| 80 | static unsigned int io[] = { ~0, ~0, ~0, ~0 }; | 93 | static unsigned int io[] = { ~0, ~0, ~0, ~0, ~0 }; |
| 81 | static unsigned int irq[] = { 0, 0, 0, 0, 0 }; | 94 | static unsigned int irq[] = { 0, 0, 0, 0, 0 }; |
| 82 | static unsigned int dma[] = { 0, 0, 0, 0, 0 }; | 95 | static unsigned int dma[] = { 0, 0, 0, 0, 0 }; |
| 83 | 96 | ||
| 84 | static int nsc_ircc_probe_108(nsc_chip_t *chip, chipio_t *info); | 97 | static int nsc_ircc_probe_108(nsc_chip_t *chip, chipio_t *info); |
| 85 | static int nsc_ircc_probe_338(nsc_chip_t *chip, chipio_t *info); | 98 | static int nsc_ircc_probe_338(nsc_chip_t *chip, chipio_t *info); |
| @@ -87,6 +100,7 @@ static int nsc_ircc_probe_39x(nsc_chip_t *chip, chipio_t *info); | |||
| 87 | static int nsc_ircc_init_108(nsc_chip_t *chip, chipio_t *info); | 100 | static int nsc_ircc_init_108(nsc_chip_t *chip, chipio_t *info); |
| 88 | static int nsc_ircc_init_338(nsc_chip_t *chip, chipio_t *info); | 101 | static int nsc_ircc_init_338(nsc_chip_t *chip, chipio_t *info); |
| 89 | static int nsc_ircc_init_39x(nsc_chip_t *chip, chipio_t *info); | 102 | static int nsc_ircc_init_39x(nsc_chip_t *chip, chipio_t *info); |
| 103 | static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *id); | ||
| 90 | 104 | ||
| 91 | /* These are the known NSC chips */ | 105 | /* These are the known NSC chips */ |
| 92 | static nsc_chip_t chips[] = { | 106 | static nsc_chip_t chips[] = { |
| @@ -101,11 +115,12 @@ static nsc_chip_t chips[] = { | |||
| 101 | /* Contributed by Jan Frey - IBM A30/A31 */ | 115 | /* Contributed by Jan Frey - IBM A30/A31 */ |
| 102 | { "PC8739x", { 0x2e, 0x4e, 0x0 }, 0x20, 0xea, 0xff, | 116 | { "PC8739x", { 0x2e, 0x4e, 0x0 }, 0x20, 0xea, 0xff, |
| 103 | nsc_ircc_probe_39x, nsc_ircc_init_39x }, | 117 | nsc_ircc_probe_39x, nsc_ircc_init_39x }, |
| 118 | { "IBM", { 0x2e, 0x4e, 0x0 }, 0x20, 0xf4, 0xff, | ||
| 119 | nsc_ircc_probe_39x, nsc_ircc_init_39x }, | ||
| 104 | { NULL } | 120 | { NULL } |
| 105 | }; | 121 | }; |
| 106 | 122 | ||
| 107 | /* Max 4 instances for now */ | 123 | static struct nsc_ircc_cb *dev_self[] = { NULL, NULL, NULL, NULL, NULL }; |
| 108 | static struct nsc_ircc_cb *dev_self[] = { NULL, NULL, NULL, NULL }; | ||
| 109 | 124 | ||
| 110 | static char *dongle_types[] = { | 125 | static char *dongle_types[] = { |
| 111 | "Differential serial interface", | 126 | "Differential serial interface", |
| @@ -126,8 +141,24 @@ static char *dongle_types[] = { | |||
| 126 | "No dongle connected", | 141 | "No dongle connected", |
| 127 | }; | 142 | }; |
| 128 | 143 | ||
| 144 | /* PNP probing */ | ||
| 145 | static chipio_t pnp_info; | ||
| 146 | static const struct pnp_device_id nsc_ircc_pnp_table[] = { | ||
| 147 | { .id = "NSC6001", .driver_data = 0 }, | ||
| 148 | { .id = "IBM0071", .driver_data = 0 }, | ||
| 149 | { } | ||
| 150 | }; | ||
| 151 | |||
| 152 | MODULE_DEVICE_TABLE(pnp, nsc_ircc_pnp_table); | ||
| 153 | |||
| 154 | static struct pnp_driver nsc_ircc_pnp_driver = { | ||
| 155 | .name = "nsc-ircc", | ||
| 156 | .id_table = nsc_ircc_pnp_table, | ||
| 157 | .probe = nsc_ircc_pnp_probe, | ||
| 158 | }; | ||
| 159 | |||
| 129 | /* Some prototypes */ | 160 | /* Some prototypes */ |
| 130 | static int nsc_ircc_open(int i, chipio_t *info); | 161 | static int nsc_ircc_open(chipio_t *info); |
| 131 | static int nsc_ircc_close(struct nsc_ircc_cb *self); | 162 | static int nsc_ircc_close(struct nsc_ircc_cb *self); |
| 132 | static int nsc_ircc_setup(chipio_t *info); | 163 | static int nsc_ircc_setup(chipio_t *info); |
| 133 | static void nsc_ircc_pio_receive(struct nsc_ircc_cb *self); | 164 | static void nsc_ircc_pio_receive(struct nsc_ircc_cb *self); |
| @@ -146,7 +177,10 @@ static int nsc_ircc_net_open(struct net_device *dev); | |||
| 146 | static int nsc_ircc_net_close(struct net_device *dev); | 177 | static int nsc_ircc_net_close(struct net_device *dev); |
| 147 | static int nsc_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | 178 | static int nsc_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); |
| 148 | static struct net_device_stats *nsc_ircc_net_get_stats(struct net_device *dev); | 179 | static struct net_device_stats *nsc_ircc_net_get_stats(struct net_device *dev); |
| 149 | static int nsc_ircc_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data); | 180 | |
| 181 | /* Globals */ | ||
| 182 | static int pnp_registered; | ||
| 183 | static int pnp_succeeded; | ||
| 150 | 184 | ||
| 151 | /* | 185 | /* |
| 152 | * Function nsc_ircc_init () | 186 | * Function nsc_ircc_init () |
| @@ -158,28 +192,36 @@ static int __init nsc_ircc_init(void) | |||
| 158 | { | 192 | { |
| 159 | chipio_t info; | 193 | chipio_t info; |
| 160 | nsc_chip_t *chip; | 194 | nsc_chip_t *chip; |
| 161 | int ret = -ENODEV; | 195 | int ret; |
| 162 | int cfg_base; | 196 | int cfg_base; |
| 163 | int cfg, id; | 197 | int cfg, id; |
| 164 | int reg; | 198 | int reg; |
| 165 | int i = 0; | 199 | int i = 0; |
| 166 | 200 | ||
| 201 | ret = platform_driver_register(&nsc_ircc_driver); | ||
| 202 | if (ret) { | ||
| 203 | IRDA_ERROR("%s, Can't register driver!\n", driver_name); | ||
| 204 | return ret; | ||
| 205 | } | ||
| 206 | |||
| 207 | /* Register with PnP subsystem to detect disable ports */ | ||
| 208 | ret = pnp_register_driver(&nsc_ircc_pnp_driver); | ||
| 209 | |||
| 210 | if (ret >= 0) | ||
| 211 | pnp_registered = 1; | ||
| 212 | |||
| 213 | ret = -ENODEV; | ||
| 214 | |||
| 167 | /* Probe for all the NSC chipsets we know about */ | 215 | /* Probe for all the NSC chipsets we know about */ |
| 168 | for (chip=chips; chip->name ; chip++) { | 216 | for (chip = chips; chip->name ; chip++) { |
| 169 | IRDA_DEBUG(2, "%s(), Probing for %s ...\n", __FUNCTION__, | 217 | IRDA_DEBUG(2, "%s(), Probing for %s ...\n", __FUNCTION__, |
| 170 | chip->name); | 218 | chip->name); |
| 171 | 219 | ||
| 172 | /* Try all config registers for this chip */ | 220 | /* Try all config registers for this chip */ |
| 173 | for (cfg=0; cfg<3; cfg++) { | 221 | for (cfg = 0; cfg < ARRAY_SIZE(chip->cfg); cfg++) { |
| 174 | cfg_base = chip->cfg[cfg]; | 222 | cfg_base = chip->cfg[cfg]; |
| 175 | if (!cfg_base) | 223 | if (!cfg_base) |
| 176 | continue; | 224 | continue; |
| 177 | |||
| 178 | memset(&info, 0, sizeof(chipio_t)); | ||
| 179 | info.cfg_base = cfg_base; | ||
| 180 | info.fir_base = io[i]; | ||
| 181 | info.dma = dma[i]; | ||
| 182 | info.irq = irq[i]; | ||
| 183 | 225 | ||
| 184 | /* Read index register */ | 226 | /* Read index register */ |
| 185 | reg = inb(cfg_base); | 227 | reg = inb(cfg_base); |
| @@ -194,24 +236,65 @@ static int __init nsc_ircc_init(void) | |||
| 194 | if ((id & chip->cid_mask) == chip->cid_value) { | 236 | if ((id & chip->cid_mask) == chip->cid_value) { |
| 195 | IRDA_DEBUG(2, "%s() Found %s chip, revision=%d\n", | 237 | IRDA_DEBUG(2, "%s() Found %s chip, revision=%d\n", |
| 196 | __FUNCTION__, chip->name, id & ~chip->cid_mask); | 238 | __FUNCTION__, chip->name, id & ~chip->cid_mask); |
| 197 | /* | ||
| 198 | * If the user supplies the base address, then | ||
| 199 | * we init the chip, if not we probe the values | ||
| 200 | * set by the BIOS | ||
| 201 | */ | ||
| 202 | if (io[i] < 0x2000) { | ||
| 203 | chip->init(chip, &info); | ||
| 204 | } else | ||
| 205 | chip->probe(chip, &info); | ||
| 206 | 239 | ||
| 207 | if (nsc_ircc_open(i, &info) == 0) | 240 | /* |
| 208 | ret = 0; | 241 | * If we found a correct PnP setting, |
| 242 | * we first try it. | ||
| 243 | */ | ||
| 244 | if (pnp_succeeded) { | ||
| 245 | memset(&info, 0, sizeof(chipio_t)); | ||
| 246 | info.cfg_base = cfg_base; | ||
| 247 | info.fir_base = pnp_info.fir_base; | ||
| 248 | info.dma = pnp_info.dma; | ||
| 249 | info.irq = pnp_info.irq; | ||
| 250 | |||
| 251 | if (info.fir_base < 0x2000) { | ||
| 252 | IRDA_MESSAGE("%s, chip->init\n", driver_name); | ||
| 253 | chip->init(chip, &info); | ||
| 254 | } else | ||
| 255 | chip->probe(chip, &info); | ||
| 256 | |||
| 257 | if (nsc_ircc_open(&info) >= 0) | ||
| 258 | ret = 0; | ||
| 259 | } | ||
| 260 | |||
| 261 | /* | ||
| 262 | * Opening based on PnP values failed. | ||
| 263 | * Let's fallback to user values, or probe | ||
| 264 | * the chip. | ||
| 265 | */ | ||
| 266 | if (ret) { | ||
| 267 | IRDA_DEBUG(2, "%s, PnP init failed\n", driver_name); | ||
| 268 | memset(&info, 0, sizeof(chipio_t)); | ||
| 269 | info.cfg_base = cfg_base; | ||
| 270 | info.fir_base = io[i]; | ||
| 271 | info.dma = dma[i]; | ||
| 272 | info.irq = irq[i]; | ||
| 273 | |||
| 274 | /* | ||
| 275 | * If the user supplies the base address, then | ||
| 276 | * we init the chip, if not we probe the values | ||
| 277 | * set by the BIOS | ||
| 278 | */ | ||
| 279 | if (io[i] < 0x2000) { | ||
| 280 | chip->init(chip, &info); | ||
| 281 | } else | ||
| 282 | chip->probe(chip, &info); | ||
| 283 | |||
| 284 | if (nsc_ircc_open(&info) >= 0) | ||
| 285 | ret = 0; | ||
| 286 | } | ||
| 209 | i++; | 287 | i++; |
| 210 | } else { | 288 | } else { |
| 211 | IRDA_DEBUG(2, "%s(), Wrong chip id=0x%02x\n", __FUNCTION__, id); | 289 | IRDA_DEBUG(2, "%s(), Wrong chip id=0x%02x\n", __FUNCTION__, id); |
| 212 | } | 290 | } |
| 213 | } | 291 | } |
| 214 | 292 | } | |
| 293 | |||
| 294 | if (ret) { | ||
| 295 | platform_driver_unregister(&nsc_ircc_driver); | ||
| 296 | pnp_unregister_driver(&nsc_ircc_pnp_driver); | ||
| 297 | pnp_registered = 0; | ||
| 215 | } | 298 | } |
| 216 | 299 | ||
| 217 | return ret; | 300 | return ret; |
| @@ -227,12 +310,17 @@ static void __exit nsc_ircc_cleanup(void) | |||
| 227 | { | 310 | { |
| 228 | int i; | 311 | int i; |
| 229 | 312 | ||
| 230 | pm_unregister_all(nsc_ircc_pmproc); | 313 | for (i = 0; i < ARRAY_SIZE(dev_self); i++) { |
| 231 | |||
| 232 | for (i=0; i < 4; i++) { | ||
| 233 | if (dev_self[i]) | 314 | if (dev_self[i]) |
| 234 | nsc_ircc_close(dev_self[i]); | 315 | nsc_ircc_close(dev_self[i]); |
| 235 | } | 316 | } |
| 317 | |||
| 318 | platform_driver_unregister(&nsc_ircc_driver); | ||
| 319 | |||
| 320 | if (pnp_registered) | ||
| 321 | pnp_unregister_driver(&nsc_ircc_pnp_driver); | ||
| 322 | |||
| 323 | pnp_registered = 0; | ||
| 236 | } | 324 | } |
| 237 | 325 | ||
| 238 | /* | 326 | /* |
| @@ -241,16 +329,26 @@ static void __exit nsc_ircc_cleanup(void) | |||
| 241 | * Open driver instance | 329 | * Open driver instance |
| 242 | * | 330 | * |
| 243 | */ | 331 | */ |
| 244 | static int __init nsc_ircc_open(int i, chipio_t *info) | 332 | static int __init nsc_ircc_open(chipio_t *info) |
| 245 | { | 333 | { |
| 246 | struct net_device *dev; | 334 | struct net_device *dev; |
| 247 | struct nsc_ircc_cb *self; | 335 | struct nsc_ircc_cb *self; |
| 248 | struct pm_dev *pmdev; | ||
| 249 | void *ret; | 336 | void *ret; |
| 250 | int err; | 337 | int err, chip_index; |
| 251 | 338 | ||
| 252 | IRDA_DEBUG(2, "%s()\n", __FUNCTION__); | 339 | IRDA_DEBUG(2, "%s()\n", __FUNCTION__); |
| 253 | 340 | ||
| 341 | |||
| 342 | for (chip_index = 0; chip_index < ARRAY_SIZE(dev_self); chip_index++) { | ||
| 343 | if (!dev_self[chip_index]) | ||
| 344 | break; | ||
| 345 | } | ||
| 346 | |||
| 347 | if (chip_index == ARRAY_SIZE(dev_self)) { | ||
| 348 | IRDA_ERROR("%s(), maximum number of supported chips reached!\n", __FUNCTION__); | ||
| 349 | return -ENOMEM; | ||
| 350 | } | ||
| 351 | |||
| 254 | IRDA_MESSAGE("%s, Found chip at base=0x%03x\n", driver_name, | 352 | IRDA_MESSAGE("%s, Found chip at base=0x%03x\n", driver_name, |
| 255 | info->cfg_base); | 353 | info->cfg_base); |
| 256 | 354 | ||
| @@ -271,8 +369,8 @@ static int __init nsc_ircc_open(int i, chipio_t *info) | |||
| 271 | spin_lock_init(&self->lock); | 369 | spin_lock_init(&self->lock); |
| 272 | 370 | ||
| 273 | /* Need to store self somewhere */ | 371 | /* Need to store self somewhere */ |
| 274 | dev_self[i] = self; | 372 | dev_self[chip_index] = self; |
| 275 | self->index = i; | 373 | self->index = chip_index; |
| 276 | 374 | ||
| 277 | /* Initialize IO */ | 375 | /* Initialize IO */ |
| 278 | self->io.cfg_base = info->cfg_base; | 376 | self->io.cfg_base = info->cfg_base; |
| @@ -351,7 +449,7 @@ static int __init nsc_ircc_open(int i, chipio_t *info) | |||
| 351 | 449 | ||
| 352 | /* Check if user has supplied a valid dongle id or not */ | 450 | /* Check if user has supplied a valid dongle id or not */ |
| 353 | if ((dongle_id <= 0) || | 451 | if ((dongle_id <= 0) || |
| 354 | (dongle_id >= (sizeof(dongle_types) / sizeof(dongle_types[0]))) ) { | 452 | (dongle_id >= ARRAY_SIZE(dongle_types))) { |
| 355 | dongle_id = nsc_ircc_read_dongle_id(self->io.fir_base); | 453 | dongle_id = nsc_ircc_read_dongle_id(self->io.fir_base); |
| 356 | 454 | ||
| 357 | IRDA_MESSAGE("%s, Found dongle: %s\n", driver_name, | 455 | IRDA_MESSAGE("%s, Found dongle: %s\n", driver_name, |
| @@ -364,11 +462,18 @@ static int __init nsc_ircc_open(int i, chipio_t *info) | |||
| 364 | self->io.dongle_id = dongle_id; | 462 | self->io.dongle_id = dongle_id; |
| 365 | nsc_ircc_init_dongle_interface(self->io.fir_base, dongle_id); | 463 | nsc_ircc_init_dongle_interface(self->io.fir_base, dongle_id); |
| 366 | 464 | ||
| 367 | pmdev = pm_register(PM_SYS_DEV, PM_SYS_IRDA, nsc_ircc_pmproc); | 465 | self->pldev = platform_device_register_simple(NSC_IRCC_DRIVER_NAME, |
| 368 | if (pmdev) | 466 | self->index, NULL, 0); |
| 369 | pmdev->data = self; | 467 | if (IS_ERR(self->pldev)) { |
| 468 | err = PTR_ERR(self->pldev); | ||
| 469 | goto out5; | ||
| 470 | } | ||
| 471 | platform_set_drvdata(self->pldev, self); | ||
| 370 | 472 | ||
| 371 | return 0; | 473 | return chip_index; |
| 474 | |||
| 475 | out5: | ||
| 476 | unregister_netdev(dev); | ||
| 372 | out4: | 477 | out4: |
| 373 | dma_free_coherent(NULL, self->tx_buff.truesize, | 478 | dma_free_coherent(NULL, self->tx_buff.truesize, |
| 374 | self->tx_buff.head, self->tx_buff_dma); | 479 | self->tx_buff.head, self->tx_buff_dma); |
| @@ -379,7 +484,7 @@ static int __init nsc_ircc_open(int i, chipio_t *info) | |||
| 379 | release_region(self->io.fir_base, self->io.fir_ext); | 484 | release_region(self->io.fir_base, self->io.fir_ext); |
| 380 | out1: | 485 | out1: |
| 381 | free_netdev(dev); | 486 | free_netdev(dev); |
| 382 | dev_self[i] = NULL; | 487 | dev_self[chip_index] = NULL; |
| 383 | return err; | 488 | return err; |
| 384 | } | 489 | } |
| 385 | 490 | ||
| @@ -399,6 +504,8 @@ static int __exit nsc_ircc_close(struct nsc_ircc_cb *self) | |||
| 399 | 504 | ||
| 400 | iobase = self->io.fir_base; | 505 | iobase = self->io.fir_base; |
| 401 | 506 | ||
| 507 | platform_device_unregister(self->pldev); | ||
| 508 | |||
| 402 | /* Remove netdevice */ | 509 | /* Remove netdevice */ |
| 403 | unregister_netdev(self->netdev); | 510 | unregister_netdev(self->netdev); |
| 404 | 511 | ||
| @@ -806,6 +913,43 @@ static int nsc_ircc_probe_39x(nsc_chip_t *chip, chipio_t *info) | |||
| 806 | return 0; | 913 | return 0; |
| 807 | } | 914 | } |
| 808 | 915 | ||
| 916 | /* PNP probing */ | ||
| 917 | static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *id) | ||
| 918 | { | ||
| 919 | memset(&pnp_info, 0, sizeof(chipio_t)); | ||
| 920 | pnp_info.irq = -1; | ||
| 921 | pnp_info.dma = -1; | ||
| 922 | pnp_succeeded = 1; | ||
| 923 | |||
| 924 | /* There don't seem to be any way to get the cfg_base. | ||
| 925 | * On my box, cfg_base is in the PnP descriptor of the | ||
| 926 | * motherboard. Oh well... Jean II */ | ||
| 927 | |||
| 928 | if (pnp_port_valid(dev, 0) && | ||
| 929 | !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) | ||
| 930 | pnp_info.fir_base = pnp_port_start(dev, 0); | ||
| 931 | |||
| 932 | if (pnp_irq_valid(dev, 0) && | ||
| 933 | !(pnp_irq_flags(dev, 0) & IORESOURCE_DISABLED)) | ||
| 934 | pnp_info.irq = pnp_irq(dev, 0); | ||
| 935 | |||
| 936 | if (pnp_dma_valid(dev, 0) && | ||
| 937 | !(pnp_dma_flags(dev, 0) & IORESOURCE_DISABLED)) | ||
| 938 | pnp_info.dma = pnp_dma(dev, 0); | ||
| 939 | |||
| 940 | IRDA_DEBUG(0, "%s() : From PnP, found firbase 0x%03X ; irq %d ; dma %d.\n", | ||
| 941 | __FUNCTION__, pnp_info.fir_base, pnp_info.irq, pnp_info.dma); | ||
| 942 | |||
| 943 | if((pnp_info.fir_base == 0) || | ||
| 944 | (pnp_info.irq == -1) || (pnp_info.dma == -1)) { | ||
| 945 | /* Returning an error will disable the device. Yuck ! */ | ||
| 946 | //return -EINVAL; | ||
| 947 | pnp_succeeded = 0; | ||
| 948 | } | ||
| 949 | |||
| 950 | return 0; | ||
| 951 | } | ||
| 952 | |||
| 809 | /* | 953 | /* |
| 810 | * Function nsc_ircc_setup (info) | 954 | * Function nsc_ircc_setup (info) |
| 811 | * | 955 | * |
| @@ -2161,45 +2305,83 @@ static struct net_device_stats *nsc_ircc_net_get_stats(struct net_device *dev) | |||
| 2161 | return &self->stats; | 2305 | return &self->stats; |
| 2162 | } | 2306 | } |
| 2163 | 2307 | ||
| 2164 | static void nsc_ircc_suspend(struct nsc_ircc_cb *self) | 2308 | static int nsc_ircc_suspend(struct platform_device *dev, pm_message_t state) |
| 2165 | { | 2309 | { |
| 2166 | IRDA_MESSAGE("%s, Suspending\n", driver_name); | 2310 | struct nsc_ircc_cb *self = platform_get_drvdata(dev); |
| 2311 | int bank; | ||
| 2312 | unsigned long flags; | ||
| 2313 | int iobase = self->io.fir_base; | ||
| 2167 | 2314 | ||
| 2168 | if (self->io.suspended) | 2315 | if (self->io.suspended) |
| 2169 | return; | 2316 | return 0; |
| 2170 | 2317 | ||
| 2171 | nsc_ircc_net_close(self->netdev); | 2318 | IRDA_DEBUG(1, "%s, Suspending\n", driver_name); |
| 2172 | 2319 | ||
| 2320 | rtnl_lock(); | ||
| 2321 | if (netif_running(self->netdev)) { | ||
| 2322 | netif_device_detach(self->netdev); | ||
| 2323 | spin_lock_irqsave(&self->lock, flags); | ||
| 2324 | /* Save current bank */ | ||
| 2325 | bank = inb(iobase+BSR); | ||
| 2326 | |||
| 2327 | /* Disable interrupts */ | ||
| 2328 | switch_bank(iobase, BANK0); | ||
| 2329 | outb(0, iobase+IER); | ||
| 2330 | |||
| 2331 | /* Restore bank register */ | ||
| 2332 | outb(bank, iobase+BSR); | ||
| 2333 | |||
| 2334 | spin_unlock_irqrestore(&self->lock, flags); | ||
| 2335 | free_irq(self->io.irq, self->netdev); | ||
| 2336 | disable_dma(self->io.dma); | ||
| 2337 | } | ||
| 2173 | self->io.suspended = 1; | 2338 | self->io.suspended = 1; |
| 2339 | rtnl_unlock(); | ||
| 2340 | |||
| 2341 | return 0; | ||
| 2174 | } | 2342 | } |
| 2175 | 2343 | ||
| 2176 | static void nsc_ircc_wakeup(struct nsc_ircc_cb *self) | 2344 | static int nsc_ircc_resume(struct platform_device *dev) |
| 2177 | { | 2345 | { |
| 2346 | struct nsc_ircc_cb *self = platform_get_drvdata(dev); | ||
| 2347 | unsigned long flags; | ||
| 2348 | |||
| 2178 | if (!self->io.suspended) | 2349 | if (!self->io.suspended) |
| 2179 | return; | 2350 | return 0; |
| 2180 | 2351 | ||
| 2352 | IRDA_DEBUG(1, "%s, Waking up\n", driver_name); | ||
| 2353 | |||
| 2354 | rtnl_lock(); | ||
| 2181 | nsc_ircc_setup(&self->io); | 2355 | nsc_ircc_setup(&self->io); |
| 2182 | nsc_ircc_net_open(self->netdev); | 2356 | nsc_ircc_init_dongle_interface(self->io.fir_base, self->io.dongle_id); |
| 2183 | |||
| 2184 | IRDA_MESSAGE("%s, Waking up\n", driver_name); | ||
| 2185 | 2357 | ||
| 2358 | if (netif_running(self->netdev)) { | ||
| 2359 | if (request_irq(self->io.irq, nsc_ircc_interrupt, 0, | ||
| 2360 | self->netdev->name, self->netdev)) { | ||
| 2361 | IRDA_WARNING("%s, unable to allocate irq=%d\n", | ||
| 2362 | driver_name, self->io.irq); | ||
| 2363 | |||
| 2364 | /* | ||
| 2365 | * Don't fail resume process, just kill this | ||
| 2366 | * network interface | ||
| 2367 | */ | ||
| 2368 | unregister_netdevice(self->netdev); | ||
| 2369 | } else { | ||
| 2370 | spin_lock_irqsave(&self->lock, flags); | ||
| 2371 | nsc_ircc_change_speed(self, self->io.speed); | ||
| 2372 | spin_unlock_irqrestore(&self->lock, flags); | ||
| 2373 | netif_device_attach(self->netdev); | ||
| 2374 | } | ||
| 2375 | |||
| 2376 | } else { | ||
| 2377 | spin_lock_irqsave(&self->lock, flags); | ||
| 2378 | nsc_ircc_change_speed(self, 9600); | ||
| 2379 | spin_unlock_irqrestore(&self->lock, flags); | ||
| 2380 | } | ||
| 2186 | self->io.suspended = 0; | 2381 | self->io.suspended = 0; |
| 2187 | } | 2382 | rtnl_unlock(); |
| 2188 | 2383 | ||
| 2189 | static int nsc_ircc_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data) | 2384 | return 0; |
| 2190 | { | ||
| 2191 | struct nsc_ircc_cb *self = (struct nsc_ircc_cb*) dev->data; | ||
| 2192 | if (self) { | ||
| 2193 | switch (rqst) { | ||
| 2194 | case PM_SUSPEND: | ||
| 2195 | nsc_ircc_suspend(self); | ||
| 2196 | break; | ||
| 2197 | case PM_RESUME: | ||
| 2198 | nsc_ircc_wakeup(self); | ||
| 2199 | break; | ||
| 2200 | } | ||
| 2201 | } | ||
| 2202 | return 0; | ||
| 2203 | } | 2385 | } |
| 2204 | 2386 | ||
| 2205 | MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); | 2387 | MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); |
diff --git a/drivers/net/irda/nsc-ircc.h b/drivers/net/irda/nsc-ircc.h index 6edf7e514624..dacf671abcd6 100644 --- a/drivers/net/irda/nsc-ircc.h +++ b/drivers/net/irda/nsc-ircc.h | |||
| @@ -269,7 +269,7 @@ struct nsc_ircc_cb { | |||
| 269 | __u32 new_speed; | 269 | __u32 new_speed; |
| 270 | int index; /* Instance index */ | 270 | int index; /* Instance index */ |
| 271 | 271 | ||
| 272 | struct pm_dev *dev; | 272 | struct platform_device *pldev; |
| 273 | }; | 273 | }; |
| 274 | 274 | ||
| 275 | static inline void switch_bank(int iobase, int bank) | 275 | static inline void switch_bank(int iobase, int bank) |
diff --git a/drivers/net/irda/sir_dongle.c b/drivers/net/irda/sir_dongle.c index 8d225921ae7b..d7e32d9554fc 100644 --- a/drivers/net/irda/sir_dongle.c +++ b/drivers/net/irda/sir_dongle.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
| 17 | #include <linux/smp_lock.h> | 17 | #include <linux/smp_lock.h> |
| 18 | #include <linux/kmod.h> | 18 | #include <linux/kmod.h> |
| 19 | #include <linux/mutex.h> | ||
| 19 | 20 | ||
| 20 | #include <net/irda/irda.h> | 21 | #include <net/irda/irda.h> |
| 21 | 22 | ||
| @@ -28,7 +29,7 @@ | |||
| 28 | */ | 29 | */ |
| 29 | 30 | ||
| 30 | static LIST_HEAD(dongle_list); /* list of registered dongle drivers */ | 31 | static LIST_HEAD(dongle_list); /* list of registered dongle drivers */ |
| 31 | static DECLARE_MUTEX(dongle_list_lock); /* protects the list */ | 32 | static DEFINE_MUTEX(dongle_list_lock); /* protects the list */ |
| 32 | 33 | ||
| 33 | int irda_register_dongle(struct dongle_driver *new) | 34 | int irda_register_dongle(struct dongle_driver *new) |
| 34 | { | 35 | { |
| @@ -38,25 +39,25 @@ int irda_register_dongle(struct dongle_driver *new) | |||
| 38 | IRDA_DEBUG(0, "%s : registering dongle \"%s\" (%d).\n", | 39 | IRDA_DEBUG(0, "%s : registering dongle \"%s\" (%d).\n", |
| 39 | __FUNCTION__, new->driver_name, new->type); | 40 | __FUNCTION__, new->driver_name, new->type); |
| 40 | 41 | ||
| 41 | down(&dongle_list_lock); | 42 | mutex_lock(&dongle_list_lock); |
| 42 | list_for_each(entry, &dongle_list) { | 43 | list_for_each(entry, &dongle_list) { |
| 43 | drv = list_entry(entry, struct dongle_driver, dongle_list); | 44 | drv = list_entry(entry, struct dongle_driver, dongle_list); |
| 44 | if (new->type == drv->type) { | 45 | if (new->type == drv->type) { |
| 45 | up(&dongle_list_lock); | 46 | mutex_unlock(&dongle_list_lock); |
| 46 | return -EEXIST; | 47 | return -EEXIST; |
| 47 | } | 48 | } |
| 48 | } | 49 | } |
| 49 | list_add(&new->dongle_list, &dongle_list); | 50 | list_add(&new->dongle_list, &dongle_list); |
| 50 | up(&dongle_list_lock); | 51 | mutex_unlock(&dongle_list_lock); |
| 51 | return 0; | 52 | return 0; |
| 52 | } | 53 | } |
| 53 | EXPORT_SYMBOL(irda_register_dongle); | 54 | EXPORT_SYMBOL(irda_register_dongle); |
| 54 | 55 | ||
| 55 | int irda_unregister_dongle(struct dongle_driver *drv) | 56 | int irda_unregister_dongle(struct dongle_driver *drv) |
| 56 | { | 57 | { |
| 57 | down(&dongle_list_lock); | 58 | mutex_lock(&dongle_list_lock); |
| 58 | list_del(&drv->dongle_list); | 59 | list_del(&drv->dongle_list); |
| 59 | up(&dongle_list_lock); | 60 | mutex_unlock(&dongle_list_lock); |
| 60 | return 0; | 61 | return 0; |
| 61 | } | 62 | } |
| 62 | EXPORT_SYMBOL(irda_unregister_dongle); | 63 | EXPORT_SYMBOL(irda_unregister_dongle); |
| @@ -75,7 +76,7 @@ int sirdev_get_dongle(struct sir_dev *dev, IRDA_DONGLE type) | |||
| 75 | return -EBUSY; | 76 | return -EBUSY; |
| 76 | 77 | ||
| 77 | /* serialize access to the list of registered dongles */ | 78 | /* serialize access to the list of registered dongles */ |
| 78 | down(&dongle_list_lock); | 79 | mutex_lock(&dongle_list_lock); |
| 79 | 80 | ||
| 80 | list_for_each(entry, &dongle_list) { | 81 | list_for_each(entry, &dongle_list) { |
| 81 | drv = list_entry(entry, struct dongle_driver, dongle_list); | 82 | drv = list_entry(entry, struct dongle_driver, dongle_list); |
| @@ -109,14 +110,14 @@ int sirdev_get_dongle(struct sir_dev *dev, IRDA_DONGLE type) | |||
| 109 | if (!drv->open || (err=drv->open(dev))!=0) | 110 | if (!drv->open || (err=drv->open(dev))!=0) |
| 110 | goto out_reject; /* failed to open driver */ | 111 | goto out_reject; /* failed to open driver */ |
| 111 | 112 | ||
| 112 | up(&dongle_list_lock); | 113 | mutex_unlock(&dongle_list_lock); |
| 113 | return 0; | 114 | return 0; |
| 114 | 115 | ||
| 115 | out_reject: | 116 | out_reject: |
| 116 | dev->dongle_drv = NULL; | 117 | dev->dongle_drv = NULL; |
| 117 | module_put(drv->owner); | 118 | module_put(drv->owner); |
| 118 | out_unlock: | 119 | out_unlock: |
| 119 | up(&dongle_list_lock); | 120 | mutex_unlock(&dongle_list_lock); |
| 120 | return err; | 121 | return err; |
| 121 | } | 122 | } |
| 122 | 123 | ||
diff --git a/drivers/net/irda/toim3232-sir.c b/drivers/net/irda/toim3232-sir.c new file mode 100644 index 000000000000..aa1a9b0ed83e --- /dev/null +++ b/drivers/net/irda/toim3232-sir.c | |||
| @@ -0,0 +1,375 @@ | |||
| 1 | /********************************************************************* | ||
| 2 | * | ||
| 3 | * Filename: toim3232-sir.c | ||
| 4 | * Version: 1.0 | ||
| 5 | * Description: Implementation of dongles based on the Vishay/Temic | ||
| 6 | * TOIM3232 SIR Endec chipset. Currently only the | ||
| 7 | * IRWave IR320ST-2 is tested, although it should work | ||
| 8 | * with any TOIM3232 or TOIM4232 chipset based RS232 | ||
| 9 | * dongle with minimal modification. | ||
| 10 | * Based heavily on the Tekram driver (tekram.c), | ||
| 11 | * with thanks to Dag Brattli and Martin Diehl. | ||
| 12 | * Status: Experimental. | ||
| 13 | * Author: David Basden <davidb-irda@rcpt.to> | ||
| 14 | * Created at: Thu Feb 09 23:47:32 2006 | ||
| 15 | * | ||
| 16 | * Copyright (c) 2006 David Basden. | ||
| 17 | * Copyright (c) 1998-1999 Dag Brattli, | ||
| 18 | * Copyright (c) 2002 Martin Diehl, | ||
| 19 | * All Rights Reserved. | ||
| 20 | * | ||
| 21 | * This program is free software; you can redistribute it and/or | ||
| 22 | * modify it under the terms of the GNU General Public License as | ||
| 23 | * published by the Free Software Foundation; either version 2 of | ||
| 24 | * the License, or (at your option) any later version. | ||
| 25 | * | ||
| 26 | * Neither Dag Brattli nor University of Tromsø admit liability nor | ||
| 27 | * provide warranty for any of this software. This material is | ||
| 28 | * provided "AS-IS" and at no charge. | ||
| 29 | * | ||
| 30 | ********************************************************************/ | ||
| 31 | |||
| 32 | /* | ||
| 33 | * This driver has currently only been tested on the IRWave IR320ST-2 | ||
| 34 | * | ||
| 35 | * PROTOCOL: | ||
| 36 | * | ||
| 37 | * The protocol for talking to the TOIM3232 is quite easy, and is | ||
| 38 | * designed to interface with RS232 with only level convertors. The | ||
| 39 | * BR/~D line on the chip is brought high to signal 'command mode', | ||
| 40 | * where a command byte is sent to select the baudrate of the RS232 | ||
| 41 | * interface and the pulse length of the IRDA output. When BR/~D | ||
| 42 | * is brought low, the dongle then changes to the selected baudrate, | ||
| 43 | * and the RS232 interface is used for data until BR/~D is brought | ||
| 44 | * high again. The initial speed for the TOIMx323 after RESET is | ||
| 45 | * 9600 baud. The baudrate for command-mode is the last selected | ||
| 46 | * baud-rate, or 9600 after a RESET. | ||
| 47 | * | ||
| 48 | * The dongle I have (below) adds some extra hardware on the front end, | ||
| 49 | * but this is mostly directed towards pariasitic power from the RS232 | ||
| 50 | * line rather than changing very much about how to communicate with | ||
| 51 | * the TOIM3232. | ||
| 52 | * | ||
| 53 | * The protocol to talk to the TOIM4232 chipset seems to be almost | ||
| 54 | * identical to the TOIM3232 (and the 4232 datasheet is more detailed) | ||
| 55 | * so this code will probably work on that as well, although I haven't | ||
| 56 | * tested it on that hardware. | ||
| 57 | * | ||
| 58 | * Target dongle variations that might be common: | ||
| 59 | * | ||
| 60 | * DTR and RTS function: | ||
| 61 | * The data sheet for the 4232 has a sample implementation that hooks the | ||
| 62 | * DTR and RTS lines to the RESET and BaudRate/~Data lines of the | ||
| 63 | * chip (through line-converters). Given both DTR and RTS would have to | ||
| 64 | * be held low in normal operation, and the TOIMx232 requires +5V to | ||
| 65 | * signal ground, most dongle designers would almost certainly choose | ||
| 66 | * an implementation that kept at least one of DTR or RTS high in | ||
| 67 | * normal operation to provide power to the dongle, but will likely | ||
| 68 | * vary between designs. | ||
| 69 | * | ||
| 70 | * User specified command bits: | ||
| 71 | * There are two user-controllable output lines from the TOIMx232 that | ||
| 72 | * can be set low or high by setting the appropriate bits in the | ||
| 73 | * high-nibble of the command byte (when setting speed and pulse length). | ||
| 74 | * These might be used to switch on and off added hardware or extra | ||
| 75 | * dongle features. | ||
| 76 | * | ||
| 77 | * | ||
| 78 | * Target hardware: IRWave IR320ST-2 | ||
| 79 | * | ||
| 80 | * The IRWave IR320ST-2 is a simple dongle based on the Vishay/Temic | ||
| 81 | * TOIM3232 SIR Endec and the Vishay/Temic TFDS4500 SIR IRDA transciever. | ||
| 82 | * It uses a hex inverter and some discrete components to buffer and | ||
| 83 | * line convert the RS232 down to 5V. | ||
| 84 | * | ||
| 85 | * The dongle is powered through a voltage regulator, fed by a large | ||
| 86 | * capacitor. To switch the dongle on, DTR is brought high to charge | ||
| 87 | * the capacitor and drive the voltage regulator. DTR isn't associated | ||
| 88 | * with any control lines on the TOIM3232. Parisitic power is also taken | ||
| 89 | * from the RTS, TD and RD lines when brought high, but through resistors. | ||
| 90 | * When DTR is low, the circuit might lose power even with RTS high. | ||
| 91 | * | ||
| 92 | * RTS is inverted and attached to the BR/~D input pin. When RTS | ||
| 93 | * is high, BR/~D is low, and the TOIM3232 is in the normal 'data' mode. | ||
| 94 | * RTS is brought low, BR/~D is high, and the TOIM3232 is in 'command | ||
| 95 | * mode'. | ||
| 96 | * | ||
| 97 | * For some unknown reason, the RESET line isn't actually connected | ||
| 98 | * to anything. This means to reset the dongle to get it to a known | ||
| 99 | * state (9600 baud) you must drop DTR and RTS low, wait for the power | ||
| 100 | * capacitor to discharge, and then bring DTR (and RTS for data mode) | ||
| 101 | * high again, and wait for the capacitor to charge, the power supply | ||
| 102 | * to stabilise, and the oscillator clock to stabilise. | ||
| 103 | * | ||
| 104 | * Fortunately, if the current baudrate is known, the chipset can | ||
| 105 | * easily change speed by entering command mode without having to | ||
| 106 | * reset the dongle first. | ||
| 107 | * | ||
| 108 | * Major Components: | ||
| 109 | * | ||
| 110 | * - Vishay/Temic TOIM3232 SIR Endec to change RS232 pulse timings | ||
| 111 | * to IRDA pulse timings | ||
| 112 | * - 3.6864MHz crystal to drive TOIM3232 clock oscillator | ||
| 113 | * - DM74lS04M Inverting Hex line buffer for RS232 input buffering | ||
| 114 | * and level conversion | ||
| 115 | * - PJ2951AC 150mA voltage regulator | ||
| 116 | * - Vishay/Temic TFDS4500 SIR IRDA front-end transceiver | ||
| 117 | * | ||
| 118 | */ | ||
| 119 | |||
| 120 | #include <linux/module.h> | ||
| 121 | #include <linux/delay.h> | ||
| 122 | #include <linux/init.h> | ||
| 123 | |||
| 124 | #include <net/irda/irda.h> | ||
| 125 | |||
| 126 | #include "sir-dev.h" | ||
| 127 | |||
| 128 | static int toim3232delay = 150; /* default is 150 ms */ | ||
| 129 | module_param(toim3232delay, int, 0); | ||
| 130 | MODULE_PARM_DESC(toim3232delay, "toim3232 dongle write complete delay"); | ||
| 131 | |||
| 132 | #if 0 | ||
| 133 | static int toim3232flipdtr = 0; /* default is DTR high to reset */ | ||
| 134 | module_param(toim3232flipdtr, int, 0); | ||
| 135 | MODULE_PARM_DESC(toim3232flipdtr, "toim3232 dongle invert DTR (Reset)"); | ||
| 136 | |||
| 137 | static int toim3232fliprts = 0; /* default is RTS high for baud change */ | ||
| 138 | module_param(toim3232fliptrs, int, 0); | ||
| 139 | MODULE_PARM_DESC(toim3232fliprts, "toim3232 dongle invert RTS (BR/D)"); | ||
| 140 | #endif | ||
| 141 | |||
| 142 | static int toim3232_open(struct sir_dev *); | ||
| 143 | static int toim3232_close(struct sir_dev *); | ||
| 144 | static int toim3232_change_speed(struct sir_dev *, unsigned); | ||
| 145 | static int toim3232_reset(struct sir_dev *); | ||
| 146 | |||
| 147 | #define TOIM3232_115200 0x00 | ||
| 148 | #define TOIM3232_57600 0x01 | ||
| 149 | #define TOIM3232_38400 0x02 | ||
| 150 | #define TOIM3232_19200 0x03 | ||
| 151 | #define TOIM3232_9600 0x06 | ||
| 152 | #define TOIM3232_2400 0x0A | ||
| 153 | |||
| 154 | #define TOIM3232_PW 0x10 /* Pulse select bit */ | ||
| 155 | |||
| 156 | static struct dongle_driver toim3232 = { | ||
| 157 | .owner = THIS_MODULE, | ||
| 158 | .driver_name = "Vishay TOIM3232", | ||
| 159 | .type = IRDA_TOIM3232_DONGLE, | ||
| 160 | .open = toim3232_open, | ||
| 161 | .close = toim3232_close, | ||
| 162 | .reset = toim3232_reset, | ||
| 163 | .set_speed = toim3232_change_speed, | ||
| 164 | }; | ||
| 165 | |||
| 166 | static int __init toim3232_sir_init(void) | ||
| 167 | { | ||
| 168 | if (toim3232delay < 1 || toim3232delay > 500) | ||
| 169 | toim3232delay = 200; | ||
| 170 | IRDA_DEBUG(1, "%s - using %d ms delay\n", | ||
| 171 | toim3232.driver_name, toim3232delay); | ||
| 172 | return irda_register_dongle(&toim3232); | ||
| 173 | } | ||
| 174 | |||
| 175 | static void __exit toim3232_sir_cleanup(void) | ||
| 176 | { | ||
| 177 | irda_unregister_dongle(&toim3232); | ||
| 178 | } | ||
| 179 | |||
| 180 | static int toim3232_open(struct sir_dev *dev) | ||
| 181 | { | ||
| 182 | struct qos_info *qos = &dev->qos; | ||
| 183 | |||
| 184 | IRDA_DEBUG(2, "%s()\n", __FUNCTION__); | ||
| 185 | |||
| 186 | /* Pull the lines high to start with. | ||
| 187 | * | ||
| 188 | * For the IR320ST-2, we need to charge the main supply capacitor to | ||
| 189 | * switch the device on. We keep DTR high throughout to do this. | ||
| 190 | * When RTS, TD and RD are high, they will also trickle-charge the | ||
| 191 | * cap. RTS is high for data transmission, and low for baud rate select. | ||
| 192 | * -- DGB | ||
| 193 | */ | ||
| 194 | sirdev_set_dtr_rts(dev, TRUE, TRUE); | ||
| 195 | |||
| 196 | /* The TOI3232 supports many speeds between 1200bps and 115000bps. | ||
| 197 | * We really only care about those supported by the IRDA spec, but | ||
| 198 | * 38400 seems to be implemented in many places */ | ||
| 199 | qos->baud_rate.bits &= IR_2400|IR_9600|IR_19200|IR_38400|IR_57600|IR_115200; | ||
| 200 | |||
| 201 | /* From the tekram driver. Not sure what a reasonable value is -- DGB */ | ||
| 202 | qos->min_turn_time.bits = 0x01; /* Needs at least 10 ms */ | ||
| 203 | irda_qos_bits_to_value(qos); | ||
| 204 | |||
| 205 | /* irda thread waits 50 msec for power settling */ | ||
| 206 | |||
| 207 | return 0; | ||
| 208 | } | ||
| 209 | |||
| 210 | static int toim3232_close(struct sir_dev *dev) | ||
| 211 | { | ||
| 212 | IRDA_DEBUG(2, "%s()\n", __FUNCTION__); | ||
| 213 | |||
| 214 | /* Power off dongle */ | ||
| 215 | sirdev_set_dtr_rts(dev, FALSE, FALSE); | ||
| 216 | |||
| 217 | return 0; | ||
| 218 | } | ||
| 219 | |||
| 220 | /* | ||
| 221 | * Function toim3232change_speed (dev, state, speed) | ||
| 222 | * | ||
| 223 | * Set the speed for the TOIM3232 based dongle. Warning, this | ||
| 224 | * function must be called with a process context! | ||
| 225 | * | ||
| 226 | * Algorithm | ||
| 227 | * 1. keep DTR high but clear RTS to bring into baud programming mode | ||
| 228 | * 2. wait at least 7us to enter programming mode | ||
| 229 | * 3. send control word to set baud rate and timing | ||
| 230 | * 4. wait at least 1us | ||
| 231 | * 5. bring RTS high to enter DATA mode (RS232 is passed through to transceiver) | ||
| 232 | * 6. should take effect immediately (although probably worth waiting) | ||
| 233 | */ | ||
| 234 | |||
| 235 | #define TOIM3232_STATE_WAIT_SPEED (SIRDEV_STATE_DONGLE_SPEED + 1) | ||
| 236 | |||
| 237 | static int toim3232_change_speed(struct sir_dev *dev, unsigned speed) | ||
| 238 | { | ||
| 239 | unsigned state = dev->fsm.substate; | ||
| 240 | unsigned delay = 0; | ||
| 241 | u8 byte; | ||
| 242 | static int ret = 0; | ||
| 243 | |||
| 244 | IRDA_DEBUG(2, "%s()\n", __FUNCTION__); | ||
| 245 | |||
| 246 | switch(state) { | ||
| 247 | case SIRDEV_STATE_DONGLE_SPEED: | ||
| 248 | |||
| 249 | /* Figure out what we are going to send as a control byte */ | ||
| 250 | switch (speed) { | ||
| 251 | case 2400: | ||
| 252 | byte = TOIM3232_PW|TOIM3232_2400; | ||
| 253 | break; | ||
| 254 | default: | ||
| 255 | speed = 9600; | ||
| 256 | ret = -EINVAL; | ||
| 257 | /* fall thru */ | ||
| 258 | case 9600: | ||
| 259 | byte = TOIM3232_PW|TOIM3232_9600; | ||
| 260 | break; | ||
| 261 | case 19200: | ||
| 262 | byte = TOIM3232_PW|TOIM3232_19200; | ||
| 263 | break; | ||
| 264 | case 38400: | ||
| 265 | byte = TOIM3232_PW|TOIM3232_38400; | ||
| 266 | break; | ||
| 267 | case 57600: | ||
| 268 | byte = TOIM3232_PW|TOIM3232_57600; | ||
| 269 | break; | ||
| 270 | case 115200: | ||
| 271 | byte = TOIM3232_115200; | ||
| 272 | break; | ||
| 273 | } | ||
| 274 | |||
| 275 | /* Set DTR, Clear RTS: Go into baud programming mode */ | ||
| 276 | sirdev_set_dtr_rts(dev, TRUE, FALSE); | ||
| 277 | |||
| 278 | /* Wait at least 7us */ | ||
| 279 | udelay(14); | ||
| 280 | |||
| 281 | /* Write control byte */ | ||
| 282 | sirdev_raw_write(dev, &byte, 1); | ||
| 283 | |||
| 284 | dev->speed = speed; | ||
| 285 | |||
| 286 | state = TOIM3232_STATE_WAIT_SPEED; | ||
| 287 | delay = toim3232delay; | ||
| 288 | break; | ||
| 289 | |||
| 290 | case TOIM3232_STATE_WAIT_SPEED: | ||
| 291 | /* Have transmitted control byte * Wait for 'at least 1us' */ | ||
| 292 | udelay(14); | ||
| 293 | |||
| 294 | /* Set DTR, Set RTS: Go into normal data mode */ | ||
| 295 | sirdev_set_dtr_rts(dev, TRUE, TRUE); | ||
| 296 | |||
| 297 | /* Wait (TODO: check this is needed) */ | ||
| 298 | udelay(50); | ||
| 299 | break; | ||
| 300 | |||
| 301 | default: | ||
| 302 | printk(KERN_ERR "%s - undefined state %d\n", __FUNCTION__, state); | ||
| 303 | ret = -EINVAL; | ||
| 304 | break; | ||
| 305 | } | ||
| 306 | |||
| 307 | dev->fsm.substate = state; | ||
| 308 | return (delay > 0) ? delay : ret; | ||
| 309 | } | ||
| 310 | |||
| 311 | /* | ||
| 312 | * Function toim3232reset (driver) | ||
| 313 | * | ||
| 314 | * This function resets the toim3232 dongle. Warning, this function | ||
| 315 | * must be called with a process context!! | ||
| 316 | * | ||
| 317 | * What we should do is: | ||
| 318 | * 0. Pull RESET high | ||
| 319 | * 1. Wait for at least 7us | ||
| 320 | * 2. Pull RESET low | ||
| 321 | * 3. Wait for at least 7us | ||
| 322 | * 4. Pull BR/~D high | ||
| 323 | * 5. Wait for at least 7us | ||
| 324 | * 6. Send control byte to set baud rate | ||
| 325 | * 7. Wait at least 1us after stop bit | ||
| 326 | * 8. Pull BR/~D low | ||
| 327 | * 9. Should then be in data mode | ||
| 328 | * | ||
| 329 | * Because the IR320ST-2 doesn't have the RESET line connected for some reason, | ||
| 330 | * we'll have to do something else. | ||
| 331 | * | ||
| 332 | * The default speed after a RESET is 9600, so lets try just bringing it up in | ||
| 333 | * data mode after switching it off, waiting for the supply capacitor to | ||
| 334 | * discharge, and then switch it back on. This isn't actually pulling RESET | ||
| 335 | * high, but it seems to have the same effect. | ||
| 336 | * | ||
| 337 | * This behaviour will probably work on dongles that have the RESET line connected, | ||
| 338 | * but if not, add a flag for the IR320ST-2, and implment the above-listed proper | ||
| 339 | * behaviour. | ||
| 340 | * | ||
| 341 | * RTS is inverted and then fed to BR/~D, so to put it in programming mode, we | ||
| 342 | * need to have pull RTS low | ||
| 343 | */ | ||
| 344 | |||
| 345 | static int toim3232_reset(struct sir_dev *dev) | ||
| 346 | { | ||
| 347 | IRDA_DEBUG(2, "%s()\n", __FUNCTION__); | ||
| 348 | |||
| 349 | /* Switch off both DTR and RTS to switch off dongle */ | ||
| 350 | sirdev_set_dtr_rts(dev, FALSE, FALSE); | ||
| 351 | |||
| 352 | /* Should sleep a while. This might be evil doing it this way.*/ | ||
| 353 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
| 354 | schedule_timeout(msecs_to_jiffies(50)); | ||
| 355 | |||
| 356 | /* Set DTR, Set RTS (data mode) */ | ||
| 357 | sirdev_set_dtr_rts(dev, TRUE, TRUE); | ||
| 358 | |||
| 359 | /* Wait at least 10 ms for power to stabilize again */ | ||
| 360 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
| 361 | schedule_timeout(msecs_to_jiffies(10)); | ||
| 362 | |||
| 363 | /* Speed should now be 9600 */ | ||
| 364 | dev->speed = 9600; | ||
| 365 | |||
| 366 | return 0; | ||
| 367 | } | ||
| 368 | |||
| 369 | MODULE_AUTHOR("David Basden <davidb-linux@rcpt.to>"); | ||
| 370 | MODULE_DESCRIPTION("Vishay/Temic TOIM3232 based dongle driver"); | ||
| 371 | MODULE_LICENSE("GPL"); | ||
| 372 | MODULE_ALIAS("irda-dongle-12"); /* IRDA_TOIM3232_DONGLE */ | ||
| 373 | |||
| 374 | module_init(toim3232_sir_init); | ||
| 375 | module_exit(toim3232_sir_cleanup); | ||
diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c index a9f49f058cfb..97a49e0be76b 100644 --- a/drivers/net/irda/vlsi_ir.c +++ b/drivers/net/irda/vlsi_ir.c | |||
| @@ -1887,7 +1887,7 @@ static int __init vlsi_mod_init(void) | |||
| 1887 | vlsi_proc_root->owner = THIS_MODULE; | 1887 | vlsi_proc_root->owner = THIS_MODULE; |
| 1888 | } | 1888 | } |
| 1889 | 1889 | ||
| 1890 | ret = pci_module_init(&vlsi_irda_driver); | 1890 | ret = pci_register_driver(&vlsi_irda_driver); |
| 1891 | 1891 | ||
| 1892 | if (ret && vlsi_proc_root) | 1892 | if (ret && vlsi_proc_root) |
| 1893 | remove_proc_entry(PROC_DIR, NULL); | 1893 | remove_proc_entry(PROC_DIR, NULL); |
