From: 赵子初 Date: Fri, 6 Sep 2013 08:16:31 +0000 (+0800) Subject: add support for huawei e1230s/e1220s X-Git-Tag: firefly_0821_release~6653 X-Git-Url: http://plrg.eecs.uci.edu/git/?p=firefly-linux-kernel-4.4.55.git;a=commitdiff_plain;h=61ce31f96e0cd903d5e85b5612509a155317a89f add support for huawei e1230s/e1220s --- diff --git a/drivers/misc/bp/chips/Makefile b/drivers/misc/bp/chips/Makefile index 5b7acf26c34c..f0029888458a 100755 --- a/drivers/misc/bp/chips/Makefile +++ b/drivers/misc/bp/chips/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_BP_AUTO) += u7501.o obj-$(CONFIG_BP_AUTO) += a85xx.o obj-$(CONFIG_BP_AUTO) += u5501.o obj-$(CONFIG_BP_AUTO) += aw706.o +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 index 000000000000..71e3c21c6e75 --- /dev/null +++ b/drivers/misc/bp/chips/e1230s.c @@ -0,0 +1,265 @@ +/* drivers/misc/bp/chips/E1230S.c + * + * Copyright (C) 2012-2015 ROCKCHIP. + * Author: luowei + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/****************operate according to bp chip:start************/ +static int bp_active(struct bp_private_data *bp, int enable) +{ + return 0; +} + +static int ap_wake_bp(struct bp_private_data *bp, int wake) +{ + printk("<-----E1230S ap_wake_bp-------->\n"); + gpio_set_value(bp->ops->ap_wakeup_bp, wake); + + return 0; + +} + +static void ap_wake_bp_work(struct work_struct *work) +{ + struct delayed_work *wakeup_work = container_of(work, struct delayed_work, work); + struct bp_private_data *bp = container_of(wakeup_work, struct bp_private_data, wakeup_work); + if(bp->suspend_status) + { + bp->suspend_status = 0; + if(bp->ops->ap_wake_bp) + bp->ops->ap_wake_bp(bp, 0); + } +} + + +static int bp_init(struct bp_private_data *bp) +{ + printk("<-----E1230S bp_init-------->\n"); + gpio_direction_output(bp->ops->bp_power, GPIO_HIGH); + gpio_set_value(bp->ops->bp_power, GPIO_HIGH); + msleep(500); + bp->suspend_status = 0; + gpio_direction_input(bp->ops->bp_wakeup_ap); + gpio_pull_updown(bp->ops->bp_wakeup_ap, 1); + gpio_direction_output(bp->ops->bp_en, GPIO_HIGH); + gpio_direction_output(bp->ops->ap_wakeup_bp, GPIO_LOW); + INIT_DELAYED_WORK(&bp->wakeup_work, ap_wake_bp_work); + return 0; +} + +static int bp_reset(struct bp_private_data *bp) +{ + gpio_set_value(bp->ops->bp_en, GPIO_LOW); + gpio_set_value(bp->ops->bp_power, GPIO_LOW); + msleep(3000); + gpio_set_value(bp->ops->bp_power, GPIO_HIGH); + gpio_set_value(bp->ops->bp_en, GPIO_HIGH); + + return 0; +} + +static int bp_wake_ap(struct bp_private_data *bp) +{ + printk("<-----E1230S bp_wake_ap-------->\n"); + + bp->suspend_status = 1; + schedule_delayed_work(&bp->wakeup_work, 2*HZ); + wake_lock_timeout(&bp->bp_wakelock, 10* HZ); + + return 0; +} + +static int bp_shutdown(struct bp_private_data *bp) +{ + int result = 0; + + if(bp->ops->active) + bp->ops->active(bp, 0); + gpio_set_value(bp->ops->bp_power, GPIO_LOW); + cancel_delayed_work_sync(&bp->wakeup_work); + + return result; +} + +static int bp_suspend(struct bp_private_data *bp) +{ + + gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_HIGH); + + return 0; +} + +static int bp_resume(struct bp_private_data *bp) +{ + if(!bp->suspend_status){ + gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_LOW); + } + return 0; +} + + +struct bp_operate bp_E1230S_ops = { +#if defined(CONFIG_ARCH_RK2928) + .name = "E1230S", + .bp_id = BP_ID_E1230S, + .bp_bus = BP_BUS_TYPE_USB_UART, + .bp_pid = 0, + .bp_vid = 0, + .bp_power = RK2928_PIN3_PC2, // 3g_power + .bp_en = BP_UNKNOW_DATA, // 3g_en + .bp_reset = RK2928_PIN1_PA3, + .ap_ready = BP_UNKNOW_DATA, // + .bp_ready = BP_UNKNOW_DATA, + .ap_wakeup_bp = RK2928_PIN3_PC4, + .bp_wakeup_ap = RK2928_PIN3_PC3, // + .bp_uart_en = BP_UNKNOW_DATA, //EINT9 + .bp_usb_en = BP_UNKNOW_DATA, //W_disable + .trig = IRQF_TRIGGER_FALLING, + + .active = bp_active, + .init = bp_init, + .reset = bp_reset, + .ap_wake_bp = ap_wake_bp, + .bp_wake_ap = bp_wake_ap, + .shutdown = bp_shutdown, + .read_status = NULL, + .write_status = NULL, + .suspend = bp_suspend, + .resume = bp_resume, + .misc_name = NULL, + .private_miscdev = NULL, +#elif (defined(CONFIG_SOC_RK3168) || defined(CONFIG_SOC_RK3188)) + .name = "E1230S", + .bp_id = BP_ID_E1230S, + .bp_bus = BP_BUS_TYPE_USB_UART, + .bp_pid = 0, + .bp_vid = 0, + .bp_power = RK30_PIN0_PC6,// 3g_power + .bp_en = RK30_PIN2_PD5,// 3g_en + .bp_reset = RK30_PIN2_PD4,//BP_UNKNOW_DATA, + .ap_ready = BP_UNKNOW_DATA, // + .bp_ready = BP_UNKNOW_DATA, + .ap_wakeup_bp = RK30_PIN0_PC4, + .bp_wakeup_ap = RK30_PIN0_PC5, // + .bp_uart_en = BP_UNKNOW_DATA, //EINT9 + .bp_usb_en = BP_UNKNOW_DATA, //W_disable + .trig = IRQF_TRIGGER_FALLING, + + .active = bp_active, + .init = bp_init, + .reset = bp_reset, + .ap_wake_bp = ap_wake_bp, + .bp_wake_ap = bp_wake_ap, + .shutdown = bp_shutdown, + .read_status = NULL, + .write_status = NULL, + .suspend = bp_suspend, + .resume = bp_resume, + .misc_name = NULL, + .private_miscdev = NULL, +#else + .name = "E1230S", + .bp_id = BP_ID_E1230S, + .bp_bus = BP_BUS_TYPE_USB_UART, + .bp_pid = 0, + .bp_vid = 0, + .bp_power = BP_UNKNOW_DATA,//RK2928_PIN3_PC2, // 3g_power + .bp_en = BP_UNKNOW_DATA, // 3g_en + .bp_reset = BP_UNKNOW_DATA,//RK2928_PIN1_PA3, + .ap_ready = BP_UNKNOW_DATA, // + .bp_ready = BP_UNKNOW_DATA, + .ap_wakeup_bp = BP_UNKNOW_DATA,//RK2928_PIN3_PC4, + .bp_wakeup_ap = BP_UNKNOW_DATA,//RK2928_PIN3_PC3, // + .bp_uart_en = BP_UNKNOW_DATA, //EINT9 + .bp_usb_en = BP_UNKNOW_DATA, //W_disable + .trig = IRQF_TRIGGER_FALLING, + + .active = bp_active, + .init = bp_init, + .reset = bp_reset, + .ap_wake_bp = ap_wake_bp, + .bp_wake_ap = bp_wake_ap, + .shutdown = bp_shutdown, + .read_status = NULL, + .write_status = NULL, + .suspend = bp_suspend, + .resume = bp_resume, + .misc_name = NULL, + .private_miscdev = NULL, +#endif +}; + +/****************operate according to bp chip:end************/ + +//function name should not be changed +static struct bp_operate *bp_get_ops(void) +{ + return &bp_E1230S_ops; +} + +static int __init bp_E1230S_init(void) +{ + struct bp_operate *ops = bp_get_ops(); + int result = 0; + result = bp_register_slave(NULL, NULL, bp_get_ops); + if(result) + { + return result; + } + + if(ops->private_miscdev) + { + result = misc_register(ops->private_miscdev); + if (result < 0) { + printk("%s:misc_register err\n",__func__); + return result; + } + } + return result; +} + +static void __exit bp_E1230S_exit(void) +{ + //struct bp_operate *ops = bp_get_ops(); + bp_unregister_slave(NULL, NULL, bp_get_ops); +} + + +subsys_initcall(bp_E1230S_init); +module_exit(bp_E1230S_exit); + diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index c9c4ce7c196e..93039fb2e6e3 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -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 diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index e88a062dc28b..2a1ad9c70af7 100755 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -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; diff --git a/include/linux/bp-auto.h b/include/linux/bp-auto.h index 5ecae14e3388..e70b59ca5fa7 100755 --- a/include/linux/bp-auto.h +++ b/include/linux/bp-auto.h @@ -32,7 +32,7 @@ enum bp_id{ BP_ID_MW100, //4 thinkwill MW100 WCDMA BP_ID_TD8801, //5 spreadtrum SC8803 TD-SCDMA BP_ID_SC6610, //6 spreadtrum SC6610 GSM - BP_ID_M51, //7 spreadtrum RDA GSM + BP_ID_M50, //7 spreadtrum RDA GSM BP_ID_MT6250, //8 ZINN M50 EDGE BP_ID_C66A, //9 ZHIGUAN C66A GSM BP_ID_SEW290, //10 SCV SEW290 WCDMA @@ -40,6 +40,7 @@ enum bp_id{ BP_ID_U7501, //12 LONGSUNG U7501 WCDMA/HSPA+ BP_ID_AW706, //13 ANICARE AW706 EDGE BP_ID_A85XX, //14 LONGSUNG A8520/A8530 GSM + BP_ID_E1230S, //15 huawei E1230S BP_ID_NUM, };