newton: add irda serial driver
authorlyx <lyx@rock-chips.com>
Sun, 17 Jul 2011 09:17:50 +0000 (02:17 -0700)
committerlyx <lyx@rock-chips.com>
Sun, 17 Jul 2011 09:17:50 +0000 (02:17 -0700)
arch/arm/configs/rk29_newton_defconfig
arch/arm/mach-rk29/board-rk29-newton.c
drivers/net/irda/Kconfig
drivers/net/irda/Makefile
drivers/net/irda/bu92725guw.c
drivers/net/irda/bu92725guw.h
drivers/net/irda/ir_serial.c [new file with mode: 0755]
drivers/net/irda/ir_serial.h [new file with mode: 0755]
drivers/net/irda/rk29_ir.c
drivers/net/irda/rk29_ir.h

index 44b793271c734acb436b0a111c2daadb184882ac..5c41a8eda87d94177ade791943b225576a9a5e12 100755 (executable)
@@ -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
index 6c52e23afaaad5223ed9e384ec3eded2839be98d..302b8442e9d5107966f22443a4477286ef40cb05 100755 (executable)
@@ -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,
index 1fb4578fd4302883feb3f1f3a59b5b1079ab6ba4..a5db500c314698069958f6c75b16ad6a32501c1d 100755 (executable)
@@ -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"
index 8aa32fa6ddb758f063ea11c90ad618760df364a9..7ee600f246338da5e925a0bf77543b1afd227b83 100755 (executable)
@@ -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
index 866e666e89c3886d663225244a7ad32ed3830cc8..6625b4d66804d80705ef52de91d643690166710d 100755 (executable)
@@ -80,7 +80,7 @@ void irda_hw_deinit(struct rk29_irda *si)
    // smc0_init(&si->irda_base_addr);\r
 }\r
 \r
-int irda_hw_startup(struct rk29_irda *si)\r
+int irda_hw_startup(void)\r
 {\r
     volatile u16 val;\r
     int i=0;\r
@@ -115,7 +115,7 @@ int irda_hw_startup(struct rk29_irda *si)
     return 0;\r
 }\r
 \r
-int irda_hw_shutdown(struct rk29_irda *si)\r
+int irda_hw_shutdown(void)\r
 {\r
        RK29IR_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);\r
 \r
index 1c3d941a4b56b38c1e48ac12f9235217d915c57e..70c7f06344e179d7c9545683268c9a1086efe9e9 100755 (executable)
@@ -219,4 +219,13 @@ extern void BU92725GUW_send_data(u8 *buf1, u16 len1, u8 *buf2, u16 len2);
 /*dump register*/\r
 extern void BU92725GUW_dump_register(void);\r
 \r
+int irda_hw_tx_enable_irq(enum eTrans_Mode mode);\r
+int irda_hw_get_mode(void);\r
+void irda_hw_set_moderx(void);\r
+int irda_hw_get_irqsrc(void);\r
+int irda_hw_shutdown(void);\r
+int irda_hw_startup(void);\r
+int irda_hw_set_speed(u32 speed);\r
+\r
+\r
 #endif /*__BU92725GUW_H*/\r
