From: 赵子初 Date: Mon, 9 Jul 2012 07:50:25 +0000 (+0800) Subject: add mw100 for rk30 X-Git-Tag: firefly_0821_release~9024 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=edd704202a3cdec35a8482946d69ab6b5dcf2528;p=firefly-linux-kernel-4.4.55.git add mw100 for rk30 --- diff --git a/arch/arm/mach-rk30/board-rk30-sdk.c b/arch/arm/mach-rk30/board-rk30-sdk.c index 9d9e8aabfd09..101361bdc1d1 100755 --- a/arch/arm/mach-rk30/board-rk30-sdk.c +++ b/arch/arm/mach-rk30/board-rk30-sdk.c @@ -54,6 +54,9 @@ #if defined(CONFIG_MU509) #include #endif +#if defined(CONFIG_MW100) +#include +#endif #if defined(CONFIG_ANDROID_TIMED_GPIO) #include "../../../drivers/staging/android/timed_gpio.h" #endif @@ -717,6 +720,38 @@ struct platform_device rk29_device_mu509 = { } }; #endif +#if defined(CONFIG_MW100) +static int mw100_io_init(void) +{ + rk30_mux_api_set(GPIO2B6_LCDC1DATA14_SMCADDR18_TSSYNC_NAME, GPIO2B_GPIO2B6); + rk30_mux_api_set(GPIO4D2_SMCDATA10_TRACEDATA10_NAME, GPIO4D_GPIO4D2); + rk30_mux_api_set(GPIO2B7_LCDC1DATA15_SMCADDR19_HSADCDATA7_NAME, GPIO2B_GPIO2B7); + rk30_mux_api_set(GPIO2C0_LCDCDATA16_GPSCLK_HSADCCLKOUT_NAME, GPIO2C_GPIO2C0); + return 0; +} + +static int mw100_io_deinit(void) +{ + + return 0; +} + +struct rk29_mw100_data rk29_mw100_info = { + .io_init = mw100_io_init, + .io_deinit = mw100_io_deinit, + .bp_power = RK30_PIN2_PB6, + .bp_reset = RK30_PIN4_PD2, + .ap_wakeup_bp = RK30_PIN2_PB7, + .bp_wakeup_ap = RK30_PIN6_PA0, +}; +struct platform_device rk29_device_mw100 = { + .name = "mw100", + .id = -1, + .dev = { + .platform_data = &rk29_mw100_info, + } + }; +#endif /*MMA8452 gsensor*/ #if defined (CONFIG_GS_MMA8452) @@ -1319,6 +1354,9 @@ static struct platform_device *devices[] __initdata = { #if defined(CONFIG_MU509) &rk29_device_mu509, #endif +#if defined(CONFIG_MW100) + &rk29_device_mw100, +#endif #ifdef CONFIG_BATTERY_RK30_ADC &rk30_device_adc_battery, #endif diff --git a/drivers/misc/MW100.c b/drivers/misc/MW100.c deleted file mode 100644 index 98b2c6859fde..000000000000 --- a/drivers/misc/MW100.c +++ /dev/null @@ -1,274 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -MODULE_LICENSE("GPL"); - -//#define DEBUG -#ifdef DEBUG -#define MODEMDBG(x...) printk(x) -#else -#define MODEMDBG(fmt,argss...) -#endif - -#define MW100IO 0XA1 -#define MW_IOCTL_RESET _IO(MW100IO,0X01) - -#define SLEEP 1 -#define READY 0 -#define MU509_RESET 0x01 -static struct wake_lock modem_wakelock; -#define IRQ_BB_WAKEUP_AP_TRIGGER IRQF_TRIGGER_RISING -//#define IRQ_BB_WAKEUP_AP_TRIGGER IRQF_TRIGGER_RISING -struct rk29_mu509_data *gpdata = NULL; -static int bp_wakeup_ap_irq = 0; - - -static void ap_wakeup_bp(struct platform_device *pdev, int wake) -{ - struct rk29_mu509_data *pdata = pdev->dev.platform_data; - MODEMDBG("ap_wakeup_bp\n"); - - gpio_set_value(pdata->ap_wakeup_bp, wake); - -} -extern void rk28_send_wakeup_key(void); - -static void do_wakeup(struct work_struct *work) -{ - MODEMDBG("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__); - rk28_send_wakeup_key(); - enable_irq(bp_wakeup_ap_irq); -} - -static DECLARE_DELAYED_WORK(wakeup_work, do_wakeup); -static irqreturn_t detect_irq_handler(int irq, void *dev_id) -{ - disable_irq_nosync( irq); - printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__); - schedule_delayed_work(&wakeup_work, HZ / 10); - - return IRQ_HANDLED; -} -int modem_poweron_off(int on_off) -{ - struct rk29_mu509_data *pdata = gpdata; - if(on_off) - { - MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__); -/* - gpio_set_value(pdata->bp_power, GPIO_LOW); - msleep(1000); - gpio_set_value(pdata->bp_power, GPIO_HIGH); - msleep(700); - gpio_set_value(pdata->ap_wakeup_bp, GPIO_LOW); -*/ - } - else - { - MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__); -/* - gpio_set_value(pdata->bp_power, GPIO_LOW); - mdelay(2500); - gpio_set_value(pdata->bp_power, GPIO_HIGH); -*/ - } - return 0; -} -static int mu509_open(struct inode *inode, struct file *file) -{ - MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__); - //modem_poweron_off(1); - return 0; -} - -static int mu509_release(struct inode *inode, struct file *file) -{ - MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__); - //modem_poweron_off(0); - return 0; -} - -static int mu509_ioctl(struct inode *inode,struct file *file, unsigned int cmd, unsigned long arg) -{ - struct rk29_mu509_data *pdata = gpdata; - switch(cmd) - { - case MW_IOCTL_RESET: - printk("%s::%d--bruins--ioctl mw100 reset\n",__func__,__LINE__); - gpio_direction_output(pdata->bp_reset,GPIO_LOW); - mdelay(120); - gpio_set_value(pdata->bp_reset, GPIO_HIGH); - - break; - default: - break; - } - return 0; -} - -static struct file_operations mu509_fops = { - .owner = THIS_MODULE, - .open = mu509_open, - .release = mu509_release, - .ioctl = mu509_ioctl -}; - -static struct miscdevice mu509_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "mw100", - .fops = &mu509_fops -}; - -static int mu509_probe(struct platform_device *pdev) -{ - struct rk29_mu509_data *pdata = gpdata = pdev->dev.platform_data; - struct modem_dev *mu509_data = NULL; - int result, irq = 0; - - gpio_request(pdata->bp_power,"bp_power"); - gpio_request(pdata->bp_reset,"bp_reset"); - gpio_request(pdata->bp_wakeup_ap,"bp_wakeup_ap"); - gpio_request(pdata->ap_wakeup_bp,"ap_wakeup_bp"); - - rk29_mux_api_set(GPIO6C76_CPUTRACEDATA76_NAME, GPIO4H_GPIO6C76); - - gpio_direction_output(pdata->bp_reset,GPIO_LOW); - mdelay(120); - gpio_set_value(pdata->bp_reset, GPIO_HIGH); - - gpio_set_value(pdata->ap_wakeup_bp, GPIO_HIGH); - gpio_direction_output(pdata->ap_wakeup_bp,GPIO_HIGH); - - gpio_set_value(pdata->bp_power, GPIO_HIGH); - gpio_direction_output(pdata->bp_power,GPIO_HIGH); - mdelay(120); - gpio_set_value(pdata->bp_power, GPIO_LOW); - gpio_direction_output(pdata->bp_power,GPIO_LOW); - - - //±£Áô -/* gpio_set_value(pdata->bp_reset, GPIO_LOW); - gpio_direction_output(pdata->bp_reset,GPIO_LOW); - mdelay(120); - gpio_set_value(pdata->bp_reset, GPIO_HIGH); - gpio_direction_output(pdata->bp_reset,GPIO_HIGH); -*/ - mu509_data = kzalloc(sizeof(struct modem_dev), GFP_KERNEL); - if(mu509_data == NULL){ - printk("failed to request mu509_data\n"); - goto err2; - } - platform_set_drvdata(pdev, mu509_data); - - gpio_direction_input(pdata->bp_wakeup_ap); - irq = gpio_to_irq(pdata->bp_wakeup_ap); - if(irq < 0){ - gpio_free(pdata->bp_wakeup_ap); - printk("failed to request bp_wakeup_ap\n"); - } - - bp_wakeup_ap_irq = irq; - - result = request_irq(irq, detect_irq_handler, IRQ_BB_WAKEUP_AP_TRIGGER, "bp_wakeup_ap", NULL); - if (result < 0) { - printk("%s: request_irq(%d) failed\n", __func__, irq); - gpio_free(pdata->bp_wakeup_ap); - goto err0; - } - - enable_irq_wake(bp_wakeup_ap_irq); - - result = misc_register(&mu509_misc); - if(result){ - MODEMDBG("misc_register err\n"); - } - return result; -err0: - gpio_free(pdata->bp_wakeup_ap); -err1: - gpio_free(pdata->ap_wakeup_bp); -err2: - kfree(mu509_data); - return 0; -} - -int mu509_suspend(struct platform_device *pdev) -{ - - struct rk29_mu509_data *pdata = pdev->dev.platform_data; - MODEMDBG("%s::%d--\n",__func__,__LINE__); - gpio_set_value(pdata->ap_wakeup_bp, GPIO_LOW); - return 0; -} - -int mu509_resume(struct platform_device *pdev) -{ - struct rk29_mu509_data *pdata = pdev->dev.platform_data; - MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__); - gpio_set_value(pdata->ap_wakeup_bp, GPIO_HIGH); - return 0; -} - -void mu509_shutdown(struct platform_device *pdev, pm_message_t state) -{ - struct rk29_mu509_data *pdata = pdev->dev.platform_data; - struct modem_dev *mu509_data = platform_get_drvdata(pdev); - - MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__); - gpio_set_value(pdata->bp_power, GPIO_HIGH); - mdelay(2010); - - gpio_free(pdata->bp_power); - gpio_free(pdata->bp_reset); - gpio_free(pdata->ap_wakeup_bp); - gpio_free(pdata->bp_wakeup_ap); - kfree(mu509_data); -} - -static struct platform_driver mu509_driver = { - .probe = mu509_probe, - .shutdown = mu509_shutdown, - .suspend = mu509_suspend, - .resume = mu509_resume, - .driver = { - .name = "MW100", - .owner = THIS_MODULE, - }, -}; - -static int __init mu509_init(void) -{ - MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__); - return platform_driver_register(&mu509_driver); -} - -static void __exit mu509_exit(void) -{ - MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__); - platform_driver_unregister(&mu509_driver); -} - -module_init(mu509_init); - -module_exit(mu509_exit); diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index dd3ff0b6fefa..bfb009e4e53b 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -54,7 +54,7 @@ obj-$(CONFIG_SENSORS_AK8975) += akm8975.o obj-$(CONFIG_MTK23D) += mtk23d.o obj-$(CONFIG_FM580X) += fm580x.o obj-$(CONFIG_MU509) += mu509.o -obj-$(CONFIG_MW100) += MW100.o +obj-$(CONFIG_MW100) += mw100.o obj-$(CONFIG_STE) += ste.o obj-$(CONFIG_RK29_SUPPORT_MODEM) += rk29_modem/ obj-$(CONFIG_GPS_GNS7560) += gps/ diff --git a/drivers/misc/mw100.c b/drivers/misc/mw100.c new file mode 100644 index 000000000000..355a6eef89c8 --- /dev/null +++ b/drivers/misc/mw100.c @@ -0,0 +1,281 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +MODULE_LICENSE("GPL"); + +//#define DEBUG +#ifdef DEBUG +#define MODEMDBG(x...) printk(x) +#else +#define MODEMDBG(fmt,argss...) +#endif + +#define MW100IO 0XA1 +#define MW_IOCTL_RESET _IO(MW100IO,0X01) + +#define SLEEP 1 +#define READY 0 +#define MW100_RESET 0x01 +#define IRQ_BB_WAKEUP_AP_TRIGGER IRQF_TRIGGER_RISING +//#define IRQ_BB_WAKEUP_AP_TRIGGER IRQF_TRIGGER_RISING +struct rk29_mw100_data *gpdata = NULL; +static int bp_wakeup_ap_irq = 0; + +static struct wake_lock bp_wakelock; +static bool bpstatus_irq_enable = false; + +#if 0 +static void ap_wakeup_bp(struct platform_device *pdev, int wake) +{ + struct rk29_mw100_data *pdata = pdev->dev.platform_data; + MODEMDBG("ap_wakeup_bp\n"); + + gpio_set_value(pdata->ap_wakeup_bp, wake); +} +#endif + +static void do_wakeup(struct work_struct *work) +{ + MODEMDBG("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__); + enable_irq(bp_wakeup_ap_irq); +} + +static DECLARE_DELAYED_WORK(wakeup_work, do_wakeup); +static irqreturn_t detect_irq_handler(int irq, void *dev_id) +{ + printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__); + wake_lock_timeout(&bp_wakelock, 10 * HZ); + + return IRQ_HANDLED; +} +int modem_poweron_off(int on_off) +{ + if(on_off) + { + MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__); + } + else + { + MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__); + } + return 0; +} + +static int mw100_open(struct inode *inode, struct file *file) +{ + MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__); + //modem_poweron_off(1); + return 0; +} + +static int mw100_release(struct inode *inode, struct file *file) +{ + MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__); + //modem_poweron_off(0); + return 0; +} + +static long mw100_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct rk29_mw100_data *pdata = gpdata; + switch(cmd) + { + case MW_IOCTL_RESET: + printk("%s::%d--bruins--ioctl mw100 reset\n",__func__,__LINE__); + gpio_direction_output(pdata->bp_reset,GPIO_LOW); + mdelay(120); + gpio_set_value(pdata->bp_reset, GPIO_HIGH); + + break; + default: + break; + } + return 0; +} + +static struct file_operations mw100_fops = { + .owner = THIS_MODULE, + .open = mw100_open, + .release = mw100_release, + .unlocked_ioctl = mw100_ioctl +}; + +static struct miscdevice mw100_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "mw100", + .fops = &mw100_fops +}; + +static int mw100_probe(struct platform_device *pdev) +{ + struct rk29_mw100_data *pdata = gpdata = pdev->dev.platform_data; + struct modem_dev *mw100_data = NULL; + int result, irq = 0; + + gpio_request(pdata->bp_power,"bp_power"); + gpio_request(pdata->bp_reset,"bp_reset"); + gpio_request(pdata->bp_wakeup_ap,"bp_wakeup_ap"); + gpio_request(pdata->ap_wakeup_bp,"ap_wakeup_bp"); +#if defined(CONFIG_ARCH_RK29) + rk29_mux_api_set(GPIO6C76_CPUTRACEDATA76_NAME, GPIO4H_GPIO6C76); +#endif + gpio_direction_output(pdata->bp_reset,GPIO_LOW); + mdelay(120); + gpio_set_value(pdata->bp_reset, GPIO_HIGH); + + gpio_set_value(pdata->ap_wakeup_bp, GPIO_HIGH); + gpio_direction_output(pdata->ap_wakeup_bp,GPIO_HIGH); + + gpio_set_value(pdata->bp_power, GPIO_HIGH); + gpio_direction_output(pdata->bp_power,GPIO_HIGH); + mdelay(120); + gpio_set_value(pdata->bp_power, GPIO_LOW); + gpio_direction_output(pdata->bp_power,GPIO_LOW); + + + //±£Áô +/* gpio_set_value(pdata->bp_reset, GPIO_LOW); + gpio_direction_output(pdata->bp_reset,GPIO_LOW); + mdelay(120); + gpio_set_value(pdata->bp_reset, GPIO_HIGH); + gpio_direction_output(pdata->bp_reset,GPIO_HIGH); +*/ + mw100_data = kzalloc(sizeof(struct modem_dev), GFP_KERNEL); + if(mw100_data == NULL){ + printk("failed to request mw100_data\n"); + goto err2; + } + platform_set_drvdata(pdev, mw100_data); + + gpio_direction_input(pdata->bp_wakeup_ap); + irq = gpio_to_irq(pdata->bp_wakeup_ap); + if(irq < 0){ + gpio_free(pdata->bp_wakeup_ap); + printk("failed to request bp_wakeup_ap\n"); + } + + bp_wakeup_ap_irq = irq; + + result = request_irq(irq, detect_irq_handler, IRQ_BB_WAKEUP_AP_TRIGGER, "bp_wakeup_ap", NULL); + if (result < 0) { + printk("%s: request_irq(%d) failed\n", __func__, irq); + gpio_free(pdata->bp_wakeup_ap); + goto err0; + } + + enable_irq_wake(bp_wakeup_ap_irq); + + wake_lock_init(&bp_wakelock, WAKE_LOCK_SUSPEND, "bp_resume"); + + result = misc_register(&mw100_misc); + if(result){ + MODEMDBG("misc_register err\n"); + } + return result; +err0: + gpio_free(pdata->bp_wakeup_ap); +err2: + kfree(mw100_data); + return 0; +} + +int mw100_suspend(struct platform_device *pdev, pm_message_t state) +{ + + struct rk29_mw100_data *pdata = pdev->dev.platform_data; + int irq; + MODEMDBG("%s::%d--\n",__func__,__LINE__); + gpio_set_value(pdata->ap_wakeup_bp, GPIO_LOW); + irq = gpio_to_irq(pdata->bp_wakeup_ap); + if (irq < 0) { + printk("can't get pdata->bp_statue irq \n"); + } + else + { + printk("enable pdata->bp_statue irq_wake!! \n"); + bpstatus_irq_enable = true; + enable_irq_wake(irq); + } + return 0; +} + +int mw100_resume(struct platform_device *pdev) +{ + struct rk29_mw100_data *pdata = pdev->dev.platform_data; + int irq; + MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__); + gpio_set_value(pdata->ap_wakeup_bp, GPIO_HIGH); + irq = gpio_to_irq(pdata->bp_wakeup_ap); + if (irq ) { + printk("enable pdata->bp_statue irq_wake!! \n"); + disable_irq_wake(irq); + bpstatus_irq_enable = false; + } + return 0; +} + +void mw100_shutdown(struct platform_device *pdev) +{ + struct rk29_mw100_data *pdata = pdev->dev.platform_data; + struct modem_dev *mw100_data = platform_get_drvdata(pdev); + + MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__); + gpio_set_value(pdata->bp_power, GPIO_HIGH); + mdelay(2010); + + gpio_free(pdata->bp_power); + gpio_free(pdata->bp_reset); + gpio_free(pdata->ap_wakeup_bp); + gpio_free(pdata->bp_wakeup_ap); + kfree(mw100_data); +} + +static struct platform_driver mw100_driver = { + .probe = mw100_probe, + .shutdown = mw100_shutdown, + .suspend = mw100_suspend, + .resume = mw100_resume, + .driver = { + .name = "mw100", + .owner = THIS_MODULE, + }, +}; + +static int __init mw100_init(void) +{ + MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__); + return platform_driver_register(&mw100_driver); +} + +static void __exit mw100_exit(void) +{ + MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__); + platform_driver_unregister(&mw100_driver); +} + +module_init(mw100_init); + +module_exit(mw100_exit); diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 677c3b9eee75..0fdebd4bf293 100755 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -57,6 +57,10 @@ static struct usb_driver usb_serial_driver = { static int MU509_USB = 0; #define MU509_USB_PORT (SERIAL_TTY_MINORS - 10) #endif +#ifdef CONFIG_MW100 +static int MW100_USB = 0; +#define MW100_USB_PORT (SERIAL_TTY_MINORS - 10) +#endif /* There is no MODULE_DEVICE_TABLE for usbserial.c. Instead the MODULE_DEVICE_TABLE declarations in each serial driver @@ -110,6 +114,10 @@ static struct usb_serial *get_free_serial(struct usb_serial *serial, #ifdef CONFIG_MU509 if (MU509_USB) a= MU509_USB_PORT; +#endif +#ifdef CONFIG_MW100 + if (MW100_USB) + a= MW100_USB_PORT; #endif for (i = a; i < SERIAL_TTY_MINORS; ++i) { if (serial_table[i]) @@ -1073,6 +1081,12 @@ int usb_serial_probe(struct usb_interface *interface, else MU509_USB = 0; #endif +#ifdef CONFIG_MW100 + if ((le16_to_cpu(dev->descriptor.idVendor) == 0x19f5) && (le16_to_cpu(dev->descriptor.idProduct) == 0x9013)) + MW100_USB =1; + else + MW100_USB = 0; +#endif if (get_free_serial(serial, num_ports, &minor) == NULL) { dev_err(&interface->dev, "No more free serial devices\n"); diff --git a/include/linux/mw100.h b/include/linux/mw100.h new file mode 100644 index 000000000000..668fc2f86703 --- /dev/null +++ b/include/linux/mw100.h @@ -0,0 +1,25 @@ +#include +#include +#include + +struct modem_dev +{ + const char *name; + struct miscdevice miscdev; + struct work_struct work; +}; + +struct rk29_mw100_data { + struct device *dev; + int (*io_init)(void); + int (*io_deinit)(void); + unsigned int bp_power; + unsigned int bp_power_active_low; + unsigned int bp_reset; + unsigned int bp_reset_active_low; + unsigned int bp_wakeup_ap; + unsigned int ap_wakeup_bp; + unsigned int modem_power_en; +}; + +#define MODEM_NAME "mw100"