# CONFIG_NET_PKTGEN is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
-# CONFIG_IRDA is not set
+CONFIG_IRDA=y
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=y
+CONFIG_IRNET=y
+# CONFIG_IRCOMM is not set
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+# CONFIG_IRDA_CACHE_LAST_LSAP is not set
+# CONFIG_IRDA_FAST_RR is not set
+CONFIG_IRDA_DEBUG=y
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+# CONFIG_IRTTY_SIR is not set
+
+#
+# Dongle support
+#
+# CONFIG_KINGSUN_DONGLE is not set
+# CONFIG_KSDAZZLE_DONGLE is not set
+# CONFIG_KS959_DONGLE is not set
+
+#
+# FIR device drivers
+#
+# CONFIG_USB_IRDA is not set
+# CONFIG_SIGMATEL_FIR is not set
+# CONFIG_MCS_FIR is not set
+CONFIG_RK_IRDA=y
+CONFIG_BU92725GUW=y
CONFIG_BT=y
CONFIG_BT_L2CAP=y
CONFIG_BT_SCO=y
#
# CONFIG_CMMB is not set
# CONFIG_TEST_CODE is not set
+CONFIG_RK29_SMC=y
#
# File systems
#include <mach/sram.h>
#include <mach/ddr.h>
#include <mach/cpufreq.h>
+#include <mach/rk29_smc.h>
#include <linux/regulator/rk29-pwm-regulator.h>
#include <linux/regulator/machine.h>
#endif
+#if defined(CONFIG_RK_IRDA) || defined(CONFIG_BU92747GUW_CIR)
+#define BU92747GUW_RESET_PIN RK29_PIN3_PD4// INVALID_GPIO //
+#define BU92747GUW_RESET_MUX_NAME GPIO3D4_HOSTWRN_NAME//NULL //
+#define BU92747GUW_RESET_MUX_MODE GPIO3H_GPIO3D4//NULL //
+
+#define BU92747GUW_PWDN_PIN RK29_PIN3_PD3//RK29_PIN5_PA7 //
+#define BU92747GUW_PWDN_MUX_NAME GPIO3D3_HOSTRDN_NAME//GPIO5A7_HSADCDATA2_NAME //
+#define BU92747GUW_PWDN_MUX_MODE GPIO3H_GPIO3D3//GPIO5L_GPIO5A7 //
+
+static int bu92747guw_io_init(void)
+{
+ int ret;
+
+ //reset pin
+ if(BU92747GUW_RESET_MUX_NAME != NULL)
+ {
+ rk29_mux_api_set(BU92747GUW_RESET_MUX_NAME, BU92747GUW_RESET_MUX_MODE);
+ }
+ ret = gpio_request(BU92747GUW_RESET_PIN, NULL);
+ if(ret != 0)
+ {
+ gpio_free(BU92747GUW_RESET_PIN);
+ printk(">>>>>> BU92747GUW_RESET_PIN gpio_request err \n ");
+ }
+ gpio_direction_output(BU92747GUW_RESET_PIN, GPIO_HIGH);
+
+ //power down pin
+ if(BU92747GUW_PWDN_MUX_NAME != NULL)
+ {
+ rk29_mux_api_set(BU92747GUW_PWDN_MUX_NAME, BU92747GUW_PWDN_MUX_MODE);
+ }
+ ret = gpio_request(BU92747GUW_PWDN_PIN, NULL);
+ if(ret != 0)
+ {
+ gpio_free(BU92747GUW_PWDN_PIN);
+ printk(">>>>>> BU92747GUW_PWDN_PIN gpio_request err \n ");
+ }
+
+ //power down as default
+ gpio_direction_output(BU92747GUW_PWDN_PIN, GPIO_LOW);
+
+ return 0;
+}
+
+
+static int bu92747guw_io_deinit(void)
+{
+ gpio_free(BU92747GUW_PWDN_PIN);
+ gpio_free(BU92747GUW_RESET_PIN);
+ return 0;
+}
+
+//power ctl func is share with irda and remote
+static int nPowerOnCount = 0;
+static DEFINE_MUTEX(bu92747_power_mutex);
+
+//1---power on; 0---power off
+static int bu92747guw_power_ctl(int enable)
+{
+ printk("%s \n",__FUNCTION__);
+
+ mutex_lock(&bu92747_power_mutex);
+ if (enable) {
+ nPowerOnCount++;
+ if (nPowerOnCount == 1) {//power on first
+ //smc0_init(NULL);
+ gpio_set_value(BU92747GUW_PWDN_PIN, GPIO_HIGH);
+ gpio_set_value(BU92747GUW_RESET_PIN, GPIO_LOW);
+ mdelay(5);
+ gpio_set_value(BU92747GUW_RESET_PIN, GPIO_HIGH);
+ mdelay(5);
+ }
+ }
+ else {
+ nPowerOnCount--;
+ if (nPowerOnCount == 0) {//power down final
+ //smc0_exit();
+ gpio_set_value(BU92747GUW_PWDN_PIN, GPIO_LOW);
+ }
+ }
+ mutex_unlock(&bu92747_power_mutex);
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_RK_IRDA
+#define IRDA_IRQ_PIN RK29_PIN5_PB2
+#define IRDA_IRQ_MUX_NAME GPIO5B2_HSADCDATA5_NAME
+#define IRDA_IRQ_MUX_MODE GPIO5L_GPIO5B2
+
+int irda_iomux_init(void)
+{
+ int ret = 0;
+
+ //irda irq pin
+ if(IRDA_IRQ_MUX_NAME != NULL)
+ {
+ rk29_mux_api_set(IRDA_IRQ_MUX_NAME, IRDA_IRQ_MUX_MODE);
+ }
+ ret = gpio_request(IRDA_IRQ_PIN, NULL);
+ if(ret != 0)
+ {
+ gpio_free(IRDA_IRQ_PIN);
+ printk(">>>>>> IRDA_IRQ_PIN gpio_request err \n ");
+ }
+ gpio_pull_updown(IRDA_IRQ_PIN, GPIO_HIGH);
+ gpio_direction_input(IRDA_IRQ_PIN);
+
+ return 0;
+}
+
+int irda_iomux_deinit(void)
+{
+ gpio_free(IRDA_IRQ_PIN);
+ return 0;
+}
+
+static struct irda_info rk29_irda_info = {
+ .intr_pin = IRDA_IRQ_PIN,
+ .iomux_init = irda_iomux_init,
+ .iomux_deinit = irda_iomux_deinit,
+ .irda_pwr_ctl = bu92747guw_power_ctl,
+};
+
+static struct platform_device irda_device = {
+ .name = "rk_irda",
+ .id = -1,
+ .dev = {
+ .platform_data = &rk29_irda_info,
+ }
+};
+#endif
+
+
static struct android_pmem_platform_data android_pmem_pdata = {
.name = "pmem",
.start = PMEM_UI_BASE,
#ifdef CONFIG_RK29_NEWTON
&rk29_device_newton,
#endif
+#ifdef CONFIG_RK_IRDA
+ &irda_device,
+#endif
};
/*****************************************************************************************
#endif
board_usb_detect_init(RK29_PIN0_PA0);
+
+#if defined(CONFIG_RK_IRDA) || defined(CONFIG_BU92747GUW_CIR)
+ smc0_init(NULL);
+ bu92747guw_io_init();
+#endif
+
}
static void __init machine_rk29_fixup(struct machine_desc *desc, struct tag *tags,
#include <linux/timer.h>
#include <linux/notifier.h>
+struct irda_info{
+ u32 intr_pin;
+ int (*iomux_init)(void);
+ int (*iomux_deinit)(void);
+ int (*irda_pwr_ctl)(int en);
+};
+
struct rk29_button_light_info{
u32 led_on_pin;
u32 led_on_level;
--- /dev/null
+\r
+#ifndef __DRIVER_IRDA_SMC_H\r
+#define __DRIVER_IRDA_SMC_H\r
+\r
+extern int smc0_init(u8 **base_addr);\r
+extern void smc0_exit(void);\r
+extern int smc0_write(u32 addr, u32 data);\r
+extern int smc0_read(u32 addr);\r
+extern int smc0_enable(int enable);\r
+#endif\r
+\r
source "drivers/testcode/Kconfig"
+source "drivers/smc/Kconfig"
endmenu
obj-y += ieee802154/
obj-$(CONFIG_CMMB) += cmmb/
obj-$(CONFIG_TEST_CODE) += testcode/
+obj-y += smc/
obj-y += dbg/
To compile it as a module, choose M here: the module will be called
mcs7780.
+config RK_IRDA
+ tristate "rockchip rk29 IrDA"
+ depends on IRDA && RK29_SMC
+ help
+ 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 module select"
+config BU92725GUW
+ bool "bu92725guw"
+endchoice
+
endmenu
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_BU92725GUW) += bu92725guw.o
# The SIR helper module
sir-dev-objs := sir_dev.o sir_dongle.o
--- /dev/null
+/***************************************************************************\r
+ *\r
+ * File: bu92725guw.c\r
+ *\r
+ * Description: functions of operating with bu92725guw board.\r
+ *\r
+ * Created: 2007/9\r
+ *\r
+ * Rev 1.1\r
+ *\r
+ *\r
+ * Confidential ROHM CO.,LTD.\r
+ *\r
+ ****************************************************************************/\r
+\r
+#include <linux/module.h>\r
+#include <linux/delay.h>\r
+#include <linux/errno.h>\r
+#include <linux/platform_device.h>\r
+#include <linux/fs.h>\r
+#include <linux/kernel.h>\r
+#include <linux/slab.h>\r
+#include <linux/mm.h>\r
+#include <linux/ioport.h>\r
+#include <linux/init.h>\r
+#include <linux/sched.h>\r
+#include <linux/pci.h>\r
+#include <linux/random.h>\r
+#include <linux/version.h>\r
+#include <linux/mutex.h>\r
+#include <linux/videodev2.h>\r
+#include <linux/dma-mapping.h>\r
+#include <linux/interrupt.h>\r
+#include <linux/kthread.h>\r
+#include <linux/highmem.h>\r
+#include <linux/freezer.h>\r
+\r
+#include "rk29_ir.h"\r
+\r
+#if 0\r
+#define RK29IR_DBG(x...) printk(x)\r
+#else\r
+#define RK29IR_DBG(x...)\r
+#endif\r
+\r
+\r
+ /*---------------------------------------------------------------------------\r
+ Data\r
+----------------------------------------------------------------------------*/\r
+/* record current setting\r
+*/\r
+static u32 curTrans_mode; /* SIR, MIR, FIR */\r
+static u32 curTrans_speed; /* 2.4kbps, 9.6kbps,..., 4Mbps */\r
+static u32 curTrans_way; /* idle, send, receive, auto-multi-receive, multi-receive, multi-send */\r
+static u16 curFIT; /* FIT2,1,0 in PWR/FIT register */\r
+\r
+/*---------------------------------------------------------------------------\r
+ Function Proto\r
+----------------------------------------------------------------------------*/\r
+static void internal_set(u8 modeChg);\r
+\r
+/*---------------------------------------------------------------------------\r
+ global Function Implement\r
+----------------------------------------------------------------------------*/\r
+/*\r
+ * Synopsis: board initialize\r
+ *\r
+ * Paras: none\r
+ *\r
+ * Return: none\r
+ */\r
+void irda_hw_init(struct rk29_irda *si)\r
+{\r
+ //smc0_init(&si->irda_base_addr);\r
+\r
+ //printk("%s [%d]\n",__FUNCTION__,__LINE__);\r
+}\r
+void irda_hw_deinit(struct rk29_irda *si)\r
+{\r
+ // smc0_init(&si->irda_base_addr);\r
+}\r
+\r
+int irda_hw_startup(struct rk29_irda *si)\r
+{\r
+ volatile u16 val;\r
+ int i=0;\r
+ RK29IR_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);\r
+\r
+ //IER (disable all)\r
+ BU92725GUW_WRITE_REG(REG_IER_ADDR, 0x0000);\r
+\r
+//MCR (use IrDA Controller func, 9.6kbps, SIR)\r
+ BU92725GUW_WRITE_REG(REG_MCR_ADDR, REG_MCR_9600 | REG_MCR_SIR);\r
+\r
+//PWR/FIT (default)\r
+ BU92725GUW_WRITE_REG(REG_PWR_FIT_ADDR, REG_PWR_FIT_MPW_3 | REG_PWR_FIT_FPW_2 | REG_PWR_FIT_FIT_0);\r
+\r
+//TRCR (idle, clr fifo, IrDA power on, mode select enable)\r
+ BU92725GUW_WRITE_REG(REG_TRCR_ADDR, REG_TRCR_FCLR | REG_TRCR_MS_EN);\r
+ val = BU92725GUW_READ_REG(REG_TRCR_ADDR);\r
+ while (val & REG_TRCR_MS_EN) {\r
+ val = BU92725GUW_READ_REG(REG_TRCR_ADDR);\r
+ }\r
+\r
+//FTLV\r
+ BU92725GUW_WRITE_REG(REG_FTLV_ADDR, 0x0000);\r
+\r
+// for(i=0; i<REG_WREC_ADDR;i=(i+2))//%REG_WREC_ADDR) //\r
+// printk("reg %d = 0x%x\n",i,BU92725GUW_READ_REG(i));\r
+\r
+ curTrans_mode = BU92725GUW_SIR;\r
+ curTrans_speed = 9600;\r
+ curTrans_way = BU92725GUW_IDLE;\r
+ curFIT = REG_PWR_FIT_FIT_0;\r
+ return 0;\r
+}\r
+\r
+int irda_hw_shutdown(struct rk29_irda *si)\r
+{\r
+ RK29IR_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);\r
+\r
+ //IER (diable all)\r
+ BU92725GUW_WRITE_REG(REG_IER_ADDR, 0x0000);\r
+\r
+//MCR (use IrDA Controller func, 9.6kbps, SIR)\r
+ BU92725GUW_WRITE_REG(REG_MCR_ADDR, REG_MCR_9600 | REG_MCR_SIR);\r
+\r
+//PWR/FIT (default)\r
+ BU92725GUW_WRITE_REG(REG_PWR_FIT_ADDR, REG_PWR_FIT_MPW_3 | REG_PWR_FIT_FPW_2 | REG_PWR_FIT_FIT_0);\r
+\r
+//TRCR (idle, clr fifo, IrDA power down)\r
+ BU92725GUW_WRITE_REG(REG_TRCR_ADDR, REG_TRCR_FCLR | REG_TRCR_IRPD);\r
+\r
+//FTLV\r
+ BU92725GUW_WRITE_REG(REG_FTLV_ADDR, 0x0000);\r
+\r
+ curTrans_mode = BU92725GUW_SIR;\r
+ curTrans_speed = 9600;\r
+ curTrans_way = BU92725GUW_IDLE;\r
+ curFIT = REG_PWR_FIT_FIT_0;\r
+\r
+ return 0;\r
+}\r
+\r
+/*\r
+ * Synopsis: set data transfer speed\r
+ *\r
+ * Paras: speed - speed value will be set; value is from enum eTrans_Speed\r
+ *\r
+ * Return: none\r
+ */\r
+int irda_hw_set_speed(u32 speed)\r
+{\r
+ u32 mode;\r
+ u8 modeChg = 0;\r
+\r
+ /* do nothing if speed is same as current */\r
+ RK29IR_DBG("line %d: enter %s, speed=%d\n", __LINE__, __FUNCTION__, speed);\r
+\r
+ if (speed == curTrans_speed)\r
+ return 0;\r
+\r
+ /* mode */\r
+ switch (speed) {\r
+ case 2400:\r
+ case 9600:\r
+ case 19200:\r
+ case 38400:\r
+ case 57600:\r
+ case 115200:\r
+ mode = BU92725GUW_SIR;\r
+ break;\r
+ case 576000:\r
+ case 1152000:\r
+ mode = BU92725GUW_MIR;\r
+ break;\r
+ case 4000000:\r
+ mode = BU92725GUW_FIR;\r
+ break;\r
+ default:\r
+ return -1; //invalid\r
+ }\r
+\r
+ /* speed */\r
+ curTrans_speed = speed;\r
+\r
+ /* change trans way if needed */\r
+ switch (curTrans_way) {\r
+ case BU92725GUW_IDLE:\r
+ break;\r
+ case BU92725GUW_REV:\r
+ if (mode != BU92725GUW_SIR)\r
+ curTrans_way = BU92725GUW_AUTO_MULTI_REV;\r
+ //curTrans_way = BU92725GUW_MULTI_REV;\r
+ break;\r
+ case BU92725GUW_SEND:\r
+ if (mode != BU92725GUW_SIR)\r
+ curTrans_way = BU92725GUW_MULTI_SEND;\r
+ break;\r
+ case BU92725GUW_AUTO_MULTI_REV:\r
+ if (mode == BU92725GUW_SIR)\r
+ curTrans_way = BU92725GUW_REV;\r
+ break;\r
+ case BU92725GUW_MULTI_REV: //not used now\r
+ if (mode == BU92725GUW_SIR)\r
+ curTrans_way = BU92725GUW_REV;\r
+ break;\r
+ case BU92725GUW_MULTI_SEND:\r
+ if (mode == BU92725GUW_SIR)\r
+ curTrans_way = BU92725GUW_SEND;\r
+ break;\r
+ }\r
+\r
+ if (mode != curTrans_mode) {\r
+ if ((mode == BU92725GUW_FIR) || (curTrans_mode == BU92725GUW_FIR))\r
+ modeChg = 1; /* need set TRCR5:MS_EN */\r
+ }\r
+\r
+ curTrans_mode = mode;\r
+\r
+ /* set bu92725guw registers */\r
+ //internal_set(modeChg);\r
+ internal_set(1);\r
+\r
+ return 0;\r
+}\r
+\r
+int irda_hw_tx_enable_irq(enum eTrans_Mode mode)\r
+{\r
+\r
+ RK29IR_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);\r
+ /* hardware-specific code\r
+ */\r
+ if (mode == BU92725GUW_SIR)\r
+ BU92725GUW_set_trans_way(BU92725GUW_SEND);\r
+ else\r
+ BU92725GUW_set_trans_way(BU92725GUW_MULTI_SEND);\r
+\r
+ //BU92725GUW_clr_fifo();\r
+\r
+ return 0;\r
+}\r
+\r
+int irda_hw_tx_enable(int len)\r
+{\r
+ RK29IR_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);\r
+ BU92725GUW_WRITE_REG(REG_FTLV_ADDR, len);\r
+ BU92725GUW_WRITE_REG(REG_TRCR_ADDR, REG_TRCR_TX_EN);\r
+ return 0;\r
+}\r
+\r
+int irda_hw_get_irqsrc(void)\r
+{\r
+ RK29IR_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);\r
+ return BU92725GUW_READ_REG(REG_EIR_ADDR);\r
+}\r
+\r
+int irda_hw_get_data16(char* data8)\r
+{\r
+ u16 data16 = 0;\r
+ int len = 0;\r
+\r
+ RK29IR_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);\r
+\r
+ len = BU92725GUW_READ_REG(REG_FLV_ADDR);\r
+ if(len > 0)\r
+ {\r
+ /* read data from RXD */\r
+ data16 = BU92725GUW_READ_REG(REG_RXD_ADDR);\r
+ data8[0] = (u8)data16;\r
+ data8[1] = (u8)(data16 >> 8);\r
+ return 2;\r
+ } else {\r
+ return 0;\r
+ }\r
+}\r
+\r
+void irda_hw_set_moderx(void)\r
+{\r
+ // frData.ucFlags &= ~(FRMF_TX_ACTIVE);\r
+ // frData.ucFlags |= FRMF_RX_ACTIVE;\r
+\r
+ int i=0;\r
+ /* hardware-specific code\r
+ */\r
+ RK29IR_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);\r
+ \r
+ //BU92725GUW_clr_fifo();\r
+\r
+ if (curTrans_mode == BU92725GUW_SIR)\r
+ BU92725GUW_set_trans_way(BU92725GUW_REV);\r
+ else\r
+ BU92725GUW_set_trans_way(BU92725GUW_AUTO_MULTI_REV);\r
+ //BU92725GUW_set_trans_way(BU92725GUW_MULTI_REV);\r
+}\r
+\r
+int irda_hw_get_mode(void)\r
+{\r
+ return curTrans_way;\r
+ \r
+ u16 val = 0;\r
+ val = BU92725GUW_READ_REG(REG_TRCR_ADDR);\r
+ RK29IR_DBG("line %d: enter %s, REG_TRCR_ADDR = 0x%x\n", __LINE__, __FUNCTION__, val);\r
+\r
+ return (val& (REG_TRCR_TX_EN | REG_TRCR_RX_EN));\r
+}\r
+\r
+/*\r
+ * Synopsis: set data transfer way\r
+ *\r
+ * Paras: way - transfer way will be set; value is from enum eThrans_Way\r
+ *\r
+ * Return: none\r
+ */\r
+void BU92725GUW_set_trans_way(u32 way)\r
+{\r
+ RK29IR_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);\r
+ if (way == curTrans_way)\r
+ return;\r
+\r
+ curTrans_way = way;\r
+\r
+ /* set bu92725guw registers */\r
+ internal_set(1);\r
+}\r
+\r
+/*\r
+ * Synopsis: clear fifo\r
+ *\r
+ * Paras: none\r
+ *\r
+ * Return: none\r
+ */\r
+void BU92725GUW_clr_fifo(void)\r
+{\r
+ volatile u16 val;\r
+\r
+ RK29IR_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);\r
+ /* set TRCR4:FCLR */\r
+ val = BU92725GUW_READ_REG(REG_TRCR_ADDR);\r
+ val &= 0xff8f;\r
+ val |= REG_TRCR_FCLR;\r
+ BU92725GUW_WRITE_REG(REG_TRCR_ADDR, val);\r
+\r
+ /* wait op complete */\r
+ val = BU92725GUW_READ_REG(REG_TRCR_ADDR);\r
+ while (val & REG_TRCR_FCLR)\r
+ val = BU92725GUW_READ_REG(REG_TRCR_ADDR);\r
+}\r
+\r
+/*\r
+ * Synopsis: read frame data from fifo\r
+ *\r
+ * Paras: buf - point to buffer for storing frame data\r
+ *\r
+ * Return: number of data got from fifo (in byte)\r
+ */\r
+u16 BU92725GUW_get_data(u8 *buf)\r
+{\r
+ volatile u16 data;\r
+ u16 len, count, i;\r
+\r
+ RK29IR_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);\r
+\r
+ /* get data count from FLV or FLVII */\r
+ if (curTrans_way == BU92725GUW_REV)\r
+ len = BU92725GUW_READ_REG(REG_FLV_ADDR);\r
+ else\r
+ len = BU92725GUW_READ_REG(REG_FLVII_ADDR);\r
+\r
+ count = (len % 2)? (len / 2 + 1) : (len / 2);\r
+\r
+ /* read data from RXD */\r
+ for (i=0; i<count; i++) {\r
+ data = BU92725GUW_READ_REG(REG_RXD_ADDR);\r
+ buf[i * 2] = (u8)data;\r
+ buf[i * 2 + 1] = (u8)(data >> 8);\r
+ }\r
+\r
+ /* restart receive mode under SIR */\r
+ if (curTrans_way == BU92725GUW_REV) {\r
+ BU92725GUW_WRITE_REG(REG_TRCR_ADDR, 0x0000);\r
+ BU92725GUW_WRITE_REG(REG_TRCR_ADDR, REG_TRCR_RX_EN);\r
+ }\r
+\r
+ return len;\r
+}\r
+\r
+/*\r
+ * Synopsis: write data from buffer1 and buffer2 into fifo\r
+ *\r
+ * Paras: buf1 - point to buffer 1\r
+ * len1 - length of data to write into fifo from buffer 1\r
+ * buf2 - point to buffer 2\r
+ * len2 - length of data to write into fifo from buffer 2\r
+ *\r
+ * Return: none\r
+ */\r
+ void BU92725GUW_send_data(u8 *buf1, u16 len1, u8 *buf2, u16 len2)\r
+{/* buf2,len2 will be used by framer under MIR/FIR mode */\r
+ u16 data, len, pos;\r
+ u8 *ptr;\r
+\r
+ len = len1 + len2;\r
+ pos = 0;\r
+ ptr = (u8 *)(&data);\r
+\r
+ RK29IR_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);\r
+\r
+ if (len == 0)\r
+ return;\r
+ \r
+ /* set FTLV */\r
+ BU92725GUW_WRITE_REG(REG_FTLV_ADDR, len);\r
+\r
+ /* set TRCR:TX_EN under normal send mode */\r
+ if (curTrans_way == BU92725GUW_SEND) {//SIR\r
+ BU92725GUW_WRITE_REG(REG_TRCR_ADDR, REG_TRCR_TX_EN);\r
+ }\r
+\r
+\r
+ /* set TXD */\r
+ while (pos < len) {\r
+\r
+ *ptr++ = (pos < len1)? buf1[pos] : buf2[pos-len1];\r
+\r
+ pos++;\r
+\r
+ if (pos < len) {\r
+ *ptr-- = (pos < len1)? buf1[pos] : buf2[pos-len1];\r
+ } else\r
+ *ptr-- = 0x00;\r
+\r
+ pos++;\r
+\r
+ BU92725GUW_WRITE_REG(REG_TXD_ADDR, data);\r
+ }\r
+}\r
+\r
+/*\r
+ * Synopsis: set frame sending interval under multi-window send mode\r
+ *\r
+ * Paras: us - interval time value to set\r
+ *\r
+ * Return: none\r
+ */\r
+void BU92725GUW_set_frame_interval(u32 us)\r
+{\r
+ volatile u16 val;\r
+\r
+ RK29IR_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);\r
+ /* set PWR/FIT */\r
+\r
+ val = BU92725GUW_READ_REG(REG_PWR_FIT_ADDR);\r
+ //val &= 0xf8ff;\r
+ val &= 0xf0ff;\r
+ \r
+ if (us <= 100)\r
+ val |= REG_PWR_FIT_FIT_0;\r
+ else if (us <= 200)\r
+ val |= REG_PWR_FIT_FIT_1;\r
+ else if (us <= 300)\r
+ val |= REG_PWR_FIT_FIT_2;\r
+ else if (us <= 400)\r
+ val |= REG_PWR_FIT_FIT_3;\r
+ else if (us <= 500)\r
+ val |= REG_PWR_FIT_FIT_4;\r
+ else if (us <= 600)\r
+ val |= REG_PWR_FIT_FIT_5;\r
+ else if (us <= 800)\r
+ val |= REG_PWR_FIT_FIT_6;\r
+ else if (us <= 1000)\r
+ val |= REG_PWR_FIT_FIT_7;\r
+ else if (us <= 1200)\r
+ val |= REG_PWR_FIT_FIT_8;\r
+ else if (us <= 1400)\r
+ val |= REG_PWR_FIT_FIT_9;\r
+ else if (us <= 1600)\r
+ val |= REG_PWR_FIT_FIT_A;\r
+ else if (us <= 1800)\r
+ val |= REG_PWR_FIT_FIT_B;\r
+ else if (us <= 2000)\r
+ val |= REG_PWR_FIT_FIT_C;\r
+ else if (us <= 2200)\r
+ val |= REG_PWR_FIT_FIT_D;\r
+ else if (us <= 2400)\r
+ val |= REG_PWR_FIT_FIT_E;\r
+ else\r
+ val |= REG_PWR_FIT_FIT_F;\r
+\r
+ BU92725GUW_WRITE_REG(REG_PWR_FIT_ADDR, val);\r
+\r
+ //curFIT = val & 0x0700;\r
+ curFIT = val & 0x0F00;\r
+}\r
+\r
+/*\r
+ * Synopsis: return current transfer mode (SIR/MIR/FIR)\r
+ *\r
+ * Paras: none\r
+ *\r
+ * Return: current transfer mode\r
+ */\r
+u32 BU92725GUW_get_trans_mode(void)\r
+{\r
+ RK29IR_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);\r
+ return curTrans_mode;\r
+}\r
+\r
+/*\r
+ * Synopsis: add a IrDA pulse following frame\r
+ *\r
+ * Paras: none\r
+ *\r
+ * Return: none\r
+ */\r
+void BU92725GUW_add_pulse(void)\r
+{\r
+ RK29IR_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);\r
+ /* valid only under M/FIR send mode */\r
+ if (curTrans_way != BU92725GUW_MULTI_SEND)\r
+ return;\r
+\r
+ /* set TRCR3:IR_PLS */\r
+ BU92725GUW_WRITE_REG(REG_TRCR_ADDR, REG_TRCR_IR_PLS | REG_TRCR_TX_CON);\r
+}\r
+\r
+/*\r
+ * Synopsis: soft reset bu92725guw board; will be called after some error happened\r
+ *\r
+ * Paras: none\r
+ *\r
+ * Return: none\r
+ */\r
+void BU92725GUW_reset(void)\r
+{\r
+ RK29IR_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);\r
+ /* set bu925725guw registers */\r
+ internal_set(1);\r
+}\r
+\r
+/*---------------------------------------------------------------------------\r
+ local Function Implement\r
+----------------------------------------------------------------------------*/\r
+/*\r
+ * Synopsis: set bu92725guw internal registers\r
+ *\r
+ * Paras: modeChg - need set TRCR5:MS_EN or not\r
+ *\r
+ * Return: none\r
+ */\r
+static void internal_set(u8 modeChg)\r
+{\r
+ volatile u16 val;\r
+\r
+ RK29IR_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);\r
+ /* disable INT */\r
+ BU92725GUW_WRITE_REG(REG_IER_ADDR, 0x0000);\r
+ val = BU92725GUW_READ_REG(REG_EIR_ADDR);\r
+\r
+ /* MCR */\r
+ val = 0;\r
+ switch (curTrans_mode) {\r
+ case BU92725GUW_SIR: //00\r
+ val |= REG_MCR_SIR;\r
+ break;\r
+ case BU92725GUW_MIR: //01\r
+ val |= REG_MCR_MIR;\r
+ break;\r
+ case BU92725GUW_FIR: //10\r
+ val |= REG_MCR_FIR;\r
+ break;\r
+ }\r
+ switch (curTrans_speed) {\r
+ case 2400: //000\r
+ val |= REG_MCR_2400;\r
+ break;\r
+ case 9600: //010\r
+ val |= REG_MCR_9600;\r
+ break;\r
+ case 19200: //011\r
+ val |= REG_MCR_19200;\r
+ break;\r
+ case 38400: //100\r
+ val |= REG_MCR_38400;\r
+ break;\r
+ case 57600: //101\r
+ val |= REG_MCR_57600;\r
+ break;\r
+ case 115200: //110\r
+ val |= REG_MCR_115200;\r
+ break;\r
+ case 576000: //001\r
+ val |= REG_MCR_576K;\r
+ break;\r
+ case 1152000: //010\r
+ val |= REG_MCR_1152K;\r
+ break;\r
+ case 4000000: //010\r
+ val |= REG_MCR_4M;\r
+ break;\r
+ }\r
+ BU92725GUW_WRITE_REG(REG_MCR_ADDR, val);\r
+ RK29IR_DBG("REG_MCR_ADDR: 0x%x\n", val);\r
+\r
+ /* PWR / FIT */\r
+ switch (curTrans_mode) {\r
+ case BU92725GUW_SIR:\r
+ val = 0x0000;\r
+ break;\r
+ case BU92725GUW_MIR:\r
+ val = REG_PWR_FIT_MPW_3 | curFIT;\r
+ break;\r
+ case BU92725GUW_FIR:\r
+ val = REG_PWR_FIT_FPW_2 | curFIT;\r
+ break;\r
+ }\r
+ BU92725GUW_WRITE_REG(REG_PWR_FIT_ADDR, val);\r
+ RK29IR_DBG("REG_PWR_FIT_ADDR: 0x%x\n", val);\r
+\r
+ /* TRCR:MS_EN */\r
+ if (modeChg) {\r
+ BU92725GUW_WRITE_REG(REG_TRCR_ADDR, REG_TRCR_MS_EN);\r
+ val = BU92725GUW_READ_REG(REG_TRCR_ADDR);\r
+ while (val & REG_TRCR_MS_EN) {\r
+ val = BU92725GUW_READ_REG(REG_TRCR_ADDR);\r
+ }\r
+ }\r
+\r
+ /* TRCR */\r
+ switch (curTrans_way) {\r
+ case BU92725GUW_IDLE:\r
+ val = 0x0000;\r
+ break;\r
+ case BU92725GUW_REV:\r
+ val = REG_TRCR_RX_EN;\r
+ break;\r
+ case BU92725GUW_SEND:\r
+ val = 0x0000;\r
+ break;\r
+ case BU92725GUW_AUTO_MULTI_REV:\r
+ val = REG_TRCR_RX_EN | REG_TRCR_AUTO_FLV_CP;\r
+ break;\r
+ case BU92725GUW_MULTI_REV: //not used\r
+ val = REG_TRCR_RX_EN | REG_TRCR_RX_CON;\r
+ break;\r
+ case BU92725GUW_MULTI_SEND:\r
+ val = REG_TRCR_TX_CON;\r
+ break;\r
+ }\r
+ BU92725GUW_WRITE_REG(REG_TRCR_ADDR, val);\r
+ RK29IR_DBG("REG_TRCR_ADDR: 0x%x\n", val);\r
+\r
+ /* IER */\r
+ switch (curTrans_way) {\r
+ case BU92725GUW_IDLE:\r
+ val = 0x0000;\r
+ break;\r
+\r
+ case BU92725GUW_REV: /* SIR use */\r
+ val = REG_INT_EOFRX | REG_INT_TO | REG_INT_OE | REG_INT_FE; //IER1, 2, 5, 7\r
+ break;\r
+\r
+ case BU92725GUW_SEND: /* SIR use */\r
+ val = REG_INT_TXE; //IER3\r
+ break;\r
+\r
+ case BU92725GUW_MULTI_REV: /* not used */\r
+ val = REG_INT_STFRX | REG_INT_TO | REG_INT_CRC | REG_INT_OE | REG_INT_EOF | REG_INT_AC | REG_INT_DECE | \r
+ REG_INT_RDOE | REG_INT_DEX | REG_INT_RDUE; //IER1,2, 4, 5, 6, 7, 8, 9, 10\r
+ break;\r
+\r
+ case BU92725GUW_AUTO_MULTI_REV: /* M/FIR use */\r
+ val = REG_INT_TO | REG_INT_CRC | REG_INT_OE | REG_INT_EOF | REG_INT_AC | REG_INT_DECE | \r
+ REG_INT_RDOE | REG_INT_DEX | REG_INT_RDE; //IER2, 4, 5, 6, 7, 8, 9, 12\r
+ break;\r
+\r
+ case BU92725GUW_MULTI_SEND: /* M/FIR use */\r
+ val = REG_INT_TO | REG_INT_TXE | REG_INT_WRE; //IER2, 3, 11\r
+ break;\r
+ }\r
+ BU92725GUW_WRITE_REG(REG_IER_ADDR, val);\r
+ RK29IR_DBG("REG_IER_ADDR: 0x%x\n", val);\r
+}\r
+\r
+\r
+\r
--- /dev/null
+/***************************************************************************\r
+ *\r
+ * File: bu92725guw.h\r
+ *\r
+ * Description: This file contains configuration constants for the\r
+ * bu92725guw board.\r
+ *\r
+ * Created: 2007/9\r
+ *\r
+ * Rev 1.1\r
+ *\r
+ *\r
+ * Confidential ROHM CO.,LTD.\r
+ *\r
+ ****************************************************************************/\r
+#ifndef __BU92725GUW_H\r
+#define __BU92725GUW_H\r
+\r
+#include "mach/rk29_smc.h"\r
+\r
+\r
+/* irda registers addr must be 2*ori_register when use smc control*/\r
+#define REG_TXD_ADDR 0\r
+#define REG_RXD_ADDR 0\r
+#define REG_IER_ADDR 2\r
+#define REG_EIR_ADDR 4\r
+#define REG_MCR_ADDR 6\r
+#define REG_PWR_FIT_ADDR 8\r
+#define REG_TRCR_ADDR 10\r
+#define REG_FTLV_ADDR 12\r
+#define REG_FLV_ADDR 14\r
+#define REG_FLVII_ADDR 16\r
+#define REG_FLVIII_ADDR 18\r
+#define REG_FLVIV_ADDR 20\r
+#define REG_TRCRII_ADDR 22\r
+#define REG_TXEC_ADDR 24\r
+#define REG_WREC_ADDR 26\r
+\r
+/*\r
+ *register bits definition (registers are all 16 bits)\r
+ */\r
+//interrupt reg (IER and EIR)\r
+#define REG_INT_DRX (0x0001 << 0)\r
+#define REG_INT_EOFRX (0x0001 << 1)\r
+#define REG_INT_STFRX (0x0001 << 1)\r
+#define REG_INT_TO (0x0001 << 2)\r
+#define REG_INT_TXE (0x0001 << 3)\r
+#define REG_INT_CRC (0x0001 << 4)\r
+#define REG_INT_OE (0x0001 << 5)\r
+#define REG_INT_EOF (0x0001 << 6)\r
+#define REG_INT_FE (0x0001 << 7)\r
+#define REG_INT_AC (0x0001 << 7)\r
+#define REG_INT_DECE (0x0001 << 7)\r
+#define REG_INT_RDOE (0x0001 << 8)\r
+#define REG_INT_DEX (0x0001 << 9)\r
+#define REG_INT_RDUE (0x0001 << 10)\r
+#define REG_INT_WRE (0x0001 << 11)\r
+#define REG_INT_RDE (0x0001 << 12)\r
+\r
+//MCR\r
+#define REG_MCR_CTLA 0x1000\r
+#define REG_MCR_RC_MODE 0x0800\r
+#define REG_MCR_RC_EN 0x0400\r
+#define REG_MCR_2400 (0x0000 << 5)\r
+#define REG_MCR_9600 (0x0002 << 5) //default\r
+#define REG_MCR_19200 (0x0003 << 5)\r
+#define REG_MCR_38400 (0x0004 << 5)\r
+#define REG_MCR_57600 (0x0005 << 5)\r
+#define REG_MCR_115200 (0x0006 << 5)\r
+#define REG_MCR_576K (0x0001 << 5)\r
+#define REG_MCR_1152K (0x0002 << 5)\r
+#define REG_MCR_4M (0x0002 << 5)\r
+#define REG_MCR_SIR 0x0000 //default\r
+#define REG_MCR_MIR 0x0001\r
+#define REG_MCR_FIR 0x0002\r
+\r
+\r
+/* flag event bit\r
+ */\r
+#define FRM_EVT_RX_EOFRX REG_INT_EOFRX //IER1\r
+#define FRM_EVT_RX_RDE REG_INT_RDE //IER12\r
+#define FRM_EVT_TX_TXE REG_INT_TXE //IER3\r
+#define FRM_EVT_TX_WRE REG_INT_WRE //IER11\r
+#define FRM_EVT_EXIT_NOW 0x00010000\r
+\r
+\r
+enum eTrans_Mode {\r
+ BU92725GUW_SIR = 0,\r
+ BU92725GUW_MIR,\r
+ BU92725GUW_FIR,\r
+};\r
+enum eTrans_Speed {\r
+ BU92725GUW_2400 = 0,\r
+ BU92725GUW_9600,\r
+ BU92725GUW_19200,\r
+ BU92725GUW_38400,\r
+ BU92725GUW_57600,\r
+ BU92725GUW_115200,\r
+ BU92725GUW_576K,\r
+ BU92725GUW_1152K,\r
+ BU92725GUW_4M,\r
+};\r
+\r
+//PWR/FIT\r
+#define REG_PWR_FIT_SPW 0x0001\r
+#define REG_PWR_FIT_MPW_0 (0x0000 << 1)\r
+#define REG_PWR_FIT_MPW_1 (0x0001 << 1)\r
+#define REG_PWR_FIT_MPW_2 (0x0002 << 1)\r
+#define REG_PWR_FIT_MPW_3 (0x0003 << 1) //default\r
+#define REG_PWR_FIT_MPW_4 (0x0004 << 1)\r
+#define REG_PWR_FIT_MPW_5 (0x0005 << 1)\r
+#define REG_PWR_FIT_MPW_6 (0x0006 << 1)\r
+#define REG_PWR_FIT_MPW_7 (0x0007 << 1)\r
+#define REG_PWR_FIT_MPW_8 (0x0008 << 1)\r
+#define REG_PWR_FIT_MPW_9 (0x0009 << 1)\r
+#define REG_PWR_FIT_MPW_10 (0x000A << 1)\r
+#define REG_PWR_FIT_MPW_11 (0x000B << 1)\r
+#define REG_PWR_FIT_MPW_12 (0x000C << 1)\r
+#define REG_PWR_FIT_MPW_13 (0x000D << 1)\r
+#define REG_PWR_FIT_MPW_14 (0x000E << 1)\r
+#define REG_PWR_FIT_MPW_15 (0x000F << 1)\r
+#define REG_PWR_FIT_FPW_0 (0x0000 << 5)\r
+#define REG_PWR_FIT_FPW_1 (0x0001 << 5)\r
+#define REG_PWR_FIT_FPW_2 (0x0002 << 5) //default\r
+#define REG_PWR_FIT_FPW_3 (0x0003 << 5)\r
+#define REG_PWR_FIT_FIT_0 (0x0000 << 8) //default\r
+#define REG_PWR_FIT_FIT_1 (0x0001 << 8)\r
+#define REG_PWR_FIT_FIT_2 (0x0002 << 8)\r
+#define REG_PWR_FIT_FIT_3 (0x0003 << 8)\r
+#define REG_PWR_FIT_FIT_4 (0x0004 << 8)\r
+#define REG_PWR_FIT_FIT_5 (0x0005 << 8)\r
+#define REG_PWR_FIT_FIT_6 (0x0006 << 8)\r
+#define REG_PWR_FIT_FIT_7 (0x0007 << 8)\r
+#define REG_PWR_FIT_FIT_8 (0x0008 << 8) //default\r
+#define REG_PWR_FIT_FIT_9 (0x0009 << 8)\r
+#define REG_PWR_FIT_FIT_A (0x000A << 8)\r
+#define REG_PWR_FIT_FIT_B (0x000B << 8)\r
+#define REG_PWR_FIT_FIT_C (0x000C << 8)\r
+#define REG_PWR_FIT_FIT_D (0x000D << 8)\r
+#define REG_PWR_FIT_FIT_E (0x000E << 8)\r
+#define REG_PWR_FIT_FIT_F (0x000F << 8)\r
+\r
+//TRCR\r
+#define REG_TRCR_TX_EN 0x0001\r
+#define REG_TRCR_RX_EN (0x0001 << 1)\r
+#define REG_TRCR_S_EOT (0x0001 << 2)\r
+#define REG_TRCR_IR_PLS (0x0001 << 3)\r
+#define REG_TRCR_FCLR (0x0001 << 4)\r
+#define REG_TRCR_MS_EN (0x0001 << 5)\r
+#define REG_TRCR_IRPD (0x0001 << 6)\r
+#define REG_TRCR_M_STA (0x0001 << 7)\r
+#define REG_TRCR_RXPWD (0x0001 << 8)\r
+#define REG_TRCR_TXPWD (0x0001 << 9)\r
+#define REG_TRCR_ONE_BIT_R (0x0001 << 10)\r
+#define REG_TRCR_AUTO_FLV_CP (0x0001 << 11)\r
+#define REG_TRCR_RX_CON (0x0001 << 12)\r
+#define REG_TRCR_FLV_CP (0x0001 << 13)\r
+#define REG_TRCR_TX_CON (0x0001 << 14)\r
+#define REG_TRCR_TX_NUM (0x0001 << 15)\r
+\r
+enum eThrans_Way {\r
+ BU92725GUW_IDLE = 0,\r
+ BU92725GUW_REV, /* SIR use */\r
+ BU92725GUW_SEND, /* SIR use */\r
+ BU92725GUW_AUTO_MULTI_REV, /* M/FIR use */\r
+ BU92725GUW_MULTI_REV, /* not used */\r
+ BU92725GUW_MULTI_SEND, /* M/FIR use */\r
+};\r
+\r
+\r
+#define BU92725GUW_FIFO_SIZE (2560 * 2)\r
+\r
+#define BU92725GUW_MAX_FRM_INTERVAL 1000 /* 1000us */\r
+\r
+/*---------------------------------------------------------------------------\r
+ Functions used by framer\r
+----------------------------------------------------------------------------*/\r
+#define BU92725GUW_READ_REG(regAddr) smc0_read(regAddr)\r
+#define BU92725GUW_WRITE_REG(regAddr, data) smc0_write(regAddr, data)\r
+\r
+\r
+/* board initialize */\r
+extern void BU92725GUW_init(void);\r
+\r
+/* board deinit */\r
+extern void BU92725GUW_deinit(void);\r
+\r
+/* set data transfer speed */\r
+extern void BU92725GUW_set_trans_speed(u32 speed);\r
+\r
+/* set frame transfer way */\r
+extern void BU92725GUW_set_trans_way(u32 way);\r
+\r
+/* flush fifo */\r
+extern void BU92725GUW_clr_fifo(void);\r
+\r
+/* set frame sending interval */\r
+extern void BU92725GUW_set_frame_interval(u32 us);\r
+\r
+/* insert IrDA pulse follow frame sending */\r
+extern void BU92725GUW_add_pulse(void);\r
+\r
+/* soft reset when some error happened */\r
+extern void BU92725GUW_reset(void);\r
+\r
+/* return transfer mode */\r
+extern u32 BU92725GUW_get_trans_mode(void);\r
+\r
+/* get frame data from fifo */\r
+extern u16 BU92725GUW_get_data(u8 *buf);\r
+\r
+/* send frame data into fifo */\r
+extern void BU92725GUW_send_data(u8 *buf1, u16 len1, u8 *buf2, u16 len2);\r
+\r
+\r
+#endif /*__BU92725GUW_H*/\r
--- /dev/null
+/*\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the BSD Licence, GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2 of the\r
+ * License, or (at your option) any later version\r
+ */\r
+#include <linux/module.h>\r
+#include <linux/delay.h>\r
+#include <linux/errno.h>\r
+#include <linux/platform_device.h>\r
+#include <linux/fs.h>\r
+#include <linux/kernel.h>\r
+#include <linux/slab.h>\r
+#include <linux/mm.h>\r
+#include <linux/ioport.h>\r
+#include <linux/init.h>\r
+#include <linux/sched.h>\r
+#include <linux/pci.h>\r
+#include <linux/random.h>\r
+#include <linux/version.h>\r
+#include <linux/mutex.h>\r
+#include <linux/videodev2.h>\r
+#include <linux/dma-mapping.h>\r
+#include <linux/interrupt.h>\r
+#include <linux/kthread.h>\r
+#include <linux/highmem.h>\r
+#include <linux/freezer.h>\r
+#include <linux/netdevice.h>\r
+#include <linux/etherdevice.h>\r
+#include <linux/irq.h>\r
+#include <linux/wakelock.h>\r
+\r
+#include <mach/iomux.h>\r
+#include <mach/gpio.h>\r
+#include <mach/board.h>\r
+#include <mach/rk29_iomap.h>\r
+#include <mach/pmu.h>\r
+#include <mach/rk29-dma-pl330.h>\r
+\r
+#include "rk29_ir.h"\r
+\r
+#if 0\r
+#define RK29IR_DBG(x...) printk(x)\r
+#else\r
+#define RK29IR_DBG(x...)\r
+#endif\r
+\r
+#if 0\r
+#define RK29IR_DATA_DBG(x...) printk(x)\r
+#else\r
+#define RK29IR_DATA_DBG(x...)\r
+#endif\r
+\r
+#define IRDA_NAME "rk_irda"\r
+\r
+struct irda_driver {\r
+ struct irda_info *pin_info;\r
+ struct device *dev;\r
+};\r
+\r
+#define IS_FIR(si) ((si)->speed >= 4000000)\r
+static int max_rate = 115200;\r
+#define IRDA_FRAME_SIZE_LIMIT BU92725GUW_FIFO_SIZE\r
+\r
+#define RK29_MAX_RXLEN 2047\r
+\r
+static void rk29_irda_fir_test(struct work_struct *work);\r
+static DECLARE_DELAYED_WORK(dwork, rk29_irda_fir_test);\r
+\r
+\r
+/*\r
+ * Allocate and map the receive buffer, unless it is already allocated.\r
+ */\r
+static int rk29_irda_rx_alloc(struct rk29_irda *si)\r
+{\r
+ if (si->rxskb)\r
+ return 0;\r
+\r
+ si->rxskb = alloc_skb(RK29_MAX_RXLEN + 1, GFP_ATOMIC);\r
+\r
+ if (!si->rxskb) {\r
+ printk(KERN_ERR "rk29_ir: out of memory for RX SKB\n");\r
+ return -ENOMEM;\r
+ }\r
+\r
+ si->rxskb->len = 0;\r
+\r
+ /*\r
+ * Align any IP headers that may be contained\r
+ * within the frame.\r
+ */\r
+ skb_reserve(si->rxskb, 1);\r
+\r
+ return 0;\r
+}\r
+\r
+/*\r
+ * Set the IrDA communications speed.\r
+ */\r
+static int rk29_irda_set_speed(struct rk29_irda *si, int speed)\r
+{\r
+ unsigned long flags;\r
+ int ret = -EINVAL;\r
+ \r
+ printk("[%s][%d], speed=%d\n",__FUNCTION__,__LINE__,speed);\r
+\r
+ switch (speed) {\r
+ case 9600: case 19200: case 38400:\r
+ case 57600: case 115200:\r
+ \r
+ local_irq_save(flags);\r
+ \r
+ irda_hw_set_speed(speed);\r
+\r
+ si->speed = speed;\r
+\r
+ local_irq_restore(flags);\r
+ ret = 0;\r
+ break;\r
+\r
+ case 4000000:\r
+ local_irq_save(flags);\r
+\r
+ si->speed = speed;\r
+ \r
+ irda_hw_set_speed(speed);\r
+ \r
+ rk29_irda_rx_alloc(si);\r
+\r
+ local_irq_restore(flags);\r
+ ret = 0;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+static irqreturn_t rk29_irda_irq(int irq, void *dev_id)\r
+{\r
+ struct net_device *dev = (struct net_device *)dev_id;\r
+ struct rk29_irda *si = netdev_priv(dev);\r
+ u8 data[2048]={0,0};\r
+ int tmp_len=0;\r
+ int i=0;\r
+ u32 irq_src = 0; \r
+ u32 irda_setptn = 0;\r
+ \r
+ irq_src = irda_hw_get_irqsrc();\r
+ \r
+ printk("[%s][%d], 0x%x\n",__FUNCTION__,__LINE__, irq_src);\r
+ \r
+ //disable_irq(dev->irq);\r
+ \r
+ /* EIR 1, 3, 11, 12 */\r
+ irda_setptn |= irq_src & (REG_INT_EOFRX | REG_INT_TXE | REG_INT_WRE | REG_INT_RDE |\r
+ REG_INT_CRC | REG_INT_OE | REG_INT_FE | REG_INT_AC | \r
+ REG_INT_DECE | REG_INT_RDOE | REG_INT_DEX) ;\r
+\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
+ RK29IR_DBG("[%s][%d]: do err\n",__FUNCTION__,__LINE__);\r
+ BU92725GUW_clr_fifo();\r
+ BU92725GUW_reset();\r
+ }\r
+\r
+ if (IS_FIR(si)) //FIR\r
+ {\r
+ RK29IR_DBG("[%s][%d]: FIR\n",__FUNCTION__,__LINE__);\r
+ if(irda_hw_get_mode() == BU92725GUW_AUTO_MULTI_REV) {//rx\r
+ struct sk_buff *skb = si->rxskb;\r
+ RK29IR_DBG("[%s][%d]: rx\n",__FUNCTION__,__LINE__);\r
+ if (irda_setptn & (REG_INT_FE | REG_INT_OE | REG_INT_CRC | REG_INT_DECE)) {\r
+ if (irda_setptn & REG_INT_FE) {\r
+ printk(KERN_DEBUG "pxa_ir: fir receive frame error\n");\r
+ dev->stats.rx_frame_errors++;\r
+ } else {\r
+ printk(KERN_DEBUG "pxa_ir: fir receive abort\n");\r
+ dev->stats.rx_errors++;\r
+ }\r
+ }\r
+ if ((irda_setptn & (FRM_EVT_RX_EOFRX | FRM_EVT_RX_RDE | REG_INT_EOF))) {\r
+ tmp_len = BU92725GUW_get_data(skb->data+skb->len);\r
+ skb->len += tmp_len; \r
+ }\r
+ if (irda_setptn & (REG_INT_EOF | FRM_EVT_RX_EOFRX)) { \r
+ RK29IR_DBG("[%s][%d]: report data:\n",__FUNCTION__,__LINE__);\r
+ si->rxskb = NULL;\r
+ RK29IR_DATA_DBG("[%s][%d]: fir report data:\n",__FUNCTION__,__LINE__);\r
+ for (i=0;i<skb->len;i++) {\r
+ RK29IR_DATA_DBG("0x%2x ", skb->data[i]);\r
+ }\r
+ RK29IR_DATA_DBG("\n");\r
+ \r
+ skb_put(skb, skb->len);\r
+ \r
+ /* Feed it to IrLAP */\r
+ skb->dev = dev;\r
+ skb_reset_mac_header(skb);\r
+ skb->protocol = htons(ETH_P_IRDA);\r
+ dev->stats.rx_packets++;\r
+ dev->stats.rx_bytes += skb->len;\r
+ \r
+ /*\r
+ * Before we pass the buffer up, allocate a new one.\r
+ */\r
+ rk29_irda_rx_alloc(si);\r
+ \r
+ netif_rx(skb);\r
+ } \r
+ }\r
+ else if (irda_hw_get_mode() == BU92725GUW_MULTI_SEND) {//tx\r
+ struct sk_buff *skb = si->txskb; \r
+ si->txskb = NULL;\r
+ RK29IR_DBG("[%s][%d]: tx\n",__FUNCTION__,__LINE__);\r
+ if (irda_setptn & (FRM_EVT_TX_TXE | FRM_EVT_TX_WRE)) {\r
+ /*\r
+ * Do we need to change speed? Note that we're lazy\r
+ * here - we don't free the old rxskb. We don't need\r
+ * to allocate a buffer either.\r
+ */\r
+ if (si->newspeed) {\r
+ rk29_irda_set_speed(si, si->newspeed);\r
+ si->newspeed = 0;\r
+ }\r
+ \r
+ /*\r
+ * Account and free the packet.\r
+ */\r
+ if (skb) {\r
+ dev->stats.tx_packets ++;\r
+ dev->stats.tx_bytes += skb->len;\r
+ dev_kfree_skb_irq(skb);\r
+ }\r
+ \r
+ /*\r
+ * Make sure that the TX queue is available for sending\r
+ * (for retries). TX has priority over RX at all times.\r
+ */\r
+ netif_wake_queue(dev);\r
+ \r
+ irda_hw_set_moderx();\r
+ }\r
+ }\r
+ }\r
+ else //SIR\r
+ {\r
+ RK29IR_DBG("[%d][%s], sir\n", __LINE__, __FUNCTION__);\r
+ if(irda_hw_get_mode() == BU92725GUW_REV) //rx\r
+ {\r
+ RK29IR_DBG("[%d][%s], receive data:\n", __LINE__, __FUNCTION__);\r
+ if(irda_setptn & (REG_INT_OE | REG_INT_FE ))\r
+ {\r
+ dev->stats.rx_errors++;\r
+ if (irda_setptn & REG_INT_FE)\r
+ dev->stats.rx_frame_errors++;\r
+ if (irda_setptn & REG_INT_OE)\r
+ dev->stats.rx_fifo_errors++;\r
+ }\r
+ if((irda_setptn & ( FRM_EVT_RX_EOFRX| REG_INT_EOF /*|FRM_EVT_RX_RDE*/)))\r
+ {\r
+ tmp_len = BU92725GUW_get_data(data);\r
+ RK29IR_DATA_DBG("[%d][%s], sir receive data:\n", __LINE__, __FUNCTION__);\r
+ for(i=0;i<=tmp_len;i++)\r
+ {\r
+ RK29IR_DATA_DBG("0x%2x ",data[i]);\r
+ async_unwrap_char(dev, &dev->stats, &si->rx_buff, data[i]);\r
+ }\r
+ RK29IR_DATA_DBG("\n");\r
+ //BU92725GUW_clr_fifo();\r
+ }\r
+ }\r
+ else if(irda_hw_get_mode() == BU92725GUW_SEND) //tx\r
+ {\r
+ RK29IR_DBG("[%d][%s], transmit data\n", __LINE__, __FUNCTION__);\r
+ if((irda_setptn & FRM_EVT_TX_TXE) && (si->tx_buff.len)) {\r
+ RK29IR_DATA_DBG("[%d][%s], sir transmit data:\n", __LINE__, __FUNCTION__);\r
+ for (i=0;i<si->tx_buff.len;i++) {\r
+ RK29IR_DATA_DBG("0x%2x ", *(si->tx_buff.data)++);\r
+ }\r
+ RK29IR_DATA_DBG("\n");\r
+\r
+ BU92725GUW_send_data(si->tx_buff.data, si->tx_buff.len, NULL, 0);\r
+ si->tx_buff.len = 0;\r
+ }\r
+ else if (si->tx_buff.len == 0) {\r
+ dev->stats.tx_packets++;\r
+ dev->stats.tx_bytes += si->tx_buff.data - si->tx_buff.head;\r
+\r
+ /*\r
+ * Ok, we've finished transmitting. Now enable\r
+ * the receiver. Sometimes we get a receive IRQ\r
+ * immediately after a transmit...\r
+ */\r
+ if (si->newspeed) {\r
+ rk29_irda_set_speed(si, si->newspeed);\r
+ si->newspeed = 0;\r
+ } \r
+\r
+ irda_hw_set_moderx();\r
+ \r
+ /* I'm hungry! */\r
+ netif_wake_queue(dev);\r
+ }\r
+ }\r
+ }\r
+ //enable_irq(dev->irq);\r
+\r
+ return IRQ_HANDLED;\r
+}\r
+\r
+static int rk29_irda_start(struct net_device *dev)\r
+{\r
+ struct rk29_irda *si = netdev_priv(dev);\r
+ int err = 0;\r
+ \r
+ RK29IR_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);\r
+ \r
+ si->speed = 9600;\r
+ \r
+ /*\r
+ * irda module power up\r
+ */\r
+ if (si->pdata->irda_pwr_ctl)\r
+ si->pdata->irda_pwr_ctl(1);\r
+ si->power = 1;\r
+ \r
+ err = request_irq(dev->irq, rk29_irda_irq, IRQ_TYPE_LEVEL_LOW, dev->name, dev);//\r
+ if (err) {\r
+ printk("line %d: %s request_irq failed\n", __LINE__, __func__);\r
+ goto err_irq;\r
+ }\r
+\r
+ /*\r
+ * The interrupt must remain disabled for now.\r
+ */\r
+ disable_irq(dev->irq);\r
+\r
+ /*\r
+ * Setup the smc port for the specified speed.\r
+ */\r
+ err = irda_hw_startup(si);\r
+ if (err) { \r
+ printk("line %d: %s irda_hw_startup err\n", __LINE__, __func__);\r
+ goto err_startup;\r
+ }\r
+ irda_hw_set_moderx();\r
+\r
+ /*\r
+ * Open a new IrLAP layer instance.\r
+ */\r
+ si->irlap = irlap_open(dev, &si->qos, "rk29");\r
+ err = -ENOMEM;\r
+ if (!si->irlap) {\r
+ printk("line %d: %s irlap_open err\n", __LINE__, __func__);\r
+ goto err_irlap;\r
+ }\r
+ \r
+ /*\r
+ * Now enable the interrupt and start the queue\r
+ */\r
+ si->open = 1;\r
+ enable_irq(dev->irq);\r
+ netif_start_queue(dev);\r
+ \r
+ printk("rk29_ir: irda driver opened\n");\r
+\r
+ //test\r
+ //rk29_irda_set_speed(si, 4000000);\r
+ //schedule_delayed_work(&dwork, msecs_to_jiffies(5000));\r
+\r
+ return 0;\r
+\r
+err_irlap:\r
+ si->open = 0;\r
+ irda_hw_shutdown(si);\r
+err_startup:\r
+ free_irq(dev->irq, dev);\r
+err_irq:\r
+ return err;\r
+}\r
+\r
+static int rk29_irda_stop(struct net_device *dev)\r
+{\r
+ struct rk29_irda *si = netdev_priv(dev);\r
+ \r
+ RK29IR_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);\r
+\r
+ disable_irq(dev->irq);\r
+ irda_hw_shutdown(si);\r
+\r
+ /*\r
+ * If we have been doing DMA receive, make sure we\r
+ * tidy that up cleanly.\r
+ */\r
+ if (si->rxskb) {\r
+ dev_kfree_skb(si->rxskb);\r
+ si->rxskb = NULL;\r
+ }\r
+\r
+ /* Stop IrLAP */\r
+ if (si->irlap) {\r
+ irlap_close(si->irlap);\r
+ si->irlap = NULL;\r
+ }\r
+\r
+ netif_stop_queue(dev);\r
+ si->open = 0;\r
+\r
+ /*\r
+ * Free resources\r
+ */\r
+ free_irq(dev->irq, dev);\r
+\r
+ //irda module power down\r
+ if (si->pdata->irda_pwr_ctl)\r
+ si->pdata->irda_pwr_ctl(0);\r
+\r
+ si->power = 0;\r
+\r
+ return 0;\r
+}\r
+\r
+static int rk29_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)\r
+{\r
+ struct rk29_irda *si = netdev_priv(dev);\r
+ int speed = irda_get_next_speed(skb);\r
+ int i;\r
+\r
+ RK29IR_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);\r
+ /*\r
+ * Does this packet contain a request to change the interface\r
+ * speed? If so, remember it until we complete the transmission\r
+ * of this frame.\r
+ */\r
+ if (speed != si->speed && speed != -1)\r
+ si->newspeed = speed;\r
+\r
+ /*\r
+ * If this is an empty frame, we can bypass a lot.\r
+ */\r
+ if (skb->len == 0) {\r
+ if (si->newspeed) {\r
+ si->newspeed = 0;\r
+ rk29_irda_set_speed(si, speed);\r
+ }\r
+ dev_kfree_skb(skb);\r
+ return NETDEV_TX_OK;\r
+ }\r
+\r
+ netif_stop_queue(dev);\r
+\r
+ if (!IS_FIR(si)) {\r
+ si->tx_buff.data = si->tx_buff.head;\r
+ si->tx_buff.len = async_wrap_skb(skb, si->tx_buff.data, si->tx_buff.truesize);\r
+\r
+ /* Disable STUART interrupts and switch to transmit mode. */\r
+ /* enable STUART and transmit interrupts */\r
+ irda_hw_tx_enable_irq(BU92725GUW_SIR);\r
+\r
+ RK29IR_DATA_DBG("[%d][%s], sir transmit data:\n", __LINE__, __FUNCTION__);\r
+ for (i=0;i<si->tx_buff.len;i++) {\r
+ RK29IR_DATA_DBG("0x%2x ", *(si->tx_buff.data)++);\r
+ }\r
+ RK29IR_DATA_DBG("\n");\r
+\r
+ dev_kfree_skb(skb);\r
+ dev->trans_start = jiffies;\r
+ BU92725GUW_send_data(si->tx_buff.data, si->tx_buff.len, NULL, 0);\r
+ si->tx_buff.len = 0;\r
+\r
+ } \r
+ else {\r
+ unsigned long mtt = irda_get_mtt(skb);\r
+ si->txskb = skb;\r
+ \r
+ irda_hw_tx_enable_irq(BU92725GUW_FIR);\r
+\r
+ RK29IR_DATA_DBG("[%d][%s], fir transmit data:\n", __LINE__, __FUNCTION__);\r
+ for (i=0;i<skb->len;i++) {\r
+ RK29IR_DATA_DBG("0x%2x ", skb->data[i]);\r
+ }\r
+ RK29IR_DATA_DBG("\n");\r
+ \r
+ dev->trans_start = jiffies; \r
+ BU92725GUW_send_data(skb->data, skb->len, NULL, 0);\r
+ }\r
+\r
+ return NETDEV_TX_OK;\r
+}\r
+\r
+static int\r
+rk29_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)\r
+{\r
+ struct if_irda_req *rq = (struct if_irda_req *)ifreq;\r
+ struct rk29_irda *si = netdev_priv(dev);\r
+ int ret = -EOPNOTSUPP;\r
+\r
+ RK29IR_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);\r
+\r
+ switch (cmd) {\r
+ case SIOCSBANDWIDTH:\r
+ if (capable(CAP_NET_ADMIN)) {\r
+ /*\r
+ * We are unable to set the speed if the\r
+ * device is not running.\r
+ */\r
+ if (si->open) {\r
+ ret = rk29_irda_set_speed(si, rq->ifr_baudrate );\r
+ } else {\r
+ printk("rk29_irda_ioctl: SIOCSBANDWIDTH: !netif_running\n");\r
+ ret = 0;\r
+ }\r
+ }\r
+ break;\r
+\r
+ case SIOCSMEDIABUSY:\r
+ ret = -EPERM;\r
+ if (capable(CAP_NET_ADMIN)) {\r
+ irda_device_set_media_busy(dev, TRUE);\r
+ ret = 0;\r
+ }\r
+ break;\r
+\r
+ case SIOCGRECEIVING:\r
+ rq->ifr_receiving = IS_FIR(si) ? 0\r
+ : si->rx_buff.state != OUTSIDE_FRAME;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+static const struct net_device_ops rk29_irda_netdev_ops = {\r
+ .ndo_open = rk29_irda_start,\r
+ .ndo_stop = rk29_irda_stop,\r
+ .ndo_start_xmit = rk29_irda_hard_xmit,\r
+ .ndo_do_ioctl = rk29_irda_ioctl,\r
+};\r
+\r
+\r
+static int rk29_irda_init_iobuf(iobuff_t *io, int size)\r
+{\r
+ io->head = kmalloc(size, GFP_KERNEL | GFP_DMA);\r
+ if (io->head != NULL) {\r
+ io->truesize = size;\r
+ io->in_frame = FALSE;\r
+ io->state = OUTSIDE_FRAME;\r
+ io->data = io->head;\r
+ }\r
+ return io->head ? 0 : -ENOMEM;\r
+}\r
+\r
+static void rk29_irda_fir_test(struct work_struct *work)\r
+{\r
+ char send_data[4] = {0,0,0,0};\r
+ irda_hw_tx_enable_irq(BU92725GUW_FIR);\r
+ \r
+ BU92725GUW_send_data(send_data, 4, NULL, 0);\r
+ \r
+ schedule_delayed_work(&dwork, msecs_to_jiffies(5000));\r
+ return ;\r
+}\r
+\r
+static int rk29_irda_probe(struct platform_device *pdev)\r
+{\r
+ struct irda_info *mach_info = NULL;\r
+ struct net_device *dev;\r
+ struct rk29_irda *si;\r
+ unsigned int baudrate_mask;\r
+ int err = -ENOMEM;\r
+\r
+ RK29IR_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);\r
+\r
+ mach_info = pdev->dev.platform_data;\r
+\r
+ if (mach_info)\r
+ mach_info->iomux_init();\r
+\r
+ dev = alloc_irdadev(sizeof(struct rk29_irda));\r
+ if (!dev) {\r
+ printk("line %d: rk29_ir malloc failed\n", __LINE__);\r
+ goto err_mem_1;\r
+ }\r
+ SET_NETDEV_DEV(dev, &pdev->dev);\r
+ si = netdev_priv(dev);\r
+ si->dev = &pdev->dev;\r
+ si->pdata = pdev->dev.platform_data;\r
+\r
+ /*\r
+ * Initialise the HP-SIR buffers\r
+ */\r
+ err = rk29_irda_init_iobuf(&si->rx_buff, 14384);\r
+ if (err) {\r
+ printk("line %d: rk29_ir malloc failed\n", __LINE__);\r
+ goto err_mem_2;\r
+ }\r
+ err = rk29_irda_init_iobuf(&si->tx_buff, 4000);\r
+ if (err) { \r
+ printk("line %d: rk29_ir malloc failed\n", __LINE__);\r
+ goto err_mem_3;\r
+ }\r
+ dev->netdev_ops = &rk29_irda_netdev_ops;\r
+ dev->irq = gpio_to_irq(mach_info->intr_pin);\r
+\r
+ irda_init_max_qos_capabilies(&si->qos);\r
+\r
+ /*\r
+ * We support original IRDA up to 115k2. (we don't currently\r
+ * support 4Mbps). Min Turn Time set to 1ms or greater.\r
+ */\r
+ baudrate_mask = IR_9600;\r
+\r
+ switch (max_rate) {\r
+ case 4000000: baudrate_mask |= IR_4000000 << 8;\r
+ case 115200: baudrate_mask |= IR_115200;\r
+ case 57600: baudrate_mask |= IR_57600;\r
+ case 38400: baudrate_mask |= IR_38400;\r
+ case 19200: baudrate_mask |= IR_19200;\r
+ }\r
+\r
+ si->qos.baud_rate.bits &= baudrate_mask;\r
+ si->qos.min_turn_time.bits = 7;\r
+\r
+ irda_qos_bits_to_value(&si->qos);\r
+\r
+ /*\r
+ * 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
+ goto err_register;\r
+ }\r
+ platform_set_drvdata(pdev, dev);\r
+\r
+ //test\r
+ //wake_lock_init(&w_lock, WAKE_LOCK_SUSPEND, "rk29_cir");\r
+ //wake_lock(&w_lock);\r
+ \r
+ 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
+err_mem_2:\r
+ free_netdev(dev);\r
+err_mem_1:\r
+ return err;\r
+\r
+}\r
+\r
+static int rk29_irda_remove(struct platform_device *pdev)\r
+{\r
+ struct net_device *dev = platform_get_drvdata(pdev);\r
+ RK29IR_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);\r
+\r
+ if (dev) {\r
+ struct rk29_irda *si = netdev_priv(dev);\r
+ unregister_netdev(dev);\r
+ 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
+}\r
+\r
+\r
+static struct platform_driver irda_driver = {\r
+ .driver = {\r
+ .name = IRDA_NAME,\r
+ .owner = THIS_MODULE,\r
+ },\r
+ .probe = rk29_irda_probe,\r
+ .remove = rk29_irda_remove,\r
+ //.suspend = rk29_irda_suspend,\r
+ //.resume = rk29_irda_resume,\r
+};\r
+\r
+static int __init irda_init(void)\r
+{\r
+ if (platform_driver_register(&irda_driver) != 0) {\r
+ printk("Could not register irda driver\n");\r
+ return -EINVAL;\r
+ }\r
+ return 0;\r
+}\r
+\r
+static void __exit irda_exit(void)\r
+{\r
+ platform_driver_unregister(&irda_driver);\r
+}\r
+\r
+module_init(irda_init);\r
+module_exit(irda_exit);\r
+MODULE_AUTHOR(" zyw@rock-chips.com");\r
+MODULE_DESCRIPTION("Driver for irda device");\r
+MODULE_LICENSE("GPL");\r
+\r
--- /dev/null
+#ifndef __DRIVERS_NET_IRDA_RK29_IR_H\r
+#define __DRIVERS_NET_IRDA_RK29_IR_H\r
+\r
+#include "bu92725guw.h"\r
+#include <net/irda/irda.h>\r
+#include <net/irda/irmod.h>\r
+#include <net/irda/wrapper.h>\r
+#include <net/irda/irda_device.h>\r
+\r
+struct rk29_irda {\r
+ unsigned char* irda_base_addr;\r
+ unsigned char power;\r
+ unsigned char open;\r
+\r
+ int speed;\r
+ int newspeed;\r
+\r
+ struct sk_buff *txskb;\r
+ struct sk_buff *rxskb;\r
+\r
+ unsigned char *dma_rx_buff;\r
+ unsigned char *dma_tx_buff;\r
+ u32 dma_rx_buff_phy;\r
+ u32 dma_tx_buff_phy;\r
+ unsigned int dma_tx_buff_len;\r
+ int txdma;\r
+ int rxdma;\r
+\r
+\r
+ struct device *dev;\r
+ struct irda_info *pdata;\r
+ struct irlap_cb *irlap;\r
+ struct qos_info qos;\r
+\r
+ 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
--- /dev/null
+
+config RK29_SMC
+ bool "rk29 smc interface"
+ default y
+ help
+ if you want to use smc in rk29, pls enable it
+
+
+
--- /dev/null
+#
+# Makefile for the Linux IrDA infrared port device drivers.
+#
+# 9 Aug 2000, Christoph Hellwig <hch@infradead.org>
+# Rewritten to use lists instead of if-statements.
+#
+
+# FIR drivers
+obj-$(CONFIG_USB_IRDA) += irda-usb.o
+obj-$(CONFIG_SIGMATEL_FIR) += stir4200.o
+obj-$(CONFIG_NSC_FIR) += nsc-ircc.o
+obj-$(CONFIG_WINBOND_FIR) += w83977af_ir.o
+obj-$(CONFIG_SA1100_FIR) += sa1100_ir.o
+obj-$(CONFIG_TOSHIBA_FIR) += donauboe.o
+obj-$(CONFIG_SMC_IRCC_FIR) += smsc-ircc2.o
+obj-$(CONFIG_ALI_FIR) += ali-ircc.o
+obj-$(CONFIG_VLSI_FIR) += vlsi_ir.o
+obj-$(CONFIG_VIA_FIR) += via-ircc.o
+
+obj-$(CONFIG_RK29_SMC) += rk29_smc.o
--- /dev/null
+#include <linux/module.h>\r
+#include <linux/kernel.h>\r
+#include <linux/errno.h>\r
+#include <linux/string.h>\r
+#include <linux/mm.h>\r
+#include <linux/slab.h>\r
+#include <linux/delay.h>\r
+#include <linux/device.h>\r
+#include <linux/init.h>\r
+#include <linux/dma-mapping.h>\r
+#include <linux/interrupt.h>\r
+#include <linux/platform_device.h>\r
+#include <linux/clk.h>\r
+#include <linux/backlight.h>\r
+#include <linux/timer.h>\r
+#include <linux/time.h>\r
+#include <linux/wait.h>\r
+#include <linux/earlysuspend.h>\r
+#include <linux/cpufreq.h>\r
+#include <linux/wakelock.h>\r
+\r
+#include <asm/io.h>\r
+#include <asm/div64.h>\r
+#include <asm/uaccess.h>\r
+\r
+\r
+#include <mach/iomux.h>\r
+#include <mach/gpio.h>\r
+#include <mach/board.h>\r
+#include <mach/rk29_iomap.h>\r
+#include <mach/pmu.h>\r
+\r
+void __iomem *rank0_vir_base; // virtual basic address of lcdc register\r
+struct clk *smc_clk = NULL;\r
+struct clk *smc_axi_clk = NULL;\r
+void __iomem *reg_vir_base; // virtual basic address of lcdc register\r
+\r
+int smc0_enable(int enable)\r
+{\r
+ if(enable){\r
+ clk_enable(smc_axi_clk);\r
+ clk_enable(smc_clk);\r
+ __raw_writel(__raw_readl(RK29_GRF_BASE+0xbc) | 0x2000 , (RK29_GRF_BASE+0xbc));\r
+\r
+ __raw_writel((0x801), (reg_vir_base+0x18));\r
+ __raw_writel(0x00400000, (reg_vir_base+0x10));\r
+ __raw_writel((15 | (14<<8) | (15<<4) | (5<<11) ), (reg_vir_base+0x14));\r
+ //__raw_writel((15 | (10<<8) | (15<<4) | (7<<11) ), (reg_vir_base+0x14));\r
+\r
+ __raw_writel(0x00400000, (reg_vir_base+0x10));\r
+ } else {\r
+ clk_disable(smc_axi_clk);\r
+ clk_disable(smc_clk);\r
+ }\r
+ return 0;\r
+}\r
+\r
+int smc0_init(u8 **base_addr)\r
+{\r
+ u32 reg_phy_base; // physical basic address of lcdc register\r
+ u32 len; // physical map length of lcdc register\r
+ struct resource *mem;\r
+\r
+ u32 rank0_phy_base; // physical basic address of lcdc register\r
+ u32 rank0_len; // physical map length of lcdc register\r
+ struct resource *rank0_mem;\r
+\r
+ printk(" %s %d \n",__FUNCTION__, __LINE__);\r
+\r
+ if(smc_axi_clk == NULL)smc_axi_clk = clk_get(NULL, "aclk_smc");\r
+ if(smc_clk == NULL)smc_clk = clk_get(NULL, "smc");\r
+\r
+ rank0_phy_base = 0x11000000; //0x12000000;//\r
+ rank0_len = SZ_4K;\r
+ rank0_mem = request_mem_region(rank0_phy_base, rank0_len, "smc_rank0");\r
+ if (rank0_mem == NULL)\r
+ {\r
+ printk("failed to get rank0 memory region [%d]\n",__LINE__);\r
+ }\r
+\r
+ rank0_vir_base = ioremap(rank0_phy_base, rank0_len);\r
+ if (rank0_vir_base == NULL)\r
+ {\r
+ printk("ioremap() of rank0 failed\n");\r
+ }\r
+\r
+ //*base_addr = rank0_vir_base;\r
+\r
+ reg_phy_base = RK29_SMC_PHYS;\r
+ len = SZ_16K;\r
+ mem = request_mem_region(reg_phy_base, len, "smc reg");\r
+ if (mem == NULL)\r
+ {\r
+ printk("failed to get memory region [%d]\n",__LINE__);\r
+ }\r
+\r
+ reg_vir_base = ioremap(reg_phy_base, len);\r
+ if (reg_vir_base == NULL)\r
+ {\r
+ printk("ioremap() of registers failed\n");\r
+ }\r
+\r
+ smc0_enable(1);\r
+\r
+ rk29_mux_api_set(GPIO0B7_EBCGDOE_SMCOEN_NAME, GPIO0L_SMC_OE_N);\r
+ rk29_mux_api_set(GPIO0B6_EBCSDSHR_SMCBLSN1_HOSTINT_NAME, GPIO0L_SMC_BLS_N_1 );\r
+ rk29_mux_api_set(GPIO0B5_EBCVCOM_SMCBLSN0_NAME, GPIO0L_SMC_BLS_N_0 );\r
+ rk29_mux_api_set(GPIO0B4_EBCBORDER1_SMCWEN_NAME, GPIO0L_SMC_WE_N);\r
+\r
+ rk29_mux_api_set(GPIO0B3_EBCBORDER0_SMCADDR3_HOSTDATA3_NAME, GPIO0L_SMC_ADDR3);\r
+ rk29_mux_api_set(GPIO0B2_EBCSDCE2_SMCADDR2_HOSTDATA2_NAME, GPIO0L_SMC_ADDR2);\r
+ rk29_mux_api_set(GPIO0B1_EBCSDCE1_SMCADDR1_HOSTDATA1_NAME, GPIO0L_SMC_ADDR1);\r
+ rk29_mux_api_set(GPIO0B0_EBCSDCE0_SMCADDR0_HOSTDATA0_NAME, GPIO0L_SMC_ADDR0);\r
+\r
+ rk29_mux_api_set(GPIO1A1_SMCCSN0_NAME, GPIO1L_SMC_CSN0);\r
+ // rk29_mux_api_set(GPIO1A1_SMCCSN0_NAME, GPIO1L_GPIO1A1);\r
+\r
+ // if(gpio_request(RK29_PIN1_PA1, NULL) != 0)\r
+ {\r
+ // gpio_free(RK29_PIN1_PA1);\r
+ // printk(">>>>>> RK29_PIN1_PA1 gpio_request err \n ");\r
+ }\r
+ // gpio_direction_output(RK29_PIN1_PA1, GPIO_LOW);\r
+\r
+ rk29_mux_api_set(GPIO1A2_SMCCSN1_NAME, GPIO1L_SMC_CSN1);\r
+ rk29_mux_api_set(GPIO0D0_EBCSDOE_SMCADVN_NAME, GPIO0H_SMC_ADV_N);\r
+\r
+ rk29_mux_api_set(GPIO5C0_EBCSDDO0_SMCDATA0_NAME, GPIO5H_SMC_DATA0);\r
+ rk29_mux_api_set(GPIO5C1_EBCSDDO1_SMCDATA1_NAME, GPIO5H_SMC_DATA1);\r
+ rk29_mux_api_set(GPIO5C2_EBCSDDO2_SMCDATA2_NAME, GPIO5H_SMC_DATA2);\r
+ rk29_mux_api_set(GPIO5C3_EBCSDDO3_SMCDATA3_NAME, GPIO5H_SMC_DATA3);\r
+ rk29_mux_api_set(GPIO5C4_EBCSDDO4_SMCDATA4_NAME, GPIO5H_SMC_DATA4);\r
+ rk29_mux_api_set(GPIO5C5_EBCSDDO5_SMCDATA5_NAME, GPIO5H_SMC_DATA5);\r
+ rk29_mux_api_set(GPIO5C6_EBCSDDO6_SMCDATA6_NAME, GPIO5H_SMC_DATA6);\r
+ rk29_mux_api_set(GPIO5C7_EBCSDDO7_SMCDATA7_NAME, GPIO5H_SMC_DATA7);\r
+\r
+ rk29_mux_api_set(GPIO0C0_EBCGDSP_SMCDATA8_NAME, GPIO0H_SMC_DATA8);\r
+ rk29_mux_api_set(GPIO0C1_EBCGDR1_SMCDATA9_NAME, GPIO0H_SMC_DATA9);\r
+ rk29_mux_api_set(GPIO0C2_EBCSDCE0_SMCDATA10_NAME, GPIO0H_SMC_DATA10);\r
+ rk29_mux_api_set(GPIO0C3_EBCSDCE1_SMCDATA11_NAME, GPIO0H_SMC_DATA11);\r
+ rk29_mux_api_set(GPIO0C4_EBCSDCE2_SMCDATA12_NAME, GPIO0H_SMC_DATA12);\r
+ rk29_mux_api_set(GPIO0C5_EBCSDCE3_SMCDATA13_NAME, GPIO0H_SMC_DATA13);\r
+ rk29_mux_api_set(GPIO0C6_EBCSDCE4_SMCDATA14_NAME, GPIO0H_SMC_DATA14);\r
+ rk29_mux_api_set(GPIO0C7_EBCSDCE5_SMCDATA15_NAME, GPIO0H_SMC_DATA15);\r
+\r
+ return 0;\r
+\r
+}\r
+\r
+\r
+\r
+int smc0_write(u32 addr, u16 data)\r
+{\r
+ // __raw_writel(data, rank0_vir_base + addr);\r
+ u16 *p = rank0_vir_base + addr;\r
+ int readdata;\r
+ *p = data;\r
+ udelay(5);\r
+ //readdata = *p;\r
+ //mdelay(5);\r
+ //mdelay(10);\r
+ //printk("%s addr=%x, data = %x, read date = %x\n",__FUNCTION__,addr,data,readdata);\r
+ return 0;\r
+}\r
+\r
+int smc0_read(u32 addr)\r
+{\r
+ u16 * p = rank0_vir_base + addr;\r
+ int readdata = *p; \r
+ //mdelay(5);\r
+ //printk("%s addr=%x, read date = %x\n",__FUNCTION__,addr,readdata);\r
+ return readdata;//__raw_readl(rank0_vir_base + addr);\r
+}\r
+\r
+void smc0_exit(void)\r
+{\r
+ smc0_enable(0);\r
+}\r
+\r
+\r
+\r