diff --git a/drivers/net/irda/ir_serial.c b/drivers/net/irda/ir_serial.c
new file mode 100755 (executable)
index 0000000..c51a352
--- /dev/null
@@ -0,0 +1,681 @@
+/*\r
+ *\r
+ *  Copyright (C) 2011 liuyixing <lyx@rock-chips.com>\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ *\r
+ *note: serial driver for IrDA(SIR and FIR) device\r
+ *\r
+ */\r
+\r
+#include <linux/delay.h>\r
+#include <linux/slab.h>\r
+#include <linux/device.h>\r
+#include <linux/serial_core.h>\r
+#include <linux/serial.h>\r
+#include <linux/freezer.h>\r
+#include <mach/board.h>\r
+#include <linux/irq.h>\r
+#include <mach/gpio.h>\r
+\r
+#include "bu92725guw.h"\r
+\r
+struct bu92747_port {\r
+       struct device           *dev;\r
+       struct irda_info *pdata;\r
+       struct uart_port port;\r
+       \r
+       int cts;                /* last CTS received for flow ctrl */\r
+       int tx_empty;           /* last TX empty bit */\r
+\r
+       spinlock_t conf_lock;   /* shared data */\r
+       int conf_commit;        /* need to make changes */\r
+       int conf;               /* configuration for the MAX31000\r
+                                * (bits 0-7, bits 8-11 are irqs) */\r
+       int rts_commit;         /* need to change rts */\r
+       int rts;                /* rts status */\r
+       int baud;               /* current baud rate */\r
+\r
+       int parity;             /* keeps track if we should send parity */\r
+       int rx_enabled;         /* if we should rx chars */\r
+\r
+       int irq;                /* irq assigned to the bu92747 */\r
+\r
+       int minor;              /* minor number */\r
+       int crystal;            /* 1 if 3.6864Mhz crystal 0 for 1.8432 */\r
+       int loopback;           /* 1 if we are in loopback mode */\r
+\r
+       /* for handling irqs: need workqueue since we do spi_sync */\r
+       struct workqueue_struct *workqueue;\r
+       struct work_struct work;\r
+       /* set to 1 to make the workhandler exit as soon as possible */\r
+       int  force_end_work;\r
+       /* need to know we are suspending to avoid deadlock on workqueue */\r
+       int suspending;\r
+\r
+       /* poll time (in ms) for ctrl lines */\r
+       int poll_time;\r
+       /* and its timer */\r
+       struct timer_list       timer;\r
+};\r
+\r
+#define MAX_BU92747 1\r
+#define BU92747_MAJOR 204\r
+#define BU92747_MINOR 209\r
+\r
+static struct bu92747_port *bu92747s[MAX_BU92747]; /* the chips */\r
+static DEFINE_MUTEX(bu92747s_lock);               /* race on probe */\r
+#define IS_FIR(s)              ((s)->baud >= 4000000)\r
+static int max_rate = 4000000; \r
+static u8 g_receive_buf[BU92725GUW_FIFO_SIZE];\r
+\r
+#if 0\r
+#define BU92747_IRDA_DBG(x...) printk(x)\r
+#else\r
+#define BU92747_IRDA_DBG(x...)\r
+#endif\r
+\r
+static int bu92747_irda_do_rx(struct bu92747_port *s)\r
+{\r
+       int i;\r
+       unsigned int ch, flag;\r
+       int len;\r
+       BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);\r
+\r
+       if (s->rx_enabled == 0) {\r
+               BU92725GUW_clr_fifo();\r
+               BU92725GUW_reset();\r
+               return 0;\r
+       }\r
+       \r
+       len = BU92725GUW_get_data(g_receive_buf);\r
+       flag = TTY_NORMAL;\r
+       //printk("receive data:\n");\r
+       for (i=0;i<len;i++) {\r
+               ch = g_receive_buf[i];\r
+               uart_insert_char(&s->port, 0, 0, ch, flag);\r
+               s->port.icount.rx++;\r
+               //printk("%d ", ch);\r
+       }\r
+       //printk("\n");\r
+       \r
+       return len;\r
+ }\r
+\r
+static int bu92747_irda_do_tx(struct bu92747_port *s)\r
+{\r
+       int i;\r
+       struct circ_buf *xmit = &s->port.state->xmit;\r
+       int len = uart_circ_chars_pending(xmit);\r
+       BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);\r
+       \r
+       if (IS_FIR(s)) {\r
+               //printk("fir sending.....\n");\r
+               irda_hw_tx_enable_irq(BU92725GUW_FIR);\r
+       }\r
+       else {          \r
+               //printk("sir sending.....\n");\r
+               irda_hw_tx_enable_irq(BU92725GUW_SIR);\r
+       }\r
+\r
+       BU92747_IRDA_DBG("data:\n");\r
+       for (i=0; i<len; i++) {\r
+               BU92747_IRDA_DBG("%d ", xmit->buf[xmit->tail+i]);\r
+       }\r
+       BU92747_IRDA_DBG("\n");\r
+       \r
+       BU92725GUW_send_data(xmit->buf+xmit->tail, len, NULL, 0);\r
+       s->port.icount.tx += len;\r
+       xmit->tail = (xmit->tail + len) & (UART_XMIT_SIZE - 1);\r
+\r
+       if (len>0)              \r
+               s->tx_empty = 0;\r
+       \r
+       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)\r
+               uart_write_wakeup(&s->port);\r
+\r
+       return len;\r
+}\r
+\r
+static void bu92747_irda_dowork(struct bu92747_port *s)\r
+{\r
+       if (!s->force_end_work && !work_pending(&s->work) &&\r
+               !freezing(current) && !s->suspending)\r
+               queue_work(s->workqueue, &s->work);\r
+}\r
+\r
+static void bu92747_irda_work(struct work_struct *w)\r
+{\r
+       struct bu92747_port *s = container_of(w, struct bu92747_port, work);\r
+       u32 irq_src = 0;        \r
+       struct circ_buf *xmit = &s->port.state->xmit;\r
+\r
+       dev_dbg(s->dev, "%s\n", __func__);\r
+       BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);\r
+\r
+       if (!s->force_end_work && !freezing(current)) {\r
+               //BU92725GUW_dump_register();\r
+\r
+               if (!uart_circ_empty(xmit) && !uart_tx_stopped(&s->port)) {\r
+                       if (s->tx_empty)\r
+                               bu92747_irda_do_tx(s);\r
+                       else \r
+                               bu92747_irda_dowork(s);\r
+               }\r
+       }\r
+}\r
+\r
+static irqreturn_t bu92747_irda_irq(int irqno, void *dev_id)\r
+{\r
+       struct bu92747_port *s = dev_id;\r
+       u32 irq_src = 0;        \r
+\r
+       dev_dbg(s->dev, "%s\n", __func__);\r
+       BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);\r
+       irq_src = irda_hw_get_irqsrc();\r
+       printk("[%s][%d], 0x%x\n",__FUNCTION__,__LINE__, irq_src);\r
+       /* error */\r
+       if (irq_src & (REG_INT_TO| REG_INT_CRC | REG_INT_OE | REG_INT_FE\r
+               | REG_INT_AC | REG_INT_DECE | REG_INT_RDOE | REG_INT_DEX)) {\r
+               BU92747_IRDA_DBG("[%s][%d]: do err\n", __FUNCTION__, __LINE__);\r
+               //BU92725GUW_dump_register();\r
+               //BU92725GUW_clr_fifo();\r
+               BU92725GUW_reset();\r
+       }\r
+       \r
+       if (irq_src & (REG_INT_DRX | FRM_EVT_RX_EOFRX | FRM_EVT_RX_RDE)) {\r
+               bu92747_irda_do_rx(s);\r
+               tty_flip_buffer_push(s->port.state->port.tty);\r
+       }\r
+       \r
+       if ((irq_src & REG_INT_EOF) && (s->port.state->port.tty != NULL)) {\r
+               tty_flip_buffer_push(s->port.state->port.tty);\r
+       }\r
+       \r
+       if (irq_src & (FRM_EVT_TX_TXE | FRM_EVT_TX_WRE)) {\r
+               s->tx_empty = 1;\r
+               irda_hw_set_moderx();\r
+       }\r
+       \r
+       return IRQ_HANDLED;\r
+}\r
+\r
+\r
+static void bu92747_irda_stop_tx(struct uart_port *port)\r
+{\r
+       struct bu92747_port *s = container_of(port,\r
+                                                 struct bu92747_port,\r
+                                                 port);\r
+       BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);\r
+\r
+       dev_dbg(s->dev, "%s\n", __func__);\r
+}\r
+\r
+static void bu92747_irda_start_tx(struct uart_port *port)\r
+{\r
+       struct bu92747_port *s = container_of(port,\r
+                                                 struct bu92747_port,\r
+                                                 port);\r
+       BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);\r
+\r
+       dev_dbg(s->dev, "%s\n", __func__);\r
+\r
+       if (s->tx_empty)\r
+               bu92747_irda_do_tx(s);\r
+       else \r
+               bu92747_irda_dowork(s);\r
+}\r
+\r
+static void bu92747_irda_stop_rx(struct uart_port *port)\r
+{\r
+       struct bu92747_port *s = container_of(port,\r
+                                                 struct bu92747_port,\r
+                                                 port);\r
+\r
+       dev_dbg(s->dev, "%s\n", __func__);\r
+       BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);\r
+\r
+       s->rx_enabled = 0;\r
+\r
+       bu92747_irda_dowork(s);\r
+}\r
+\r
+static unsigned int bu92747_irda_tx_empty(struct uart_port *port)\r
+{\r
+       struct bu92747_port *s = container_of(port,\r
+                                                 struct bu92747_port,\r
+                                                 port);\r
+\r
+       BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);\r
+       dev_dbg(s->dev, "%s\n", __func__);\r
+\r
+       /* may not be truly up-to-date */\r
+       bu92747_irda_dowork(s);\r
+       return s->tx_empty;\r
+}\r
+\r
+static const char *bu92747_irda_type(struct uart_port *port)\r
+{\r
+       struct bu92747_port *s = container_of(port,\r
+                                                 struct bu92747_port,\r
+                                                 port);\r
+\r
+       BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);\r
+       dev_dbg(s->dev, "%s\n", __func__);\r
+\r
+       return s->port.type == PORT_IRDA ? "BU92747" : NULL;\r
+}\r
+\r
+static void bu92747_irda_release_port(struct uart_port *port)\r
+{\r
+       struct bu92747_port *s = container_of(port,\r
+                                                 struct bu92747_port,\r
+                                                 port);\r
+\r
+       BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);\r
+       dev_dbg(s->dev, "%s\n", __func__);\r
+}\r
+\r
+static void bu92747_irda_config_port(struct uart_port *port, int flags)\r
+{\r
+       struct bu92747_port *s = container_of(port,\r
+                                                 struct bu92747_port,\r
+                                                 port);\r
+\r
+       BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);\r
+       dev_dbg(s->dev, "%s\n", __func__);\r
+\r
+       if (flags & UART_CONFIG_TYPE)\r
+               s->port.type = PORT_IRDA;\r
+}\r
+\r
+static int bu92747_irda_verify_port(struct uart_port *port,\r
+                                  struct serial_struct *ser)\r
+{\r
+       struct bu92747_port *s = container_of(port,\r
+                                                 struct bu92747_port,\r
+                                                 port);\r
+       int ret = -EINVAL;\r
+\r
+       BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);\r
+       dev_dbg(s->dev, "%s\n", __func__);\r
+\r
+       if (ser->type == PORT_UNKNOWN || ser->type == PORT_IRDA)\r
+               ret = 0;\r
+       \r
+       return ret;\r
+}\r
+\r
+static void bu92747_irda_shutdown(struct uart_port *port)\r
+{\r
+       struct bu92747_port *s = container_of(port,\r
+                                                 struct bu92747_port,\r
+                                                 port);\r
+\r
+       BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);\r
+       dev_dbg(s->dev, "%s\n", __func__);\r
+\r
+       if (s->suspending)\r
+               return;\r
+\r
+       s->force_end_work = 1;\r
+\r
+       if (s->workqueue) {\r
+               flush_workqueue(s->workqueue);\r
+               destroy_workqueue(s->workqueue);\r
+               s->workqueue = NULL;\r
+       }\r
+       if (s->irq)\r
+               free_irq(s->irq, s);\r
+       \r
+       irda_hw_shutdown();\r
+       if (s->pdata->irda_pwr_ctl)\r
+               s->pdata->irda_pwr_ctl(0);\r
+\r
+}\r
+\r
+static int bu92747_irda_startup(struct uart_port *port)\r
+{\r
+       struct bu92747_port *s = container_of(port,\r
+                                                 struct bu92747_port,\r
+                                                 port);\r
+       char b[32];\r
+\r
+       BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);\r
+       dev_dbg(s->dev, "%s\n", __func__);\r
+\r
+       s->baud = 9600;\r
+       s->rx_enabled = 1;\r
+\r
+       if (s->suspending)\r
+               return 0;\r
+\r
+       s->tx_empty = 1;\r
+       s->force_end_work = 0;\r
+\r
+       sprintf(b, "bu92747_irda-%d", s->minor);\r
+       s->workqueue = create_freezeable_workqueue(b);\r
+       if (!s->workqueue) {\r
+               dev_warn(s->dev, "cannot create workqueue\n");\r
+               return -EBUSY;\r
+       }\r
+       INIT_WORK(&s->work, bu92747_irda_work);\r
+\r
+       if (request_irq(s->irq, bu92747_irda_irq,\r
+                       IRQ_TYPE_EDGE_FALLING, "bu92747_irda", s) < 0) {\r
+               dev_warn(s->dev, "cannot allocate irq %d\n", s->irq);\r
+               s->irq = 0;\r
+               destroy_workqueue(s->workqueue);\r
+               s->workqueue = NULL;\r
+               return -EBUSY;\r
+       }\r
+\r
+       disable_irq(s->irq);\r
+\r
+       if (s->pdata->irda_pwr_ctl)\r
+               s->pdata->irda_pwr_ctl(1);\r
+\r
+       irda_hw_startup();\r
+       irda_hw_set_moderx();\r
+\r
+       enable_irq(s->irq);\r
+\r
+       return 0;\r
+}\r
+\r
+static int bu92747_irda_request_port(struct uart_port *port)\r
+{\r
+       struct bu92747_port *s = container_of(port,\r
+                                                 struct bu92747_port,\r
+                                                 port);\r
+\r
+       BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);\r
+       dev_dbg(s->dev, "%s\n", __func__);\r
+       return 0;\r
+}\r
+\r
+static void bu92747_irda_break_ctl(struct uart_port *port, int break_state)\r
+{\r
+       struct bu92747_port *s = container_of(port,\r
+                                                 struct bu92747_port,\r
+                                                 port);\r
+\r
+       BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);\r
+       dev_dbg(s->dev, "%s\n", __func__);\r
+}\r
+\r
+static unsigned int bu92747_irda_get_mctrl(struct uart_port *port)\r
+{\r
+       struct bu92747_port *s = container_of(port,\r
+                                                 struct bu92747_port,\r
+                                                 port);\r
+\r
+       dev_dbg(s->dev, "%s\n", __func__);\r
+\r
+       return  TIOCM_DSR | TIOCM_CAR;\r
+}\r
+\r
+static void bu92747_irda_set_mctrl(struct uart_port *port, unsigned int mctrl)\r
+{\r
+       struct bu92747_port *s = container_of(port,\r
+                                                 struct bu92747_port,\r
+                                                 port);\r
+       int rts;\r
+\r
+       dev_dbg(s->dev, "%s\n", __func__);\r
+       BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);\r
+}\r
+\r
+static void\r
+bu92747_irda_set_termios(struct uart_port *port, struct ktermios *termios,\r
+                       struct ktermios *old)\r
+{\r
+       struct bu92747_port *s = container_of(port,\r
+                                                 struct bu92747_port,\r
+                                                 port);\r
+       int baud = 0;\r
+       unsigned cflag;\r
+       struct tty_struct *tty = s->port.state->port.tty;\r
+\r
+       BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);\r
+       dev_dbg(s->dev, "%s\n", __func__);\r
+       if (!tty)\r
+               return;\r
+\r
+       cflag = termios->c_cflag;\r
+       baud = uart_get_baud_rate(port, termios, old, 0, max_rate);\r
+\r
+       switch (baud) {\r
+       case 9600:\r
+       case 19200:\r
+       case 38400:\r
+       case 57600:\r
+       case 115200:\r
+       case 4000000:\r
+               if (s->baud!=baud) {\r
+                       irda_hw_set_speed(baud);\r
+                       s->baud = baud;\r
+               }\r
+               break;\r
+\r
+       default:\r
+               break;\r
+       }\r
+       \r
+       uart_update_timeout(port, termios->c_cflag, baud);\r
+\r
+}\r
+\r
+static struct uart_ops bu92747_irda_ops = {\r
+       .tx_empty       = bu92747_irda_tx_empty,\r
+       .set_mctrl      = bu92747_irda_set_mctrl,\r
+       .get_mctrl      = bu92747_irda_get_mctrl,\r
+       .stop_tx        = bu92747_irda_stop_tx,\r
+       .start_tx       = bu92747_irda_start_tx,\r
+       .stop_rx        = bu92747_irda_stop_rx,\r
+       //.enable_ms      = bu92747_irda_enable_ms,\r
+       .break_ctl      = bu92747_irda_break_ctl,\r
+       .startup        = bu92747_irda_startup,\r
+       .shutdown       = bu92747_irda_shutdown,\r
+       .set_termios    = bu92747_irda_set_termios,\r
+       .type           = bu92747_irda_type,\r
+       .release_port   = bu92747_irda_release_port,\r
+       .request_port   = bu92747_irda_request_port,\r
+       .config_port    = bu92747_irda_config_port,\r
+       .verify_port    = bu92747_irda_verify_port,\r
+};\r
+\r
+static struct uart_driver bu92747_irda_uart_driver = {\r
+       .owner          = THIS_MODULE,\r
+       .driver_name    = "ttyIr",\r
+       .dev_name       = "ttyIr",\r
+       .major          = BU92747_MAJOR,\r
+       .minor          = BU92747_MINOR,\r
+       .nr             = MAX_BU92747,\r
+};\r
+\r
+static int uart_driver_registered;\r
+static int __devinit bu92747_irda_probe(struct platform_device *pdev)\r
+{\r
+       int i, retval;\r
+    struct irda_info *platdata = pdev->dev.platform_data;\r
+\r
+       BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);\r
+       if (!platdata) {\r
+               dev_warn(&pdev->dev, "no platform data info\n");\r
+               return -1;\r
+       }\r
+\r
+       mutex_lock(&bu92747s_lock);\r
+\r
+       if (!uart_driver_registered) {\r
+               uart_driver_registered = 1;\r
+               retval = uart_register_driver(&bu92747_irda_uart_driver);\r
+               if (retval) {\r
+                       printk(KERN_ERR "Couldn't register bu92747 uart driver\n");\r
+                       mutex_unlock(&bu92747s_lock);\r
+                       return retval;\r
+               }\r
+       }\r
+\r
+       for (i = 0; i < MAX_BU92747; i++)\r
+               if (!bu92747s[i])\r
+                       break;\r
+       if (i == MAX_BU92747) {\r
+               dev_warn(&pdev->dev, "too many bu92747 chips\n");\r
+               mutex_unlock(&bu92747s_lock);\r
+               return -ENOMEM;\r
+       }\r
+\r
+       bu92747s[i] = kzalloc(sizeof(struct bu92747_port), GFP_KERNEL);\r
+       if (!bu92747s[i]) {\r
+               dev_warn(&pdev->dev,\r
+                        "kmalloc for bu92747 structure %d failed!\n", i);\r
+               mutex_unlock(&bu92747s_lock);\r
+               return -ENOMEM;\r
+       }\r
+       bu92747s[i]->dev = &pdev->dev;\r
+       bu92747s[i]->irq = gpio_to_irq(platdata->intr_pin);\r
+       if (platdata->iomux_init)\r
+               platdata->iomux_init();\r
+       bu92747s[i]->pdata = platdata;\r
+       spin_lock_init(&bu92747s[i]->conf_lock);\r
+       dev_set_drvdata(&pdev->dev, bu92747s[i]);\r
+       bu92747s[i]->minor = i;\r
+       dev_dbg(&pdev->dev, "%s: adding port %d\n", __func__, i);\r
+       bu92747s[i]->port.irq = bu92747s[i]->irq;\r
+       bu92747s[i]->port.fifosize = BU92725GUW_FIFO_SIZE;\r
+       bu92747s[i]->port.ops = &bu92747_irda_ops;\r
+       bu92747s[i]->port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;\r
+       bu92747s[i]->port.line = i;\r
+       bu92747s[i]->port.type = PORT_IRDA;\r
+       bu92747s[i]->port.dev = &pdev->dev;\r
+       retval = uart_add_one_port(&bu92747_irda_uart_driver, &bu92747s[i]->port);\r
+       if (retval < 0)\r
+               dev_warn(&pdev->dev,\r
+                        "uart_add_one_port failed for line %d with error %d\n",\r
+                        i, retval);\r
+\r
+       /* set shutdown mode to save power. Will be woken-up on open */\r
+       if (bu92747s[i]->pdata->irda_pwr_ctl)\r
+               bu92747s[i]->pdata->irda_pwr_ctl(0);\r
+\r
+       mutex_unlock(&bu92747s_lock);\r
+       \r
+       return 0;\r
+}\r
+\r
+static int __devexit bu92747_irda_remove(struct platform_device *pdev)\r
+{\r
+       struct bu92747_port *s = dev_get_drvdata(&pdev->dev);\r
+       int i;\r
+\r
+       BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);\r
+       mutex_lock(&bu92747s_lock);\r
+\r
+       /* find out the index for the chip we are removing */\r
+       for (i = 0; i < MAX_BU92747; i++)\r
+               if (bu92747s[i] == s)\r
+                       break;\r
+\r
+       dev_dbg(&pdev->dev, "%s: removing port %d\n", __func__, i);\r
+       uart_remove_one_port(&bu92747_irda_uart_driver, &bu92747s[i]->port);\r
+       kfree(bu92747s[i]);\r
+       bu92747s[i] = NULL;\r
+\r
+       /* check if this is the last chip we have */\r
+       for (i = 0; i < MAX_BU92747; i++)\r
+               if (bu92747s[i]) {\r
+                       mutex_unlock(&bu92747s_lock);\r
+                       return 0;\r
+               }\r
+       pr_debug("removing bu92747 driver\n");\r
+       uart_unregister_driver(&bu92747_irda_uart_driver);\r
+\r
+       mutex_unlock(&bu92747s_lock);\r
+       return 0;\r
+}\r
+\r
+\r
+#ifdef CONFIG_PM\r
+static int bu92747_irda_suspend(struct platform_device *pdev, pm_message_t state)\r
+{\r
+       struct bu92747_port *s = dev_get_drvdata(&pdev->dev);\r
+\r
+       dev_dbg(s->dev, "%s\n", __func__);\r
+\r
+       BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);\r
+       disable_irq(s->irq);\r
+\r
+       s->suspending = 1;\r
+       uart_suspend_port(&bu92747_irda_uart_driver, &s->port);\r
+\r
+       irda_hw_shutdown();\r
+       if (s->pdata->irda_pwr_ctl)\r
+               s->pdata->irda_pwr_ctl(0);\r
+\r
+       return 0;\r
+}\r
+\r
+static int bu92747_irda_resume(struct platform_device *pdev)\r
+{\r
+       struct bu92747_port *s = dev_get_drvdata(&pdev->dev);\r
+\r
+       dev_dbg(s->dev, "%s\n", __func__);\r
+\r
+       BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);\r
+       if (s->pdata->irda_pwr_ctl)\r
+               s->pdata->irda_pwr_ctl(1);\r
+       \r
+       irda_hw_startup();\r
+\r
+       uart_resume_port(&bu92747_irda_uart_driver, &s->port);\r
+       s->suspending = 0;\r
+\r
+       enable_irq(s->irq);\r
+       \r
+       if (s->workqueue)\r
+               bu92747_irda_dowork(s);\r
+\r
+       return 0;\r
+}\r
+#else\r
+#define bu92747_irda_suspend NULL\r
+#define bu92747_irda_resume  NULL\r
+#endif\r
+\r
+static struct platform_driver bu92747_irda_driver = {\r
+       .driver = {\r
+               .name = "bu92747_irda",\r
+        .owner = THIS_MODULE,\r
+       },\r
+       .probe = bu92747_irda_probe,\r
+       .remove = bu92747_irda_remove,\r
+       .suspend = bu92747_irda_suspend,\r
+       .resume = bu92747_irda_resume,\r
+};\r
+\r
+static int __init bu92747_irda_init(void)\r
+{\r
+       if (platform_driver_register(&bu92747_irda_driver) != 0) {\r
+       printk("Could not register irda driver\n");\r
+       return -EINVAL;\r
+       }\r
+       return 0;\r
+}\r
+\r
+static void __exit bu92747_irda_exit(void)\r
+{\r
+       platform_driver_unregister(&bu92747_irda_driver);\r
+}\r
+\r
+module_init(bu92747_irda_init);\r
+module_exit(bu92747_irda_exit);\r
+MODULE_DESCRIPTION("BU92747 irda driver");\r
+MODULE_AUTHOR("liuyixing <lyx@rock-chips.com>");\r
+MODULE_LICENSE("GPL");\r
+\r
diff --git a/drivers/net/irda/ir_serial.h b/drivers/net/irda/ir_serial.h
new file mode 100755 (executable)
index 0000000..c2abcac
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _IR_SERIAL_H_\r
+#define _IR_SERIAL_H_\r
+\r
+#include "bu92725guw.h"\r
+\r
+#endif\r
index 802e13e19cf6f2f36291feeb82161c0b62fa9fea..22c1cdc11f7bec2db9128b13d1b573ef45e33af2 100755 (executable)
@@ -344,7 +344,7 @@ static int rk29_irda_start(struct net_device *dev)
        /*\r
         * Setup the smc port for the specified speed.\r
         */\r
