From 7fb55de51d21e744a36297eef343c4f766064f80 Mon Sep 17 00:00:00 2001 From: lyx Date: Sun, 17 Jul 2011 02:17:50 -0700 Subject: [PATCH] newton: add irda serial driver --- arch/arm/configs/rk29_newton_defconfig | 2 + arch/arm/mach-rk29/board-rk29-newton.c | 9 +- drivers/net/irda/Kconfig | 9 + drivers/net/irda/Makefile | 3 +- drivers/net/irda/bu92725guw.c | 4 +- drivers/net/irda/bu92725guw.h | 9 + drivers/net/irda/ir_serial.c | 681 +++++++++++++++++++++++++ drivers/net/irda/ir_serial.h | 6 + drivers/net/irda/rk29_ir.c | 14 +- drivers/net/irda/rk29_ir.h | 13 - 10 files changed, 723 insertions(+), 27 deletions(-) create mode 100755 drivers/net/irda/ir_serial.c create mode 100755 drivers/net/irda/ir_serial.h diff --git a/arch/arm/configs/rk29_newton_defconfig b/arch/arm/configs/rk29_newton_defconfig index 44b793271c73..5c41a8eda87d 100755 --- a/arch/arm/configs/rk29_newton_defconfig +++ b/arch/arm/configs/rk29_newton_defconfig @@ -530,6 +530,8 @@ CONFIG_IRNET=y # CONFIG_SIGMATEL_FIR is not set # CONFIG_MCS_FIR is not set CONFIG_RK_IRDA=y +CONFIG_RK_IRDA_UART=y +# CONFIG_RK_IRDA_NET is not set CONFIG_BU92725GUW=y CONFIG_BT=y CONFIG_BT_L2CAP=y diff --git a/arch/arm/mach-rk29/board-rk29-newton.c b/arch/arm/mach-rk29/board-rk29-newton.c index 6c52e23afaaa..302b8442e9d5 100755 --- a/arch/arm/mach-rk29/board-rk29-newton.c +++ b/arch/arm/mach-rk29/board-rk29-newton.c @@ -445,7 +445,8 @@ static int bu92747guw_power_ctl(int enable) } else { nPowerOnCount--; - if (nPowerOnCount == 0) {//power down final + if (nPowerOnCount <= 0) {//power down final + nPowerOnCount = 0; //smc0_exit(); gpio_set_value(BU92747GUW_PWDN_PIN, GPIO_LOW); } @@ -495,7 +496,11 @@ static struct irda_info rk29_irda_info = { }; static struct platform_device irda_device = { - .name = "rk_irda", +#ifdef CONFIG_RK_IRDA_NET + .name = "rk_irda", +#else + .name = "bu92747_irda", +#endif .id = -1, .dev = { .platform_data = &rk29_irda_info, diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig index 1fb4578fd430..a5db500c3146 100755 --- a/drivers/net/irda/Kconfig +++ b/drivers/net/irda/Kconfig @@ -394,6 +394,15 @@ config RK_IRDA Say Y or M here if you want to build support for the rk29 built-in IRDA interface which can support both SIR, MIR and FIR. +choice + depends on RK_IRDA + prompt "irda device driver" +config RK_IRDA_UART + bool "uses irda as a serial device" +config RK_IRDA_NET + bool "uses irda as a network device" +endchoice + choice depends on RK_IRDA prompt "irda module select" diff --git a/drivers/net/irda/Makefile b/drivers/net/irda/Makefile index 8aa32fa6ddb7..7ee600f24633 100755 --- a/drivers/net/irda/Makefile +++ b/drivers/net/irda/Makefile @@ -37,7 +37,8 @@ obj-$(CONFIG_EP7211_DONGLE) += ep7211-sir.o obj-$(CONFIG_KINGSUN_DONGLE) += kingsun-sir.o obj-$(CONFIG_KSDAZZLE_DONGLE) += ksdazzle-sir.o obj-$(CONFIG_KS959_DONGLE) += ks959-sir.o -obj-$(CONFIG_RK_IRDA) += rk29_ir.o +obj-$(CONFIG_RK_IRDA_UART) += ir_serial.o +obj-$(CONFIG_RK_IRDA_NET) += rk29_ir.o obj-$(CONFIG_BU92725GUW) += bu92725guw.o # The SIR helper module diff --git a/drivers/net/irda/bu92725guw.c b/drivers/net/irda/bu92725guw.c index 866e666e89c3..6625b4d66804 100755 --- a/drivers/net/irda/bu92725guw.c +++ b/drivers/net/irda/bu92725guw.c @@ -80,7 +80,7 @@ void irda_hw_deinit(struct rk29_irda *si) // smc0_init(&si->irda_base_addr); } -int irda_hw_startup(struct rk29_irda *si) +int irda_hw_startup(void) { volatile u16 val; int i=0; @@ -115,7 +115,7 @@ int irda_hw_startup(struct rk29_irda *si) return 0; } -int irda_hw_shutdown(struct rk29_irda *si) +int irda_hw_shutdown(void) { RK29IR_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__); diff --git a/drivers/net/irda/bu92725guw.h b/drivers/net/irda/bu92725guw.h index 1c3d941a4b56..70c7f06344e1 100755 --- a/drivers/net/irda/bu92725guw.h +++ b/drivers/net/irda/bu92725guw.h @@ -219,4 +219,13 @@ extern void BU92725GUW_send_data(u8 *buf1, u16 len1, u8 *buf2, u16 len2); /*dump register*/ extern void BU92725GUW_dump_register(void); +int irda_hw_tx_enable_irq(enum eTrans_Mode mode); +int irda_hw_get_mode(void); +void irda_hw_set_moderx(void); +int irda_hw_get_irqsrc(void); +int irda_hw_shutdown(void); +int irda_hw_startup(void); +int irda_hw_set_speed(u32 speed); + + #endif /*__BU92725GUW_H*/ diff --git a/drivers/net/irda/ir_serial.c b/drivers/net/irda/ir_serial.c new file mode 100755 index 000000000000..c51a3520ca51 --- /dev/null +++ b/drivers/net/irda/ir_serial.c @@ -0,0 +1,681 @@ +/* + * + * Copyright (C) 2011 liuyixing + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * + *note: serial driver for IrDA(SIR and FIR) device + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bu92725guw.h" + +struct bu92747_port { + struct device *dev; + struct irda_info *pdata; + struct uart_port port; + + int cts; /* last CTS received for flow ctrl */ + int tx_empty; /* last TX empty bit */ + + spinlock_t conf_lock; /* shared data */ + int conf_commit; /* need to make changes */ + int conf; /* configuration for the MAX31000 + * (bits 0-7, bits 8-11 are irqs) */ + int rts_commit; /* need to change rts */ + int rts; /* rts status */ + int baud; /* current baud rate */ + + int parity; /* keeps track if we should send parity */ + int rx_enabled; /* if we should rx chars */ + + int irq; /* irq assigned to the bu92747 */ + + int minor; /* minor number */ + int crystal; /* 1 if 3.6864Mhz crystal 0 for 1.8432 */ + int loopback; /* 1 if we are in loopback mode */ + + /* for handling irqs: need workqueue since we do spi_sync */ + struct workqueue_struct *workqueue; + struct work_struct work; + /* set to 1 to make the workhandler exit as soon as possible */ + int force_end_work; + /* need to know we are suspending to avoid deadlock on workqueue */ + int suspending; + + /* poll time (in ms) for ctrl lines */ + int poll_time; + /* and its timer */ + struct timer_list timer; +}; + +#define MAX_BU92747 1 +#define BU92747_MAJOR 204 +#define BU92747_MINOR 209 + +static struct bu92747_port *bu92747s[MAX_BU92747]; /* the chips */ +static DEFINE_MUTEX(bu92747s_lock); /* race on probe */ +#define IS_FIR(s) ((s)->baud >= 4000000) +static int max_rate = 4000000; +static u8 g_receive_buf[BU92725GUW_FIFO_SIZE]; + +#if 0 +#define BU92747_IRDA_DBG(x...) printk(x) +#else +#define BU92747_IRDA_DBG(x...) +#endif + +static int bu92747_irda_do_rx(struct bu92747_port *s) +{ + int i; + unsigned int ch, flag; + int len; + BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__); + + if (s->rx_enabled == 0) { + BU92725GUW_clr_fifo(); + BU92725GUW_reset(); + return 0; + } + + len = BU92725GUW_get_data(g_receive_buf); + flag = TTY_NORMAL; + //printk("receive data:\n"); + for (i=0;iport, 0, 0, ch, flag); + s->port.icount.rx++; + //printk("%d ", ch); + } + //printk("\n"); + + return len; + } + +static int bu92747_irda_do_tx(struct bu92747_port *s) +{ + int i; + struct circ_buf *xmit = &s->port.state->xmit; + int len = uart_circ_chars_pending(xmit); + BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__); + + if (IS_FIR(s)) { + //printk("fir sending.....\n"); + irda_hw_tx_enable_irq(BU92725GUW_FIR); + } + else { + //printk("sir sending.....\n"); + irda_hw_tx_enable_irq(BU92725GUW_SIR); + } + + BU92747_IRDA_DBG("data:\n"); + for (i=0; ibuf[xmit->tail+i]); + } + BU92747_IRDA_DBG("\n"); + + BU92725GUW_send_data(xmit->buf+xmit->tail, len, NULL, 0); + s->port.icount.tx += len; + xmit->tail = (xmit->tail + len) & (UART_XMIT_SIZE - 1); + + if (len>0) + s->tx_empty = 0; + + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(&s->port); + + return len; +} + +static void bu92747_irda_dowork(struct bu92747_port *s) +{ + if (!s->force_end_work && !work_pending(&s->work) && + !freezing(current) && !s->suspending) + queue_work(s->workqueue, &s->work); +} + +static void bu92747_irda_work(struct work_struct *w) +{ + struct bu92747_port *s = container_of(w, struct bu92747_port, work); + u32 irq_src = 0; + struct circ_buf *xmit = &s->port.state->xmit; + + dev_dbg(s->dev, "%s\n", __func__); + BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__); + + if (!s->force_end_work && !freezing(current)) { + //BU92725GUW_dump_register(); + + if (!uart_circ_empty(xmit) && !uart_tx_stopped(&s->port)) { + if (s->tx_empty) + bu92747_irda_do_tx(s); + else + bu92747_irda_dowork(s); + } + } +} + +static irqreturn_t bu92747_irda_irq(int irqno, void *dev_id) +{ + struct bu92747_port *s = dev_id; + u32 irq_src = 0; + + dev_dbg(s->dev, "%s\n", __func__); + BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__); + irq_src = irda_hw_get_irqsrc(); + printk("[%s][%d], 0x%x\n",__FUNCTION__,__LINE__, irq_src); + /* error */ + if (irq_src & (REG_INT_TO| REG_INT_CRC | REG_INT_OE | REG_INT_FE + | REG_INT_AC | REG_INT_DECE | REG_INT_RDOE | REG_INT_DEX)) { + BU92747_IRDA_DBG("[%s][%d]: do err\n", __FUNCTION__, __LINE__); + //BU92725GUW_dump_register(); + //BU92725GUW_clr_fifo(); + BU92725GUW_reset(); + } + + if (irq_src & (REG_INT_DRX | FRM_EVT_RX_EOFRX | FRM_EVT_RX_RDE)) { + bu92747_irda_do_rx(s); + tty_flip_buffer_push(s->port.state->port.tty); + } + + if ((irq_src & REG_INT_EOF) && (s->port.state->port.tty != NULL)) { + tty_flip_buffer_push(s->port.state->port.tty); + } + + if (irq_src & (FRM_EVT_TX_TXE | FRM_EVT_TX_WRE)) { + s->tx_empty = 1; + irda_hw_set_moderx(); + } + + return IRQ_HANDLED; +} + + +static void bu92747_irda_stop_tx(struct uart_port *port) +{ + struct bu92747_port *s = container_of(port, + struct bu92747_port, + port); + BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__); + + dev_dbg(s->dev, "%s\n", __func__); +} + +static void bu92747_irda_start_tx(struct uart_port *port) +{ + struct bu92747_port *s = container_of(port, + struct bu92747_port, + port); + BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__); + + dev_dbg(s->dev, "%s\n", __func__); + + if (s->tx_empty) + bu92747_irda_do_tx(s); + else + bu92747_irda_dowork(s); +} + +static void bu92747_irda_stop_rx(struct uart_port *port) +{ + struct bu92747_port *s = container_of(port, + struct bu92747_port, + port); + + dev_dbg(s->dev, "%s\n", __func__); + BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__); + + s->rx_enabled = 0; + + bu92747_irda_dowork(s); +} + +static unsigned int bu92747_irda_tx_empty(struct uart_port *port) +{ + struct bu92747_port *s = container_of(port, + struct bu92747_port, + port); + + BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__); + dev_dbg(s->dev, "%s\n", __func__); + + /* may not be truly up-to-date */ + bu92747_irda_dowork(s); + return s->tx_empty; +} + +static const char *bu92747_irda_type(struct uart_port *port) +{ + struct bu92747_port *s = container_of(port, + struct bu92747_port, + port); + + BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__); + dev_dbg(s->dev, "%s\n", __func__); + + return s->port.type == PORT_IRDA ? "BU92747" : NULL; +} + +static void bu92747_irda_release_port(struct uart_port *port) +{ + struct bu92747_port *s = container_of(port, + struct bu92747_port, + port); + + BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__); + dev_dbg(s->dev, "%s\n", __func__); +} + +static void bu92747_irda_config_port(struct uart_port *port, int flags) +{ + struct bu92747_port *s = container_of(port, + struct bu92747_port, + port); + + BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__); + dev_dbg(s->dev, "%s\n", __func__); + + if (flags & UART_CONFIG_TYPE) + s->port.type = PORT_IRDA; +} + +static int bu92747_irda_verify_port(struct uart_port *port, + struct serial_struct *ser) +{ + struct bu92747_port *s = container_of(port, + struct bu92747_port, + port); + int ret = -EINVAL; + + BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__); + dev_dbg(s->dev, "%s\n", __func__); + + if (ser->type == PORT_UNKNOWN || ser->type == PORT_IRDA) + ret = 0; + + return ret; +} + +static void bu92747_irda_shutdown(struct uart_port *port) +{ + struct bu92747_port *s = container_of(port, + struct bu92747_port, + port); + + BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__); + dev_dbg(s->dev, "%s\n", __func__); + + if (s->suspending) + return; + + s->force_end_work = 1; + + if (s->workqueue) { + flush_workqueue(s->workqueue); + destroy_workqueue(s->workqueue); + s->workqueue = NULL; + } + if (s->irq) + free_irq(s->irq, s); + + irda_hw_shutdown(); + if (s->pdata->irda_pwr_ctl) + s->pdata->irda_pwr_ctl(0); + +} + +static int bu92747_irda_startup(struct uart_port *port) +{ + struct bu92747_port *s = container_of(port, + struct bu92747_port, + port); + char b[32]; + + BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__); + dev_dbg(s->dev, "%s\n", __func__); + + s->baud = 9600; + s->rx_enabled = 1; + + if (s->suspending) + return 0; + + s->tx_empty = 1; + s->force_end_work = 0; + + sprintf(b, "bu92747_irda-%d", s->minor); + s->workqueue = create_freezeable_workqueue(b); + if (!s->workqueue) { + dev_warn(s->dev, "cannot create workqueue\n"); + return -EBUSY; + } + INIT_WORK(&s->work, bu92747_irda_work); + + if (request_irq(s->irq, bu92747_irda_irq, + IRQ_TYPE_EDGE_FALLING, "bu92747_irda", s) < 0) { + dev_warn(s->dev, "cannot allocate irq %d\n", s->irq); + s->irq = 0; + destroy_workqueue(s->workqueue); + s->workqueue = NULL; + return -EBUSY; + } + + disable_irq(s->irq); + + if (s->pdata->irda_pwr_ctl) + s->pdata->irda_pwr_ctl(1); + + irda_hw_startup(); + irda_hw_set_moderx(); + + enable_irq(s->irq); + + return 0; +} + +static int bu92747_irda_request_port(struct uart_port *port) +{ + struct bu92747_port *s = container_of(port, + struct bu92747_port, + port); + + BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__); + dev_dbg(s->dev, "%s\n", __func__); + return 0; +} + +static void bu92747_irda_break_ctl(struct uart_port *port, int break_state) +{ + struct bu92747_port *s = container_of(port, + struct bu92747_port, + port); + + BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__); + dev_dbg(s->dev, "%s\n", __func__); +} + +static unsigned int bu92747_irda_get_mctrl(struct uart_port *port) +{ + struct bu92747_port *s = container_of(port, + struct bu92747_port, + port); + + dev_dbg(s->dev, "%s\n", __func__); + + return TIOCM_DSR | TIOCM_CAR; +} + +static void bu92747_irda_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ + struct bu92747_port *s = container_of(port, + struct bu92747_port, + port); + int rts; + + dev_dbg(s->dev, "%s\n", __func__); + BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__); +} + +static void +bu92747_irda_set_termios(struct uart_port *port, struct ktermios *termios, + struct ktermios *old) +{ + struct bu92747_port *s = container_of(port, + struct bu92747_port, + port); + int baud = 0; + unsigned cflag; + struct tty_struct *tty = s->port.state->port.tty; + + BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__); + dev_dbg(s->dev, "%s\n", __func__); + if (!tty) + return; + + cflag = termios->c_cflag; + baud = uart_get_baud_rate(port, termios, old, 0, max_rate); + + switch (baud) { + case 9600: + case 19200: + case 38400: + case 57600: + case 115200: + case 4000000: + if (s->baud!=baud) { + irda_hw_set_speed(baud); + s->baud = baud; + } + break; + + default: + break; + } + + uart_update_timeout(port, termios->c_cflag, baud); + +} + +static struct uart_ops bu92747_irda_ops = { + .tx_empty = bu92747_irda_tx_empty, + .set_mctrl = bu92747_irda_set_mctrl, + .get_mctrl = bu92747_irda_get_mctrl, + .stop_tx = bu92747_irda_stop_tx, + .start_tx = bu92747_irda_start_tx, + .stop_rx = bu92747_irda_stop_rx, + //.enable_ms = bu92747_irda_enable_ms, + .break_ctl = bu92747_irda_break_ctl, + .startup = bu92747_irda_startup, + .shutdown = bu92747_irda_shutdown, + .set_termios = bu92747_irda_set_termios, + .type = bu92747_irda_type, + .release_port = bu92747_irda_release_port, + .request_port = bu92747_irda_request_port, + .config_port = bu92747_irda_config_port, + .verify_port = bu92747_irda_verify_port, +}; + +static struct uart_driver bu92747_irda_uart_driver = { + .owner = THIS_MODULE, + .driver_name = "ttyIr", + .dev_name = "ttyIr", + .major = BU92747_MAJOR, + .minor = BU92747_MINOR, + .nr = MAX_BU92747, +}; + +static int uart_driver_registered; +static int __devinit bu92747_irda_probe(struct platform_device *pdev) +{ + int i, retval; + struct irda_info *platdata = pdev->dev.platform_data; + + BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__); + if (!platdata) { + dev_warn(&pdev->dev, "no platform data info\n"); + return -1; + } + + mutex_lock(&bu92747s_lock); + + if (!uart_driver_registered) { + uart_driver_registered = 1; + retval = uart_register_driver(&bu92747_irda_uart_driver); + if (retval) { + printk(KERN_ERR "Couldn't register bu92747 uart driver\n"); + mutex_unlock(&bu92747s_lock); + return retval; + } + } + + for (i = 0; i < MAX_BU92747; i++) + if (!bu92747s[i]) + break; + if (i == MAX_BU92747) { + dev_warn(&pdev->dev, "too many bu92747 chips\n"); + mutex_unlock(&bu92747s_lock); + return -ENOMEM; + } + + bu92747s[i] = kzalloc(sizeof(struct bu92747_port), GFP_KERNEL); + if (!bu92747s[i]) { + dev_warn(&pdev->dev, + "kmalloc for bu92747 structure %d failed!\n", i); + mutex_unlock(&bu92747s_lock); + return -ENOMEM; + } + bu92747s[i]->dev = &pdev->dev; + bu92747s[i]->irq = gpio_to_irq(platdata->intr_pin); + if (platdata->iomux_init) + platdata->iomux_init(); + bu92747s[i]->pdata = platdata; + spin_lock_init(&bu92747s[i]->conf_lock); + dev_set_drvdata(&pdev->dev, bu92747s[i]); + bu92747s[i]->minor = i; + dev_dbg(&pdev->dev, "%s: adding port %d\n", __func__, i); + bu92747s[i]->port.irq = bu92747s[i]->irq; + bu92747s[i]->port.fifosize = BU92725GUW_FIFO_SIZE; + bu92747s[i]->port.ops = &bu92747_irda_ops; + bu92747s[i]->port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; + bu92747s[i]->port.line = i; + bu92747s[i]->port.type = PORT_IRDA; + bu92747s[i]->port.dev = &pdev->dev; + retval = uart_add_one_port(&bu92747_irda_uart_driver, &bu92747s[i]->port); + if (retval < 0) + dev_warn(&pdev->dev, + "uart_add_one_port failed for line %d with error %d\n", + i, retval); + + /* set shutdown mode to save power. Will be woken-up on open */ + if (bu92747s[i]->pdata->irda_pwr_ctl) + bu92747s[i]->pdata->irda_pwr_ctl(0); + + mutex_unlock(&bu92747s_lock); + + return 0; +} + +static int __devexit bu92747_irda_remove(struct platform_device *pdev) +{ + struct bu92747_port *s = dev_get_drvdata(&pdev->dev); + int i; + + BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__); + mutex_lock(&bu92747s_lock); + + /* find out the index for the chip we are removing */ + for (i = 0; i < MAX_BU92747; i++) + if (bu92747s[i] == s) + break; + + dev_dbg(&pdev->dev, "%s: removing port %d\n", __func__, i); + uart_remove_one_port(&bu92747_irda_uart_driver, &bu92747s[i]->port); + kfree(bu92747s[i]); + bu92747s[i] = NULL; + + /* check if this is the last chip we have */ + for (i = 0; i < MAX_BU92747; i++) + if (bu92747s[i]) { + mutex_unlock(&bu92747s_lock); + return 0; + } + pr_debug("removing bu92747 driver\n"); + uart_unregister_driver(&bu92747_irda_uart_driver); + + mutex_unlock(&bu92747s_lock); + return 0; +} + + +#ifdef CONFIG_PM +static int bu92747_irda_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct bu92747_port *s = dev_get_drvdata(&pdev->dev); + + dev_dbg(s->dev, "%s\n", __func__); + + BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__); + disable_irq(s->irq); + + s->suspending = 1; + uart_suspend_port(&bu92747_irda_uart_driver, &s->port); + + irda_hw_shutdown(); + if (s->pdata->irda_pwr_ctl) + s->pdata->irda_pwr_ctl(0); + + return 0; +} + +static int bu92747_irda_resume(struct platform_device *pdev) +{ + struct bu92747_port *s = dev_get_drvdata(&pdev->dev); + + dev_dbg(s->dev, "%s\n", __func__); + + BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__); + if (s->pdata->irda_pwr_ctl) + s->pdata->irda_pwr_ctl(1); + + irda_hw_startup(); + + uart_resume_port(&bu92747_irda_uart_driver, &s->port); + s->suspending = 0; + + enable_irq(s->irq); + + if (s->workqueue) + bu92747_irda_dowork(s); + + return 0; +} +#else +#define bu92747_irda_suspend NULL +#define bu92747_irda_resume NULL +#endif + +static struct platform_driver bu92747_irda_driver = { + .driver = { + .name = "bu92747_irda", + .owner = THIS_MODULE, + }, + .probe = bu92747_irda_probe, + .remove = bu92747_irda_remove, + .suspend = bu92747_irda_suspend, + .resume = bu92747_irda_resume, +}; + +static int __init bu92747_irda_init(void) +{ + if (platform_driver_register(&bu92747_irda_driver) != 0) { + printk("Could not register irda driver\n"); + return -EINVAL; + } + return 0; +} + +static void __exit bu92747_irda_exit(void) +{ + platform_driver_unregister(&bu92747_irda_driver); +} + +module_init(bu92747_irda_init); +module_exit(bu92747_irda_exit); +MODULE_DESCRIPTION("BU92747 irda driver"); +MODULE_AUTHOR("liuyixing "); +MODULE_LICENSE("GPL"); + diff --git a/drivers/net/irda/ir_serial.h b/drivers/net/irda/ir_serial.h new file mode 100755 index 000000000000..c2abcac496e0 --- /dev/null +++ b/drivers/net/irda/ir_serial.h @@ -0,0 +1,6 @@ +#ifndef _IR_SERIAL_H_ +#define _IR_SERIAL_H_ + +#include "bu92725guw.h" + +#endif diff --git a/drivers/net/irda/rk29_ir.c b/drivers/net/irda/rk29_ir.c index 802e13e19cf6..22c1cdc11f7b 100755 --- a/drivers/net/irda/rk29_ir.c +++ b/drivers/net/irda/rk29_ir.c @@ -344,7 +344,7 @@ static int rk29_irda_start(struct net_device *dev) /* * Setup the smc port for the specified speed. */ - err = irda_hw_startup(si); + err = irda_hw_startup(); if (err) { printk("line %d: %s irda_hw_startup err\n", __LINE__, __func__); goto err_startup; @@ -378,7 +378,7 @@ static int rk29_irda_start(struct net_device *dev) err_irlap: si->open = 0; - irda_hw_shutdown(si); + irda_hw_shutdown(); if (si->pdata->irda_pwr_ctl) si->pdata->irda_pwr_ctl(0); err_startup: @@ -394,7 +394,7 @@ static int rk29_irda_stop(struct net_device *dev) RK29IR_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__); disable_irq(dev->irq); - irda_hw_shutdown(si); + irda_hw_shutdown(); /* * If we have been doing DMA receive, make sure we @@ -637,8 +637,6 @@ static int rk29_irda_probe(struct platform_device *pdev) * Initially enable HP-SIR modulation, and ensure that the port * is disabled. */ - irda_hw_init(si); - err = register_netdev(dev); if (err) { printk("line %d: rk29_ir register_netdev failed\n", __LINE__); @@ -653,7 +651,6 @@ static int rk29_irda_probe(struct platform_device *pdev) return 0; err_register: - irda_hw_deinit(si); kfree(si->tx_buff.head); err_mem_3: kfree(si->rx_buff.head); @@ -675,7 +672,6 @@ static int rk29_irda_remove(struct platform_device *pdev) kfree(si->tx_buff.head); kfree(si->rx_buff.head); free_netdev(dev); - irda_hw_deinit(si); } return 0; @@ -700,7 +696,7 @@ static int rk29_irda_suspend(struct platform_device *pdev, pm_message_t state) */ netif_device_detach(dev); disable_irq(dev->irq); - irda_hw_shutdown(si); + irda_hw_shutdown(); if (si->pdata->irda_pwr_ctl) si->pdata->irda_pwr_ctl(0); } @@ -737,7 +733,7 @@ static int rk29_irda_resume(struct platform_device *pdev) si->newspeed = 0; } - irda_hw_startup(si); + irda_hw_startup(); enable_irq(dev->irq); /* diff --git a/drivers/net/irda/rk29_ir.h b/drivers/net/irda/rk29_ir.h index ba4380fec5b0..beb3e7bc840c 100755 --- a/drivers/net/irda/rk29_ir.h +++ b/drivers/net/irda/rk29_ir.h @@ -35,18 +35,5 @@ struct rk29_irda { iobuff_t tx_buff; iobuff_t rx_buff; }; -extern void irda_hw_init(struct rk29_irda *si); -extern int irda_hw_get_mode(void); -extern void irda_hw_deinit(struct rk29_irda *si); -extern int irda_hw_startup(struct rk29_irda *si); -extern int irda_hw_shutdown(struct rk29_irda *si); -extern int irda_hw_set_speed(u32 speed); -extern int irda_hw_tx_enable_irq(enum eTrans_Mode mode); -extern int irda_hw_tx_enable(int len); -extern int irda_hw_get_irqsrc(void); -extern int irda_hw_get_data16(char* data8); -extern void irda_hw_set_moderx(void); -extern int irda_hw_get_mode(void); - #endif //__DRIVERS_NET_IRDA_RK29_IR_H -- 2.34.1