add support for huawei e1230s/e1220s
author赵子初 <zzc@rock-chips.com>
Fri, 6 Sep 2013 08:16:31 +0000 (16:16 +0800)
committer赵子初 <zzc@rock-chips.com>
Fri, 6 Sep 2013 08:16:31 +0000 (16:16 +0800)
drivers/misc/bp/chips/Makefile
drivers/misc/bp/chips/e1230s.c [new file with mode: 0755]
drivers/usb/serial/option.c
drivers/usb/serial/usb-serial.c
include/linux/bp-auto.h

index 5b7acf26c34cf65f5b2e2f9ba34a80d9896a6a68..f0029888458a5ac155d2aaa42d3312a8e980a539 100755 (executable)
@@ -11,3 +11,4 @@ obj-$(CONFIG_BP_AUTO)                           += u7501.o
 obj-$(CONFIG_BP_AUTO)                           += a85xx.o\r
 obj-$(CONFIG_BP_AUTO)                           += u5501.o\r
 obj-$(CONFIG_BP_AUTO)                           += aw706.o\r
+obj-$(CONFIG_BP_AUTO)                          += e1230s.o
\ No newline at end of file
diff --git a/drivers/misc/bp/chips/e1230s.c b/drivers/misc/bp/chips/e1230s.c
new file mode 100755 (executable)
index 0000000..71e3c21
--- /dev/null
@@ -0,0 +1,265 @@
+/* drivers/misc/bp/chips/E1230S.c\r
+ *\r
+ * Copyright (C) 2012-2015 ROCKCHIP.\r
+ * Author: luowei <lw@rock-chips.com>\r
+ *\r
+ * This software is licensed under the terms of the GNU General Public\r
+ * License version 2, as published by the Free Software Foundation, and\r
+ * may be copied, distributed, and modified under those terms.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ */\r
+#include <linux/module.h>\r
+#include <linux/kernel.h>\r
+#include <linux/i2c.h>\r
+#include <linux/irq.h>\r
+#include <linux/gpio.h>\r
+#include <linux/input.h>\r
+#include <linux/platform_device.h>\r
+#include <linux/fs.h>\r
+#include <linux/uaccess.h>\r
+#include <linux/miscdevice.h>\r
+#include <linux/circ_buf.h>\r
+#include <linux/interrupt.h>\r
+#include <linux/miscdevice.h>\r
+#include <mach/iomux.h>\r
+#include <mach/gpio.h>\r
+#include <asm/gpio.h>\r
+#include <linux/delay.h>\r
+#include <linux/poll.h>\r
+#include <linux/wait.h>\r
+#include <linux/wakelock.h>\r
+#include <linux/workqueue.h>\r
+#include <linux/slab.h>\r
+#include <linux/earlysuspend.h>\r
+\r
+#include <linux/bp-auto.h>\r
+         \r
+/****************operate according to bp chip:start************/\r
+static int bp_active(struct bp_private_data *bp, int enable)\r
+{              \r
+       return 0;\r
+}\r
+\r
+static int ap_wake_bp(struct bp_private_data *bp, int wake)\r
+{\r
+       printk("<-----E1230S ap_wake_bp-------->\n");\r
+       gpio_set_value(bp->ops->ap_wakeup_bp, wake);  \r
+       \r
+       return 0;\r
+\r
+}\r
+\r
+static void  ap_wake_bp_work(struct work_struct *work)\r
+{\r
+       struct delayed_work *wakeup_work = container_of(work, struct delayed_work, work);\r
+       struct bp_private_data *bp = container_of(wakeup_work, struct bp_private_data, wakeup_work);\r
+       if(bp->suspend_status)\r
+       {\r
+               bp->suspend_status = 0;\r
+               if(bp->ops->ap_wake_bp)\r
+               bp->ops->ap_wake_bp(bp, 0);\r
+       }\r
+}\r
+\r
+\r
+static int bp_init(struct bp_private_data *bp)\r
+{\r
+       printk("<-----E1230S bp_init-------->\n");\r
+       gpio_direction_output(bp->ops->bp_power, GPIO_HIGH);\r
+       gpio_set_value(bp->ops->bp_power, GPIO_HIGH);\r
+       msleep(500);\r
+       bp->suspend_status = 0;\r
+       gpio_direction_input(bp->ops->bp_wakeup_ap);\r
+       gpio_pull_updown(bp->ops->bp_wakeup_ap, 1);     \r
+       gpio_direction_output(bp->ops->bp_en, GPIO_HIGH);\r
+       gpio_direction_output(bp->ops->ap_wakeup_bp, GPIO_LOW);\r
+       INIT_DELAYED_WORK(&bp->wakeup_work, ap_wake_bp_work);\r
+       return 0;\r
+}\r
+\r
+static int bp_reset(struct bp_private_data *bp)\r
+{\r
+       gpio_set_value(bp->ops->bp_en, GPIO_LOW);\r
+       gpio_set_value(bp->ops->bp_power, GPIO_LOW);\r
+       msleep(3000);\r
+       gpio_set_value(bp->ops->bp_power, GPIO_HIGH);\r
+       gpio_set_value(bp->ops->bp_en, GPIO_HIGH);      \r
+\r
+       return 0;\r
+}\r
+\r
+static int bp_wake_ap(struct bp_private_data *bp)\r
+{\r
+       printk("<-----E1230S bp_wake_ap-------->\n");\r
+       \r
+       bp->suspend_status = 1;\r
+       schedule_delayed_work(&bp->wakeup_work, 2*HZ);\r
+       wake_lock_timeout(&bp->bp_wakelock, 10* HZ);    \r
+       \r
+       return 0;\r
+}\r
+\r
+static int bp_shutdown(struct bp_private_data *bp)\r
+{\r
+       int result = 0;\r
+       \r
+       if(bp->ops->active)\r
+               bp->ops->active(bp, 0);\r
+       gpio_set_value(bp->ops->bp_power, GPIO_LOW);\r
+       cancel_delayed_work_sync(&bp->wakeup_work);     \r
+\r
+       return result;\r
+}\r
+\r
+static int bp_suspend(struct bp_private_data *bp)\r
+{      \r
+\r
+       gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_HIGH);       \r
+       \r
+       return 0;\r
+}\r
+\r
+static int bp_resume(struct bp_private_data *bp)\r
+{      \r
+       if(!bp->suspend_status){\r
+       gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_LOW);        \r
+       }\r
+       return 0;\r
+}\r
+\r
+\r
+struct bp_operate bp_E1230S_ops = {\r
+#if defined(CONFIG_ARCH_RK2928)\r
+       .name                   = "E1230S",\r
+       .bp_id                  = BP_ID_E1230S,\r
+       .bp_bus                 = BP_BUS_TYPE_USB_UART,         \r
+       .bp_pid                 = 0,    \r
+       .bp_vid                 = 0,    \r
+       .bp_power               = RK2928_PIN3_PC2,      // 3g_power\r
+       .bp_en                  = BP_UNKNOW_DATA,       // 3g_en\r
+       .bp_reset                       = RK2928_PIN1_PA3,\r
+       .ap_ready               = BP_UNKNOW_DATA,       //\r
+       .bp_ready               = BP_UNKNOW_DATA,\r
+       .ap_wakeup_bp           = RK2928_PIN3_PC4,\r
+       .bp_wakeup_ap           = RK2928_PIN3_PC3,      //\r
+       .bp_uart_en             = BP_UNKNOW_DATA,       //EINT9\r
+       .bp_usb_en              = BP_UNKNOW_DATA,       //W_disable\r
+       .trig                   = IRQF_TRIGGER_FALLING,\r
+\r
+       .active                 = bp_active,\r
+       .init                   = bp_init,\r
+       .reset                  = bp_reset,\r
+       .ap_wake_bp             = ap_wake_bp,\r
+       .bp_wake_ap             = bp_wake_ap,\r
+       .shutdown               = bp_shutdown,\r
+       .read_status            = NULL,\r
+       .write_status           = NULL,\r
+       .suspend                = bp_suspend,\r
+       .resume                 = bp_resume,\r
+       .misc_name              = NULL,\r
+       .private_miscdev        = NULL,\r
+#elif (defined(CONFIG_SOC_RK3168) || defined(CONFIG_SOC_RK3188))\r
+       .name                   = "E1230S",\r
+       .bp_id                  = BP_ID_E1230S,\r
+       .bp_bus                 = BP_BUS_TYPE_USB_UART,         \r
+       .bp_pid                 = 0,    \r
+       .bp_vid                 = 0,    \r
+       .bp_power               = RK30_PIN0_PC6,// 3g_power\r
+       .bp_en                  = RK30_PIN2_PD5,// 3g_en\r
+       .bp_reset                       = RK30_PIN2_PD4,//BP_UNKNOW_DATA,\r
+       .ap_ready               = BP_UNKNOW_DATA,       //\r
+       .bp_ready               = BP_UNKNOW_DATA,\r
+       .ap_wakeup_bp           = RK30_PIN0_PC4,\r
+       .bp_wakeup_ap           = RK30_PIN0_PC5,        //\r
+       .bp_uart_en             = BP_UNKNOW_DATA,       //EINT9\r
+       .bp_usb_en              = BP_UNKNOW_DATA,       //W_disable\r
+       .trig                   = IRQF_TRIGGER_FALLING,\r
+\r
+       .active                 = bp_active,\r
+       .init                   = bp_init,\r
+       .reset                  = bp_reset,\r
+       .ap_wake_bp             = ap_wake_bp,\r
+       .bp_wake_ap             = bp_wake_ap,\r
+       .shutdown               = bp_shutdown,\r
+       .read_status            = NULL,\r
+       .write_status           = NULL,\r
+       .suspend                = bp_suspend,\r
+       .resume                 = bp_resume,\r
+       .misc_name              = NULL,\r
+       .private_miscdev        = NULL,\r
+#else\r
+       .name                   = "E1230S",\r
+       .bp_id                  = BP_ID_E1230S,\r
+       .bp_bus                 = BP_BUS_TYPE_USB_UART,         \r
+       .bp_pid                 = 0,    \r
+       .bp_vid                 = 0,    \r
+       .bp_power               = BP_UNKNOW_DATA,//RK2928_PIN3_PC2,     // 3g_power\r
+       .bp_en                  = BP_UNKNOW_DATA,       // 3g_en\r
+       .bp_reset                       = BP_UNKNOW_DATA,//RK2928_PIN1_PA3,\r
+       .ap_ready               = BP_UNKNOW_DATA,       //\r
+       .bp_ready               = BP_UNKNOW_DATA,\r
+       .ap_wakeup_bp           = BP_UNKNOW_DATA,//RK2928_PIN3_PC4,\r
+       .bp_wakeup_ap           = BP_UNKNOW_DATA,//RK2928_PIN3_PC3,     //\r
+       .bp_uart_en             = BP_UNKNOW_DATA,       //EINT9\r
+       .bp_usb_en              = BP_UNKNOW_DATA,       //W_disable\r
+       .trig                   = IRQF_TRIGGER_FALLING,\r
+\r
+       .active                 = bp_active,\r
+       .init                   = bp_init,\r
+       .reset                  = bp_reset,\r
+       .ap_wake_bp             = ap_wake_bp,\r
+       .bp_wake_ap             = bp_wake_ap,\r
+       .shutdown               = bp_shutdown,\r
+       .read_status            = NULL,\r
+       .write_status           = NULL,\r
+       .suspend                = bp_suspend,\r
+       .resume                 = bp_resume,\r
+       .misc_name              = NULL,\r
+       .private_miscdev        = NULL,\r
+#endif\r
+};\r
+\r
+/****************operate according to bp chip:end************/\r
+\r
+//function name should not be changed\r
+static struct bp_operate *bp_get_ops(void)\r
+{\r
+       return &bp_E1230S_ops;\r
+}\r
+\r
+static int __init bp_E1230S_init(void)\r
+{\r
+       struct bp_operate *ops = bp_get_ops();\r
+       int result = 0;\r
+       result = bp_register_slave(NULL, NULL, bp_get_ops);\r
+       if(result)\r
+       {       \r
+               return result;\r
+       }\r
+       \r
+       if(ops->private_miscdev)\r
+       {\r
+               result = misc_register(ops->private_miscdev);\r
+               if (result < 0) {\r
+                       printk("%s:misc_register err\n",__func__);\r
+                       return result;\r
+               }\r
+       }\r
+       return result;\r
+}\r
+\r
+static void __exit bp_E1230S_exit(void)\r
+{\r
+       //struct bp_operate *ops = bp_get_ops();\r
+       bp_unregister_slave(NULL, NULL, bp_get_ops);\r
+}\r
+\r
+\r
+subsys_initcall(bp_E1230S_init);\r
+module_exit(bp_E1230S_exit);\r
+\r
index c9c4ce7c196e31318f1f6bb02577ed5721c1d486..93039fb2e6e3803e66a24fc0ae2dcf21c258be8d 100644 (file)
@@ -1332,6 +1332,7 @@ static const struct usb_device_id option_ids[] = {
     { USB_DEVICE(0x19D2, 0x1181) },
        { USB_DEVICE(0x2020, 0x1005)},//S830 3G Dongle
     { USB_DEVICE(0x1782, 0x0002)},//U7501
+    { USB_DEVICE(0x1782, 0x4D00)},
        { USB_DEVICE(0x21f5, 0x2012) },//SEW290
 // cmy end
 //xxh
index e88a062dc28b1584746837febe2c7b722137e9ca..2a1ad9c70af771f09d33f6fc339c65039f6a2190 100755 (executable)
@@ -1084,6 +1084,7 @@ int usb_serial_probe(struct usb_interface *interface,
                        || ((le16_to_cpu(dev->descriptor.idVendor) == 0x1782) && (le16_to_cpu(dev->descriptor.idProduct) == 0x4D00) && (bp_id == BP_ID_U7501))
                        || ((le16_to_cpu(dev->descriptor.idVendor) == 0x21f5) && (le16_to_cpu(dev->descriptor.idProduct) == 0x2012) && (bp_id == BP_ID_SEW290))
                        || ((le16_to_cpu(dev->descriptor.idVendor) == 0x1c9e) && (le16_to_cpu(dev->descriptor.idProduct) == 0x9603) && (bp_id == BP_ID_U5501))
+                       || ((le16_to_cpu(dev->descriptor.idVendor) == 0x12d1) && (le16_to_cpu(dev->descriptor.idProduct) == 0x1506) && (bp_id == BP_ID_E1230S)) 
                ){
                        BP_USB =1;
 
index 5ecae14e3388b8fb51e69927c764e12fa3cc5e50..e70b59ca5fa7487accfd292740a0deb553e23f93 100755 (executable)
@@ -32,7 +32,7 @@ enum bp_id{
        BP_ID_MW100,    //4 thinkwill MW100 WCDMA\r
        BP_ID_TD8801,   //5 spreadtrum SC8803 TD-SCDMA\r
        BP_ID_SC6610,   //6 spreadtrum SC6610 GSM\r
-       BP_ID_M51,      //7 spreadtrum RDA GSM\r
+       BP_ID_M50,      //7 spreadtrum RDA GSM\r
        BP_ID_MT6250,   //8 ZINN M50  EDGE\r
        BP_ID_C66A,     //9 ZHIGUAN C66A GSM\r
        BP_ID_SEW290,   //10 SCV SEW290 WCDMA\r
@@ -40,6 +40,7 @@ enum bp_id{
        BP_ID_U7501,    //12 LONGSUNG U7501 WCDMA/HSPA+\r
        BP_ID_AW706,    //13 ANICARE AW706 EDGE\r
        BP_ID_A85XX,    //14 LONGSUNG A8520/A8530 GSM
+    BP_ID_E1230S,    //15 huawei E1230S\r
 
        BP_ID_NUM,  \r
 };\r