From 7214eed2e0f313e68e1282b2a8da4adf2f6fcd2d Mon Sep 17 00:00:00 2001 From: wlq Date: Wed, 10 Oct 2012 17:48:24 +0800 Subject: [PATCH] add sc6610 modem --- arch/arm/configs/rk2928_phonepad_defconfig | 2 + arch/arm/mach-rk2928/board-rk2928-phonepad.c | 47 ++++ drivers/misc/3g_module/Kconfig | 4 +- drivers/misc/3g_module/Makefile | 1 + drivers/misc/3g_module/sc6610.c | 242 +++++++++++++++++++ drivers/misc/rk2928_callpad_misc/Kconfig | 2 +- include/linux/mu509.h | 3 +- 7 files changed, 297 insertions(+), 4 deletions(-) mode change 100644 => 100755 drivers/misc/3g_module/Kconfig mode change 100644 => 100755 drivers/misc/3g_module/Makefile create mode 100755 drivers/misc/3g_module/sc6610.c mode change 100644 => 100755 include/linux/mu509.h diff --git a/arch/arm/configs/rk2928_phonepad_defconfig b/arch/arm/configs/rk2928_phonepad_defconfig index 2ccaed60cad9..64551a783d2a 100644 --- a/arch/arm/configs/rk2928_phonepad_defconfig +++ b/arch/arm/configs/rk2928_phonepad_defconfig @@ -194,6 +194,8 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_MISC_DEVICES=y CONFIG_UID_STAT=y CONFIG_APANIC=y +CONFIG_3G_MODULE=y +CONFIG_SC6610=y CONFIG_AUDIO_SWITCH=y CONFIG_GPIOEXP_AW9523B=y CONFIG_SCSI=y diff --git a/arch/arm/mach-rk2928/board-rk2928-phonepad.c b/arch/arm/mach-rk2928/board-rk2928-phonepad.c index d78acdef9a19..353ae71ad3f1 100755 --- a/arch/arm/mach-rk2928/board-rk2928-phonepad.c +++ b/arch/arm/mach-rk2928/board-rk2928-phonepad.c @@ -54,6 +54,10 @@ #include "../../../drivers/spi/rk29_spim.h" #endif +#if defined(CONFIG_SC6610) +#include +#endif + #include "board-rk2928-phonepad-camera.c" #include "board-rk2928-phonepad-key.c" @@ -395,9 +399,11 @@ static struct sensor_platform_data mma7660_info = { }; #endif + #if defined (CONFIG_GS_KXTIK) #define KXTIK_INT_PIN RK2928_PIN3_PD1 #if 0 + static int kxtik_init_hw(void) { int ret = 0; @@ -424,6 +430,7 @@ static struct gsensor_platform_data kxtik_pdata = { .exit_platform_hw = kxtik_exit_hw, .orientation = {-1, 0, 0, 0, 0, -1, 0, 1, 0}, }; + #endif static int kxtik_init_platform_hw(void) { @@ -439,6 +446,7 @@ static struct sensor_platform_data kxtik_pdata = { .orientation = {-1, 0, 0, 0, 0, -1, 0, 1, 0}, //.orientation = {0, 1, 0, 0, 0, -1, 1, 0, 0}, }; + #endif /* CONFIG_GS_KXTIK*/ #ifdef CONFIG_INPUT_AP321XX @@ -473,6 +481,7 @@ static struct ap321xx_platform_data ap321xx_info = { }; #endif + #if defined(CONFIG_BATTERY_RK30_ADC)||defined(CONFIG_BATTERY_RK30_ADC_FAC) static struct rk30_adc_battery_platform_data rk30_adc_battery_platdata = { .dc_det_pin = RK2928_PIN1_PA5, @@ -492,6 +501,7 @@ static struct platform_device rk30_device_adc_battery = { }; #endif + #if CONFIG_RK30_PWM_REGULATOR const static int pwm_voltage_map[] = { 1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000, 1400000 @@ -683,6 +693,37 @@ struct rk29_sdmmc_platform_data default_sdmmc1_data = { }; #endif //endif--#ifdef CONFIG_SDMMC1_RK29 +#if defined(CONFIG_SC6610) +static int sc6610_io_init(void) +{ + + return 0; +} + +static int sc6610_io_deinit(void) +{ + + + return 0; +} + +struct rk29_mu509_data rk29_sc6610_info = { + .io_init = sc6610_io_init, + .io_deinit = sc6610_io_deinit, + .bp_power = RK2928_PIN3_PC2,//RK29_PIN0_PB4, + .bp_reset = NULL,//RK29_PIN0_PB3, + .bp_wakeup_ap = RK2928_PIN3_PC3,//RK29_PIN0_PC2, + .ap_wakeup_bp = RK2928_PIN3_PC4,//RK29_PIN0_PB0, + .modem_assert = RK2928_PIN3_PC5, +}; +struct platform_device rk29_device_sc6610 = { + .name = "SC6610", + .id = -1, + .dev = { + .platform_data = &rk29_sc6610_info, + } + }; +#endif #ifdef CONFIG_SND_SOC_RK2928 static struct resource resources_acodec[] = { { @@ -721,8 +762,13 @@ static struct platform_device *devices[] __initdata = { #ifdef CONFIG_SND_SOC_RK2928 &device_acodec, #endif + #if defined(CONFIG_BATTERY_RK30_ADC)||defined(CONFIG_BATTERY_RK30_ADC_FAC) &rk30_device_adc_battery, + +#if defined(CONFIG_SC6610) + &rk29_device_sc6610, + #endif }; //i2c @@ -767,6 +813,7 @@ static struct i2c_board_info __initdata i2c1_info[] = { }, #endif + #if defined (CONFIG_GS_KXTIK) { .type = "gs_kxtik", diff --git a/drivers/misc/3g_module/Kconfig b/drivers/misc/3g_module/Kconfig old mode 100644 new mode 100755 index d702973a2d09..3640e3ccf89d --- a/drivers/misc/3g_module/Kconfig +++ b/drivers/misc/3g_module/Kconfig @@ -25,7 +25,7 @@ choice config MI700 bool "MI700" - - +config SC6610 + bool "SC6610" endchoice diff --git a/drivers/misc/3g_module/Makefile b/drivers/misc/3g_module/Makefile old mode 100644 new mode 100755 index 768a2d535124..81907e0d4d40 --- a/drivers/misc/3g_module/Makefile +++ b/drivers/misc/3g_module/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_MW100) += mw100.o obj-$(CONFIG_MT6229) += mt6229.o obj-$(CONFIG_SEW868) += sew868.o obj-$(CONFIG_MI700) += mi700.o +obj-$(CONFIG_SC6610) += sc6610.o \ No newline at end of file diff --git a/drivers/misc/3g_module/sc6610.c b/drivers/misc/3g_module/sc6610.c new file mode 100755 index 000000000000..ec84c0d1c4b6 --- /dev/null +++ b/drivers/misc/3g_module/sc6610.c @@ -0,0 +1,242 @@ +#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 1 +#ifdef DEBUG +#define MODEMDBG(x...) printk(x) +#else +#define MODEMDBG(fmt,argss...) +#endif +#define MODEM_RESET 2 +#define MODEM_ON 1 +#define MODEM_OFF 0 +struct rk29_mu509_data *s_gpdata = NULL; +struct class *modem_class = NULL; +static int do_wakeup_irq = 0; +static struct wake_lock modem_wakelock; +#define IRQ_BB_WAKEUP_AP_TRIGGER IRQF_TRIGGER_FALLING +int modem_poweron_off(int on_off) +{ + struct rk29_mu509_data *pdata = s_gpdata; + if(on_off){ + MODEMDBG("------------modem_poweron usb\n"); + gpio_set_value(pdata->bp_power, GPIO_HIGH); + + }else{ + MODEMDBG("------------modem_poweroff usb\n"); + //gpio_set_value(pdata->bp_power, GPIO_LOW); + } + return 0; +} + +static irqreturn_t detect_irq_handler(int irq, void *dev_id) +{ + if(do_wakeup_irq) + { + do_wakeup_irq = 0; + + // MODEMDBG("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__); + wake_lock_timeout(&modem_wakelock, 10 * HZ); + //schedule_delayed_work(&wakeup_work, 2*HZ); + } + return IRQ_HANDLED; +} +static int sc6610_open(struct inode *inode, struct file *file) +{ + //MODEMDBG("------sc6610_open-------%s\n",__FUNCTION__); + struct rk29_mu509_data *pdata = s_gpdata; + //device_init_wakeup(pdata->dev, 1); + modem_poweron_off(MODEM_ON); + return 0; +} + +static int sc6610_release(struct inode *inode, struct file *file) +{ + //MODEMDBG("-------------%s\n",__FUNCTION__); + modem_poweron_off(MODEM_OFF); + return 0; +} + +static long sc6610_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct rk29_mu509_data *pdata = s_gpdata; + switch(cmd) + { + case MODEM_RESET: + gpio_set_value(pdata->bp_reset, GPIO_LOW); + msleep(2000); + gpio_set_value(pdata->bp_reset, GPIO_HIGH); + break; + case MODEM_ON: + modem_poweron_off(MODEM_ON); + break; + case MODEM_OFF: + modem_poweron_off(MODEM_OFF); + break; + default: + break; + } + return 0; +} + +static struct file_operations sc6610_fops = { + .owner = THIS_MODULE, + .open = sc6610_open, + .release = sc6610_release, + .unlocked_ioctl = sc6610_ioctl +}; + +static struct miscdevice sc6610_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = MODEM_NAME, + .fops = &sc6610_fops +}; + +static int sc6610_probe(struct platform_device *pdev) +{ + struct rk29_mu509_data *pdata = s_gpdata = pdev->dev.platform_data; + struct modem_dev *sc6610_data = NULL; + int result; + int irq; + pdata->dev = &pdev->dev; + printk("%s, sc6610 new \n", __FUNCTION__); + //rk30_mux_api_set(GPIO1C1_UART0RTSN_SDMMC1WRITEPRT_NAME, GPIO1H_GPIO1C1); + + if(pdata->io_init) + pdata->io_init(); + result = gpio_request(pdata->ap_wakeup_bp, "sc6610"); + if (result) { + printk("failed to request AP_BP_WAKEUP gpio\n"); + goto err; + } + result = gpio_request(pdata->bp_power, "sc6610"); + if (result) { + printk("failed to request bp_power gpio\n"); + goto err1; + } + result = gpio_request(pdata->bp_wakeup_ap, "sc6610"); + if (result) { + printk("failed to request modem_power_en gpio\n"); + goto err2; + } + + + gpio_set_value(pdata->ap_wakeup_bp, 0); + + irq = gpio_to_irq(pdata->bp_wakeup_ap); + + 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 err4; + } + enable_irq_wake(irq); + wake_lock_init(&modem_wakelock, WAKE_LOCK_SUSPEND, "bp_wakeup_ap"); + sc6610_data = kzalloc(sizeof(struct modem_dev), GFP_KERNEL); + if(sc6610_data == NULL) + { + printk("failed to request sc6610_data\n"); + goto err; + } + platform_set_drvdata(pdev, sc6610_data); + result = misc_register(&sc6610_misc); + if(result) + { + printk("misc_register err\n"); + } + modem_poweron_off(MODEM_ON); + printk("<----sc6610 prope ok----->\n"); + return result; + +err4: + gpio_free(pdata->bp_wakeup_ap); +err2: + gpio_free(pdata->bp_power); +err1: + gpio_free(pdata->ap_wakeup_bp); +err: + kfree(sc6610_data); + return 0; +} + +int c6310_suspend(struct platform_device *pdev, pm_message_t state) +{ + //struct rk29_mu509_data *pdata = pdev->dev.platform_data; + do_wakeup_irq = 1; + //gpio_set_value(pdata->ap_statue, GPIO_HIGH); + return 0; +} + +int c6310_resume(struct platform_device *pdev) +{ + //struct rk29_mu509_data *pdata = pdev->dev.platform_data; + //gpio_set_value(pdata->ap_statue, GPIO_LOW); + return 0; +} + +void c6310_shutdown(struct platform_device *pdev) +{ + struct rk29_mu509_data *pdata = pdev->dev.platform_data; + struct modem_dev *sc6610_data = platform_get_drvdata(pdev); + modem_poweron_off(0); + if(pdata->io_deinit) + pdata->io_deinit(); + cancel_work_sync(&sc6610_data->work); + gpio_free(pdata->bp_power); + gpio_free(pdata->bp_reset); + gpio_free(pdata->ap_wakeup_bp); + gpio_free(pdata->bp_wakeup_ap); + kfree(sc6610_data); +} + +static struct platform_driver sc6610_driver = { + .probe = sc6610_probe, + .shutdown = c6310_shutdown, + .suspend = c6310_suspend, + .resume = c6310_resume, + .driver = { + .name = "SC6610", + .owner = THIS_MODULE, + }, +}; + +static int __init sc6610_init(void) +{ + + return platform_driver_register(&sc6610_driver); +} + +static void __exit sc6610_exit(void) +{ + platform_driver_unregister(&sc6610_driver); + +} + +module_init(sc6610_init); + +module_exit(sc6610_exit); diff --git a/drivers/misc/rk2928_callpad_misc/Kconfig b/drivers/misc/rk2928_callpad_misc/Kconfig index d11316f34634..f53da3432c14 100755 --- a/drivers/misc/rk2928_callpad_misc/Kconfig +++ b/drivers/misc/rk2928_callpad_misc/Kconfig @@ -3,7 +3,7 @@ # menuconfig RK2928_CALLPAD_MISC - tristate "3G module for phonepad" + tristate "3G module audio for phonepad" ---help--- Say Y here if you have a support modem diff --git a/include/linux/mu509.h b/include/linux/mu509.h old mode 100644 new mode 100755 index 431461037f96..3d40aa26438d --- a/include/linux/mu509.h +++ b/include/linux/mu509.h @@ -21,6 +21,7 @@ struct rk29_mu509_data { unsigned int bp_wakeup_ap; unsigned int ap_wakeup_bp; unsigned int modem_power_en; + unsigned int modem_assert; }; -#define MODEM_NAME "mu509" +#define MODEM_NAME "SC6610" -- 2.34.1