From 2489007e7d740ccbc3e0a202914e243ad5178787 Mon Sep 17 00:00:00 2001 From: codeworkx Date: Sat, 22 Sep 2012 09:48:20 +0200 Subject: merge opensource jb u5 Change-Id: I1aaec157aa196f3448eff8636134fce89a814cf2 --- .../misc/modem_if/modem_modemctl_device_cmc221.c | 84 ++++++++++++++-------- 1 file changed, 55 insertions(+), 29 deletions(-) (limited to 'drivers/misc/modem_if/modem_modemctl_device_cmc221.c') diff --git a/drivers/misc/modem_if/modem_modemctl_device_cmc221.c b/drivers/misc/modem_if/modem_modemctl_device_cmc221.c index 2d564e9..fe8ce69 100644 --- a/drivers/misc/modem_if/modem_modemctl_device_cmc221.c +++ b/drivers/misc/modem_if/modem_modemctl_device_cmc221.c @@ -30,9 +30,9 @@ #define PIF_TIMEOUT (180 * HZ) #define DPRAM_INIT_TIMEOUT (30 * HZ) - static void mc_state_fsm(struct modem_ctl *mc) { + struct link_device *ld = get_current_link(mc->iod); int cp_on = gpio_get_value(mc->gpio_cp_on); int cp_reset = gpio_get_value(mc->gpio_cp_reset); int cp_active = gpio_get_value(mc->gpio_phone_active); @@ -46,6 +46,7 @@ static void mc_state_fsm(struct modem_ctl *mc) if (!cp_on) { gpio_set_value(mc->gpio_cp_reset, 0); new_state = STATE_OFFLINE; + ld->mode = LINK_MODE_OFFLINE; mif_err("%s: new_state = PHONE_PWR_OFF\n", mc->name); } else if (old_state == STATE_ONLINE) { new_state = STATE_CRASH_EXIT; @@ -55,7 +56,6 @@ static void mc_state_fsm(struct modem_ctl *mc) } } -exit: if (old_state != new_state) { mc->bootd->modem_state_changed(mc->bootd, new_state); mc->iod->modem_state_changed(mc->iod, new_state); @@ -73,37 +73,53 @@ static irqreturn_t phone_active_handler(int irq, void *arg) return IRQ_HANDLED; } +/* TX dynamic switching between DPRAM and USB in one modem */ static irqreturn_t dynamic_switching_handler(int irq, void *arg) { struct modem_ctl *mc = (struct modem_ctl *)arg; int txpath = gpio_get_value(mc->gpio_dynamic_switching); + bool enumerated = usb_is_enumerated(mc->msd); + + mif_err("txpath=%d, enumeration=%d\n", txpath, enumerated); + + /* do not switch to USB, when USB is not enumerated. */ + if (!enumerated && txpath) { + mc->need_switch_to_usb = true; + return IRQ_HANDLED; + } - rawdevs_set_tx_link(&mc->commons, txpath ? LINKDEV_USB : LINKDEV_DPRAM); + mc->need_switch_to_usb = false; + rawdevs_set_tx_link(mc->msd, txpath ? LINKDEV_USB : LINKDEV_DPRAM); return IRQ_HANDLED; } static int cmc221_on(struct modem_ctl *mc) { - struct link_device *ld = get_current_link(mc->bootd); + struct link_device *ld = get_current_link(mc->iod); + + if (!wake_lock_active(&mc->mc_wake_lock)) + wake_lock(&mc->mc_wake_lock); + set_sromc_access(true); + + mc->phone_state = STATE_OFFLINE; + ld->mode = LINK_MODE_OFFLINE; - mif_err("%s\n", mc->bootd->name); + mif_err("%s\n", mc->name); disable_irq_nosync(mc->irq_phone_active); - gpio_set_value(mc->gpio_cp_reset, 0); gpio_set_value(mc->gpio_cp_on, 0); + msleep(100); + gpio_set_value(mc->gpio_cp_reset, 0); msleep(500); gpio_set_value(mc->gpio_cp_on, 1); - msleep(100); gpio_set_value(mc->gpio_cp_reset, 1); - mc->phone_state = STATE_OFFLINE; - return 0; } @@ -111,13 +127,14 @@ static int cmc221_off(struct modem_ctl *mc) { int cp_on = gpio_get_value(mc->gpio_cp_on); + mif_err("%s\n", mc->name); + if (mc->phone_state == STATE_OFFLINE || cp_on == 0) return 0; - mif_err("%s\n", mc->bootd->name); - - if (mc->log_fp) - mif_close_log_file(mc); + if (!wake_lock_active(&mc->mc_wake_lock)) + wake_lock(&mc->mc_wake_lock); + set_sromc_access(true); gpio_set_value(mc->gpio_cp_on, 0); @@ -128,7 +145,7 @@ static int cmc221_force_crash_exit(struct modem_ctl *mc) { struct link_device *ld = get_current_link(mc->bootd); - mif_err("%s\n", mc->bootd->name); + mif_err("%s\n", mc->name); /* Make DUMP start */ ld->force_dump(ld, mc->bootd); @@ -138,10 +155,11 @@ static int cmc221_force_crash_exit(struct modem_ctl *mc) static int cmc221_dump_reset(struct modem_ctl *mc) { - mif_err("%s\n", mc->bootd->name); + mif_err("%s\n", mc->name); - if (mc->log_fp) - mif_close_log_file(mc); + if (!wake_lock_active(&mc->mc_wake_lock)) + wake_lock(&mc->mc_wake_lock); + set_sromc_access(true); gpio_set_value(mc->gpio_host_active, 0); gpio_set_value(mc->gpio_cp_reset, 0); @@ -157,7 +175,7 @@ static int cmc221_dump_reset(struct modem_ctl *mc) static int cmc221_reset(struct modem_ctl *mc) { - mif_err("%s\n", mc->bootd->name); + mif_err("%s\n", mc->name); if (cmc221_off(mc)) return -ENXIO; @@ -172,13 +190,13 @@ static int cmc221_reset(struct modem_ctl *mc) static int cmc221_boot_on(struct modem_ctl *mc) { - mif_err("%s\n", mc->bootd->name); + mif_err("%s\n", mc->name); + + gpio_set_value(mc->gpio_pda_active, 1); mc->bootd->modem_state_changed(mc->bootd, STATE_BOOTING); mc->iod->modem_state_changed(mc->iod, STATE_BOOTING); - mif_set_log_level(mc); - return 0; } @@ -188,7 +206,7 @@ static int cmc221_boot_off(struct modem_ctl *mc) struct link_device *ld = get_current_link(mc->bootd); struct dpram_link_device *dpld = to_dpram_link_device(ld); - mif_err("%s\n", mc->bootd->name); + mif_err("%s\n", mc->name); ret = wait_for_completion_interruptible_timeout(&dpld->dpram_init_cmd, DPRAM_INIT_TIMEOUT); @@ -198,14 +216,18 @@ static int cmc221_boot_off(struct modem_ctl *mc) return -ENXIO; } - if (!mc->fs_ready) - mc->fs_ready = true; + enable_irq(mc->irq_phone_active); - if (mc->use_mif_log && mc->log_level && !mc->fs_failed && - mc->fs_ready && !mc->log_fp) - mif_open_log_file(mc); + return 0; +} - enable_irq(mc->irq_phone_active); +static int cmc221_boot_done(struct modem_ctl *mc) +{ + mif_err("%s\n", mc->name); + + set_sromc_access(false); + if (wake_lock_active(&mc->mc_wake_lock)) + wake_unlock(&mc->mc_wake_lock); return 0; } @@ -217,6 +239,7 @@ static void cmc221_get_ops(struct modem_ctl *mc) mc->ops.modem_reset = cmc221_reset; mc->ops.modem_boot_on = cmc221_boot_on; mc->ops.modem_boot_off = cmc221_boot_off; + mc->ops.modem_boot_done = cmc221_boot_done; mc->ops.modem_force_crash_exit = cmc221_force_crash_exit; mc->ops.modem_dump_reset = cmc221_dump_reset; } @@ -231,8 +254,8 @@ int cmc221_init_modemctl_device(struct modem_ctl *mc, struct modem_data *pdata) mc->gpio_cp_on = pdata->gpio_cp_on; mc->gpio_cp_reset = pdata->gpio_cp_reset; mc->gpio_phone_active = pdata->gpio_phone_active; -#if 0 /*TODO: check the GPIO map*/ mc->gpio_pda_active = pdata->gpio_pda_active; +#if 0 /*TODO: check the GPIO map*/ mc->gpio_cp_dump_int = pdata->gpio_cp_dump_int; mc->gpio_flm_uart_sel = pdata->gpio_flm_uart_sel; mc->gpio_slave_wakeup = pdata->gpio_slave_wakeup; @@ -240,6 +263,7 @@ int cmc221_init_modemctl_device(struct modem_ctl *mc, struct modem_data *pdata) mc->gpio_host_wakeup = pdata->gpio_host_wakeup; #endif mc->gpio_dynamic_switching = pdata->gpio_dynamic_switching; + mc->need_switch_to_usb = false; if (!mc->gpio_cp_on || !mc->gpio_cp_reset || !mc->gpio_phone_active) { mif_err("%s: ERR! no GPIO data\n", mc->name); @@ -260,6 +284,8 @@ int cmc221_init_modemctl_device(struct modem_ctl *mc, struct modem_data *pdata) } mif_err("%s: PHONE_ACTIVE IRQ# = %d\n", mc->name, mc->irq_phone_active); + wake_lock_init(&mc->mc_wake_lock, WAKE_LOCK_SUSPEND, "cmc_wake_lock"); + flag = IRQF_TRIGGER_FALLING | IRQF_NO_SUSPEND; irq = mc->irq_phone_active; ret = request_irq(irq, phone_active_handler, flag, "cmc_active", mc); -- cgit v1.1