-       err = irda_hw_startup(si);\r
+       err = irda_hw_startup();\r
        if (err) {              \r
                printk("line %d: %s irda_hw_startup err\n", __LINE__, __func__);\r
                goto err_startup;\r
@@ -378,7 +378,7 @@ static int rk29_irda_start(struct net_device *dev)
 \r
 err_irlap:\r
        si->open = 0;\r
-       irda_hw_shutdown(si);\r
+       irda_hw_shutdown();\r
        if (si->pdata->irda_pwr_ctl)\r
                si->pdata->irda_pwr_ctl(0);\r
 err_startup:\r
@@ -394,7 +394,7 @@ static int rk29_irda_stop(struct net_device *dev)
        RK29IR_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);\r
 \r
        disable_irq(dev->irq);\r
-       irda_hw_shutdown(si);\r
+       irda_hw_shutdown();\r
 \r
        /*\r
         * If we have been doing DMA receive, make sure we\r
@@ -637,8 +637,6 @@ static int rk29_irda_probe(struct platform_device *pdev)
         * Initially enable HP-SIR modulation, and ensure that the port\r
         * is disabled.\r
         */\r
-    irda_hw_init(si);\r
-\r
        err = register_netdev(dev);\r
        if (err) {      \r
                printk("line %d: rk29_ir register_netdev failed\n", __LINE__);\r
@@ -653,7 +651,6 @@ static int rk29_irda_probe(struct platform_device *pdev)
        return 0;\r
        \r
 err_register:\r
-       irda_hw_deinit(si);\r
        kfree(si->tx_buff.head);\r
 err_mem_3:\r
        kfree(si->rx_buff.head);\r
@@ -675,7 +672,6 @@ static int rk29_irda_remove(struct platform_device *pdev)
                kfree(si->tx_buff.head);\r
                kfree(si->rx_buff.head);\r
                free_netdev(dev);\r
-        irda_hw_deinit(si);\r
        }\r
 \r
        return 0;\r
