mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
add SEW290 3G modem
This commit is contained in:
44
arch/arm/mach-rk30/board-rk30-phonepad.c
Executable file → Normal file
44
arch/arm/mach-rk30/board-rk30-phonepad.c
Executable file → Normal file
@@ -1427,21 +1427,41 @@ static int bp_io_deinit(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bp_id_get(void)
|
||||
{
|
||||
int bp_id = 0;
|
||||
#if defined(CONFIG_BP_AUTO_MT6229)
|
||||
bp_id = BP_ID_MT6229;
|
||||
#elif defined(CONFIG_BP_AUTO_MU509)
|
||||
bp_id = BP_ID_MU509;
|
||||
#elif defined(CONFIG_BP_AUTO_MW100)
|
||||
bp_id = BP_ID_MW100;
|
||||
#elif defined(CONFIG_BP_AUTO_MI700)
|
||||
bp_id = BP_ID_MI700;
|
||||
#endif
|
||||
#elif defined(CONFIG_BP_AUTO_MI700)
|
||||
bp_id = BP_ID_SEW290;
|
||||
#endif
|
||||
return bp_id;
|
||||
}
|
||||
|
||||
struct bp_platform_data bp_auto_info = {
|
||||
.board_id = BOARD_ID_C8003,
|
||||
.bp_id = BP_ID_MT6229,
|
||||
.init_platform_hw = bp_io_init,
|
||||
.exit_platform_hw = bp_io_deinit,
|
||||
.bp_power = RK30_PIN6_PB2, // 3g_power
|
||||
.bp_en = RK30_PIN2_PB6, // 3g_en
|
||||
.bp_usb_en = RK30_PIN2_PC0, //W_disable
|
||||
.bp_uart_en = RK30_PIN2_PC1, //EINT9
|
||||
.bp_wakeup_ap = RK30_PIN6_PA1, //
|
||||
.ap_ready = RK30_PIN2_PB7, //
|
||||
.gpio_valid = 0, //don't use this gpios
|
||||
struct bp_platform_data bp_auto_info = {
|
||||
.init_platform_hw = bp_io_init,
|
||||
.exit_platform_hw = bp_io_deinit,
|
||||
.get_bp_id = bp_id_get,
|
||||
.bp_power = RK30_PIN6_PB2, // 3g_power,<2C><><EFBFBD><EFBFBD>ʵ<EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
.bp_en = BP_UNKNOW_DATA, // 3g_en
|
||||
.bp_reset = BP_UNKNOW_DATA, //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
.bp_usb_en = BP_UNKNOW_DATA, //W_disable
|
||||
.bp_uart_en = BP_UNKNOW_DATA, //EINT9
|
||||
.bp_wakeup_ap = RK30_PIN2_PC4, //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD>ʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
.ap_wakeup_bp = RK30_PIN2_PC4, //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
.ap_ready = BP_UNKNOW_DATA, //
|
||||
.bp_ready = BP_UNKNOW_DATA,
|
||||
.gpio_valid = 1, //if 1:gpio is define in bp_auto_info,if 0:is not use gpio in bp_auto_info
|
||||
};
|
||||
|
||||
|
||||
struct platform_device device_bp_auto = {
|
||||
.name = "bp-auto",
|
||||
.id = -1,
|
||||
|
||||
@@ -16,3 +16,6 @@ config BP_AUTO_C66A
|
||||
bool "modem c66a"
|
||||
default n
|
||||
|
||||
config BP_AUTO_SEW290
|
||||
bool "modem sew290"
|
||||
default n
|
||||
|
||||
@@ -6,3 +6,4 @@ obj-$(CONFIG_BP_AUTO) += sc6610.o
|
||||
obj-$(CONFIG_BP_AUTO) += m51.o
|
||||
obj-$(CONFIG_BP_AUTO) += mtk6250.o
|
||||
obj-$(CONFIG_BP_AUTO) += c66a.o
|
||||
obj-$(CONFIG_BP_AUTO) += sew290.o
|
||||
|
||||
258
drivers/misc/bp/chips/sew290.c
Normal file
258
drivers/misc/bp/chips/sew290.c
Normal file
@@ -0,0 +1,258 @@
|
||||
/* drivers/misc/bp/chips/mu509.c
|
||||
*
|
||||
* Copyright (C) 2012-2015 ROCKCHIP.
|
||||
* Author: luowei <lw@rock-chips.com>
|
||||
*
|
||||
* 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 <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/circ_buf.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/wakelock.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/earlysuspend.h>
|
||||
|
||||
#include <linux/bp-auto.h>
|
||||
|
||||
|
||||
#if 0
|
||||
#define DBG(x...) printk(x)
|
||||
|
||||
#else
|
||||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
|
||||
/****************operate according to bp chip:start************/
|
||||
static int bp_active(struct bp_private_data *bp, int enable)
|
||||
{
|
||||
printk("<-----SEW290 bp_active-------->\n");
|
||||
if(enable)
|
||||
{
|
||||
gpio_set_value(bp->ops->bp_power, GPIO_LOW);
|
||||
msleep(1000);
|
||||
gpio_set_value(bp->ops->bp_power, GPIO_HIGH);
|
||||
msleep(2500);
|
||||
gpio_set_value(bp->ops->bp_power, GPIO_LOW);
|
||||
gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_LOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_HIGH);
|
||||
msleep(4000);
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_LOW);
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ap_wake_bp(struct bp_private_data *bp, int wake)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
gpio_set_value(bp->ops->ap_wakeup_bp, wake);
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if(bp->ops->ap_wake_bp)
|
||||
bp->ops->ap_wake_bp(bp, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(bp->ops->ap_wake_bp)
|
||||
bp->ops->ap_wake_bp(bp, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int bp_init(struct bp_private_data *bp)
|
||||
{
|
||||
printk("<-----SEW290 bp_init-------->\n");
|
||||
gpio_direction_output(bp->ops->bp_power, GPIO_HIGH);
|
||||
gpio_set_value(bp->ops->bp_power, GPIO_HIGH);
|
||||
msleep(500);
|
||||
//if(bp->ops->active)
|
||||
// bp->ops->active(bp, 1);
|
||||
gpio_direction_input(bp->ops->bp_wakeup_ap);
|
||||
gpio_direction_output(bp->ops->bp_reset, GPIO_LOW);
|
||||
gpio_direction_output(bp->ops->bp_en, GPIO_LOW);
|
||||
gpio_direction_output(bp->ops->ap_wakeup_bp, GPIO_HIGH);
|
||||
INIT_DELAYED_WORK(&bp->wakeup_work, ap_wake_bp_work);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bp_reset(struct bp_private_data *bp)
|
||||
{
|
||||
// gpio_direction_output(bp->ops->bp_power, GPIO_HIGH);
|
||||
// msleep(500);
|
||||
gpio_set_value(bp->ops->bp_reset, GPIO_HIGH);
|
||||
msleep(100);
|
||||
gpio_set_value(bp->ops->bp_reset, GPIO_LOW);
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_LOW);
|
||||
msleep(1000);
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_HIGH);
|
||||
msleep(700);
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_LOW);
|
||||
gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_LOW);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bp_wake_ap(struct bp_private_data *bp)
|
||||
{
|
||||
printk("<-----SEW290 bp_wake_ap-------->\n");
|
||||
|
||||
bp->suspend_status = 0;
|
||||
wake_lock_timeout(&bp->bp_wakelock, 20* 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)
|
||||
{
|
||||
|
||||
printk("<-----SEW290 bp_suspend-------->\n");
|
||||
|
||||
bp->suspend_status = 1;
|
||||
gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_LOW);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static int bp_resume(struct bp_private_data *bp)
|
||||
{
|
||||
|
||||
printk("<-----SEW290 bp_resume-------->\n");
|
||||
bp->suspend_status = 0;
|
||||
gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_HIGH);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct bp_operate bp_sew290_ops = {
|
||||
.name = "sew290",
|
||||
.bp_id = BP_ID_SEW290,
|
||||
.bp_bus = BP_BUS_TYPE_USB_UART,
|
||||
.bp_pid = 0,
|
||||
.bp_vid = 0,
|
||||
.bp_power = BP_UNKNOW_DATA, // 3g_power
|
||||
.bp_en = BP_UNKNOW_DATA, // 3g_en
|
||||
.bp_reset = BP_UNKNOW_DATA,
|
||||
.ap_ready = BP_UNKNOW_DATA, //
|
||||
.bp_ready = BP_UNKNOW_DATA,
|
||||
.ap_wakeup_bp = RK30_PIN2_PC5,
|
||||
.bp_wakeup_ap = RK30_PIN2_PC4, //
|
||||
.bp_uart_en = BP_UNKNOW_DATA, //EINT9
|
||||
.bp_usb_en = BP_UNKNOW_DATA, //W_disable
|
||||
.trig = IRQF_TRIGGER_RISING,
|
||||
|
||||
.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,
|
||||
};
|
||||
|
||||
/****************operate according to bp chip:end************/
|
||||
|
||||
//function name should not be changed
|
||||
static struct bp_operate *bp_get_ops(void)
|
||||
{
|
||||
return &bp_sew290_ops;
|
||||
}
|
||||
|
||||
static int __init bp_sew290_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;
|
||||
}
|
||||
}
|
||||
|
||||
DBG("%s\n",__func__);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void __exit bp_sew290_exit(void)
|
||||
{
|
||||
//struct bp_operate *ops = bp_get_ops();
|
||||
bp_unregister_slave(NULL, NULL, bp_get_ops);
|
||||
}
|
||||
|
||||
|
||||
subsys_initcall(bp_sew290_init);
|
||||
module_exit(bp_sew290_exit);
|
||||
|
||||
2
drivers/usb/serial/option.c
Executable file → Normal file
2
drivers/usb/serial/option.c
Executable file → Normal file
@@ -1331,6 +1331,8 @@ static const struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE(0x1d09, 0x1010) },
|
||||
{ USB_DEVICE(0x19D2, 0x1181) },
|
||||
{ USB_DEVICE(0x2020, 0x1005)},//S830 3G Dongle
|
||||
{ USB_DEVICE(0x1782, 0x0002)},//U7501
|
||||
{ USB_DEVICE(0x21f5, 0x2012) },//SEW290
|
||||
// cmy end
|
||||
//xxh
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x05c6, 0x1000, 0xff, 0xff, 0xff) },
|
||||
|
||||
3
drivers/usb/serial/usb-serial.c
Executable file → Normal file
3
drivers/usb/serial/usb-serial.c
Executable file → Normal file
@@ -1075,9 +1075,10 @@ int usb_serial_probe(struct usb_interface *interface,
|
||||
}
|
||||
#ifdef CONFIG_BP_AUTO
|
||||
int bp_id = get_current_bp_id();
|
||||
if (((le16_to_cpu(dev->descriptor.idVendor) == 0x12D1 ) && (le16_to_cpu(dev->descriptor.idProduct) == 0x1001) && (bp_id == 2))
|
||||
if (((le16_to_cpu(dev->descriptor.idVendor) == 0x1782 ) && (le16_to_cpu(dev->descriptor.idProduct) == 0x0002) && (bp_id == 2))
|
||||
|| ((le16_to_cpu(dev->descriptor.idVendor) == 0x19f5) && (le16_to_cpu(dev->descriptor.idProduct) == 0x9013) && (bp_id == 4))
|
||||
|| ((le16_to_cpu(dev->descriptor.idVendor) == 0x0E8D) && (le16_to_cpu(dev->descriptor.idProduct) == 0x00A2) && (bp_id == 1))
|
||||
|| ((le16_to_cpu(dev->descriptor.idVendor) == 0x21f5) && (le16_to_cpu(dev->descriptor.idProduct) == 0x2012) && (bp_id == 10))
|
||||
){
|
||||
BP_USB =1;
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ enum bp_id{
|
||||
BP_ID_M50, //spreadtrum RDA GSM
|
||||
BP_ID_MT6250, //ZINN M50 EDGE
|
||||
BP_ID_C66A, //zhongben
|
||||
BP_ID_SEW290, //SCV SEW290 WCDMA
|
||||
BP_ID_NUM,
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user