@@ -700,7 +696,7 @@ static int rk29_irda_suspend(struct platform_device *pdev, pm_message_t state)
                 */\r
                netif_device_detach(dev);\r
                disable_irq(dev->irq);\r
-               irda_hw_shutdown(si);\r
+               irda_hw_shutdown();\r
                if (si->pdata->irda_pwr_ctl)\r
                        si->pdata->irda_pwr_ctl(0);\r
        }\r
@@ -737,7 +733,7 @@ static int rk29_irda_resume(struct platform_device *pdev)
                        si->newspeed = 0;\r
                }\r
                \r
-               irda_hw_startup(si);\r
+               irda_hw_startup();\r
                enable_irq(dev->irq);\r
 \r
                /*\r
index ba4380fec5b06bda8a17701d746459f130c760a4..beb3e7bc840c60ace8f49fd8939bac6b85c1ad6a 100755 (executable)
@@ -35,18 +35,5 @@ struct rk29_irda {
        iobuff_t                tx_buff;\r
        iobuff_t                rx_buff;\r
 };\r
-extern void irda_hw_init(struct rk29_irda *si);\r
-extern int irda_hw_get_mode(void);\r
-extern void irda_hw_deinit(struct rk29_irda *si);\r
-extern int irda_hw_startup(struct rk29_irda *si);\r
-extern int irda_hw_shutdown(struct rk29_irda *si);\r
-extern int irda_hw_set_speed(u32 speed);\r
-extern int irda_hw_tx_enable_irq(enum eTrans_Mode mode);\r
-extern int irda_hw_tx_enable(int len);\r
-extern int irda_hw_get_irqsrc(void);\r
-extern int irda_hw_get_data16(char* data8);\r
-extern void irda_hw_set_moderx(void);\r
-extern int irda_hw_get_mode(void);\r
-\r
 \r
 #endif //__DRIVERS_NET_IRDA_RK29_IR_H\r