static void charge_current_set(int cable_type)
{
	static struct regulator *regulator;
	int ret;

	if (regulator == NULL) {
		regulator = regulator_get(NULL, "vinchg1");
		if (IS_ERR_OR_NULL(regulator)) {
			pr_err("%s : falied to get regulator\n", __func__);
			regulator = NULL;
			goto out;
		}
	}

	switch (cable_type) {
	case CABLE_TYPE_USB:
		ret = regulator_set_current_limit(regulator, CURRENT_USB,
			CURRENT_USB + 25000);
		break;
	case CABLE_TYPE_TA:
		ret = regulator_set_current_limit(regulator, CURRENT_TA,
			CURRENT_TA + 25000);
		break;
	default:
		pr_err("%s : unsupported type of cable\n", __func__);
	}

	if (ret < 0)
		pr_err("%s : failed to set current limit\n", __func__);

out:
	return;
}
Example #2
0
/* interface to regulator framework */
static void nop_set_vbus_draw(struct usb_phy_generic *nop, unsigned mA)
{
	struct regulator *vbus_draw = nop->vbus_draw;
	int enabled;
	int ret;

	if (!vbus_draw)
		return;

	enabled = nop->vbus_draw_enabled;
	if (mA) {
		regulator_set_current_limit(vbus_draw, 0, 1000 * mA);
		if (!enabled) {
			ret = regulator_enable(vbus_draw);
			if (ret < 0)
				return;
			nop->vbus_draw_enabled = 1;
		}
	} else {
		if (enabled) {
			ret = regulator_disable(vbus_draw);
			if (ret < 0)
				return;
			nop->vbus_draw_enabled = 0;
		}
	}
	nop->mA = mA;
}
/* interface to regulator framework */
static void set_vbus_draw(struct gpio_vbus_data *gpio_vbus, unsigned mA)
{
	struct regulator *vbus_draw = gpio_vbus->vbus_draw;
	int enabled;
	int ret;

	if (!vbus_draw)
		return;

	enabled = gpio_vbus->vbus_draw_enabled;
	if (mA) {
		regulator_set_current_limit(vbus_draw, 0, 1000 * mA);
		if (!enabled) {
			ret = regulator_enable(vbus_draw);
			if (ret < 0)
				return;
			gpio_vbus->vbus_draw_enabled = 1;
		}
	} else {
		if (enabled) {
			ret = regulator_disable(vbus_draw);
			if (ret < 0)
				return;
			gpio_vbus->vbus_draw_enabled = 0;
		}
	}
	gpio_vbus->mA = mA;
}
Example #4
0
static void led_work(struct work_struct *work)
{
	struct wm8350_led *led = container_of(work, struct wm8350_led, work);
	int ret;
	int uA;
	unsigned long flags;

	mutex_lock(&led->mutex);

	spin_lock_irqsave(&led->value_lock, flags);

	if (led->value == LED_OFF) {
		spin_unlock_irqrestore(&led->value_lock, flags);
		wm8350_led_disable(led);
		goto out;
	}

	
	uA = (led->max_uA_index * led->value) / LED_FULL;
	spin_unlock_irqrestore(&led->value_lock, flags);
	BUG_ON(uA >= ARRAY_SIZE(isink_cur));

	ret = regulator_set_current_limit(led->isink, isink_cur[uA],
					  isink_cur[uA]);
	if (ret != 0)
		dev_err(led->cdev.dev, "Failed to set %duA: %d\n",
			isink_cur[uA], ret);

	wm8350_led_enable(led);

out:
	mutex_unlock(&led->mutex);
}
Example #5
0
static void update_current_limit_constraints(struct virtual_consumer_data
						*data)
{
	int ret;

	if (data->max_uA
	    && data->min_uA <= data->max_uA) {
		ret = regulator_set_current_limit(data->regulator,
					data->min_uA, data->max_uA);
		if (ret != 0) {
			pr_err("regulator_set_current_limit() failed: %d\n",
			       ret);
			return;
		}
	}

	if (data->max_uA && !data->enabled) {
		ret = regulator_enable(data->regulator);
		if (ret == 0)
			data->enabled = 1;
		else
			printk(KERN_ERR "regulator_enable() failed: %d\n",
				ret);
	}

	if (!(data->min_uA && data->max_uA) && data->enabled) {
		ret = regulator_disable(data->regulator);
		if (ret == 0)
			data->enabled = 0;
		else
			printk(KERN_ERR "regulator_disable() failed: %d\n",
				ret);
	}
}
Example #6
0
static int max77665_charger_types(struct max77665_charger *charger)
{
#define MA_TO_UA 1000
	enum cable_status_t cable_status = charger->cable_status;
	int chgin_ilim = 0;
	int ret;

	switch (cable_status) {
	case CABLE_TYPE_USB:	//USB input current 500mA
		chgin_ilim = charger->chgin_ilim_usb *MA_TO_UA;
		break;
	case CABLE_TYPE_AC:	//AC input current 1200mA
		chgin_ilim = charger->chgin_ilim_ac * MA_TO_UA;
		break;
	default:
		chgin_ilim = 0;
		break;
	}

	if (chgin_ilim) {
		/* set ilim cur */
		ret = regulator_set_current_limit(charger->ps, chgin_ilim, MAX_AC_CURRENT*MA_TO_UA);
		if (ret) {
			pr_err("failed to set current limit\n");
			return ret;
		}

	}

	if(delayed_work_pending(&charger->poll_dwork))
		cancel_delayed_work(&charger->poll_dwork);
	schedule_delayed_work_on(0, &charger->poll_dwork, 0);

	return 0;
}
static void update_charger(void)
{
	static int regulator_enabled;
	int max_uA = pdata->ac_max_uA;

	if (pdata->set_charge) {
		if (new_ac_status > 0) {
			dev_dbg(dev, "charger on (AC)\n");
			pdata->set_charge(PDA_POWER_CHARGE_AC);
		} else if (new_usb_status > 0) {
			dev_dbg(dev, "charger on (USB)\n");
			pdata->set_charge(PDA_POWER_CHARGE_USB);
		} else {
			dev_dbg(dev, "charger off\n");
			pdata->set_charge(0);
		}
	} else if (ac_draw) {
		if (new_ac_status > 0) {
			regulator_set_current_limit(ac_draw, max_uA, max_uA);
			if (!regulator_enabled) {
				dev_dbg(dev, "charger on (AC)\n");
				regulator_enable(ac_draw);
				regulator_enabled = 1;
			}
		} else {
			if (regulator_enabled) {
				dev_dbg(dev, "charger off\n");
				regulator_disable(ac_draw);
				regulator_enabled = 0;
			}
		}
	}
}
Example #8
0
static void regulator_led_set_value(struct regulator_led *led)
{
	int voltage;
	int ret;
	struct regulator *movie;

	mutex_lock(&led->mutex);

	if(led->cdev.flags & LED_SUSPENDED)
		goto out;
 
	if (led->value == LED_OFF) {
		regulator_led_disable(led);
		goto out;
	}

	movie = regulator_get(NULL, "led_movie");
	if(IS_ERR(movie)) {
		pr_err("%s: led_movie is failed.\n", __func__);
		goto out;
	}

	if (regulator_is_enabled(movie) > 0) {
		pr_info("%s: led_movie is enabled.\n", __func__);
		goto end;
	}

#if 0 //TODO
	if (led->cdev.max_brightness > 1) {
		voltage = led_regulator_get_voltage(led->vcc, led->value);
		dev_dbg(led->cdev.dev, "brightness: %d voltage: %d\n",
				led->value, voltage);

		ret = regulator_set_voltage(led->vcc, voltage, voltage);
		if (ret != 0)
			dev_err(led->cdev.dev, "Failed to set voltage %d: %d\n",
				voltage, ret);
	}
#endif

	regulator_set_current_limit(led->vcc, 90000, 110000);
	regulator_led_enable(led);

end:
	regulator_put(movie);

out:
	mutex_unlock(&led->mutex);
}
Example #9
0
static int bc_sm_restart(struct stmp3xxx_info *info)
{
	ddi_bc_Status_t bcret;
	int ret = 0;

	mutex_lock(&info->sm_lock);

	/* ungate power clk */
	ddi_power_SetPowerClkGate(0);

	/*
	 * config battery charger state machine and move it to the Disabled
	 * state. This must be done before starting the state machine.
	 */
	bcret = ddi_bc_Init(info->sm_cfg);
	if (bcret != DDI_BC_STATUS_SUCCESS) {
		dev_err(info->dev, "battery charger init failed: %d\n", bcret);
		ret = -EIO;
		goto out;
	} else {

		if (!info->regulator) {
			info->regulator = regulator_get(NULL, "charger-1");
			if (!info->regulator || IS_ERR(info->regulator)) {
				dev_err(info->dev,
				"%s: failed to get regulator\n", __func__);
				info->regulator = NULL;
			} else {
				regulator_set_current_limit(
						info->regulator, 0, 0);
				regulator_set_mode(info->regulator,
						   REGULATOR_MODE_FAST);
			}
		}
	}



	/* schedule first call to state machine */
	mod_timer(&info->sm_timer, jiffies + 1);
out:
	mutex_unlock(&info->sm_lock);
	return ret;
}
static ssize_t pt_val_set(struct device *d, struct device_attribute *attr,
					const char *buf, size_t size)
{
	int i, ret;
	REG_GET();

	ret = sscanf(buf, "%u", &i);
	if (ret != 1)
		return -EINVAL;

	mutex_lock(&run_mutex);
	if (!regulator_set_current_limit(reg, i, i)) {
		mod_timer(&pt_timer,
			  jiffies + msecs_to_jiffies(timer_delay));
		return size;
	} else {
		mutex_unlock(&run_mutex);
		return -EPERM;
	}

}
static void update_current_limit_constraints(struct device *dev,
					  struct virtual_consumer_data *data)
{
	int ret;

	if (data->max_uA
	    && data->min_uA <= data->max_uA) {
		dev_dbg(dev, "Requesting %d-%duA\n",
			data->min_uA, data->max_uA);
		ret = regulator_set_current_limit(data->regulator,
					data->min_uA, data->max_uA);
		if (ret != 0) {
			dev_err(dev,
				"regulator_set_current_limit() failed: %d\n",
				ret);
			return;
		}
	}

	if (data->max_uA && !data->enabled) {
		dev_dbg(dev, "Enabling regulator\n");
		ret = regulator_enable(data->regulator);
		if (ret == 0)
			data->enabled = true;
		else
			dev_err(dev, "regulator_enable() failed: %d\n",
				ret);
	}

	if (!(data->min_uA && data->max_uA) && data->enabled) {
		dev_dbg(dev, "Disabling regulator\n");
		ret = regulator_disable(data->regulator);
		if (ret == 0)
			data->enabled = false;
		else
			dev_err(dev, "regulator_disable() failed: %d\n",
				ret);
	}
}
static ssize_t pt_val_fset(struct device *d, struct device_attribute *attr,
					const char *buf, size_t size)
{
	int i, ret;
	ret = sscanf(buf, "%u", &i);
	if (ret != 1)
		return -EINVAL;

	if (!freg) {
		freg = regulator_get(NULL, "stmp3xxx-bl-1");
		if (!freg || IS_ERR(freg)) {
			freg = NULL ; return -ENODEV;
		}
	}
	regulator_set_mode(freg, REGULATOR_MODE_NORMAL);

	if (!regulator_set_current_limit(freg, i, i))
		printk(KERN_ERR "got backlight reg\n");
	else
		printk(KERN_ERR "failed to get backlight reg");

	return size;
}
Example #13
0
static int set_bl_intensity(struct mxs_platform_bl_data *data,
			    struct backlight_device *bd, int suspended)
{
	int intensity = bd->props.brightness;
	int scaled_int;

	if (bd->props.power != FB_BLANK_UNBLANK)
		intensity = 0;
	if (bd->props.fb_blank != FB_BLANK_UNBLANK)
		intensity = 0;
	if (suspended)
		intensity = 0;

	/*
	 * This is not too cool but what can we do?
	 * Luminance changes non-linearly...
	 */
	if (regulator_set_current_limit
	    (data->regulator, bl_to_power(intensity), bl_to_power(intensity)))
		return -EBUSY;

	scaled_int = values[intensity / 10];
	if (scaled_int < 100) {
		int rem = intensity - 10 * (intensity / 10);	/* r = i % 10; */
		scaled_int += rem * (values[intensity / 10 + 1] -
				     values[intensity / 10]) / 10;
	}
	__raw_writel(BF_PWM_ACTIVEn_INACTIVE(scaled_int) |
		     BF_PWM_ACTIVEn_ACTIVE(0),
		     REGS_PWM_BASE + HW_PWM_ACTIVEn(2));
	__raw_writel(BF_PWM_PERIODn_CDIV(6) |	/* divide by 64 */
		     BF_PWM_PERIODn_INACTIVE_STATE(2) |	/* low */
		     BF_PWM_PERIODn_ACTIVE_STATE(3) |	/* high */
		     BF_PWM_PERIODn_PERIOD(399),
		     REGS_PWM_BASE + HW_PWM_PERIODn(2));
	return 0;
}
Example #14
0
static void led_work(struct work_struct *work)
{
	struct wm8350_led *led = container_of(work, struct wm8350_led, work);
	int ret;
	int uA;
	unsigned long flags;

	mutex_lock(&led->mutex);

	spin_lock_irqsave(&led->value_lock, flags);

	if (led->value == LED_OFF) {
		spin_unlock_irqrestore(&led->value_lock, flags);
		wm8350_led_disable(led);
		goto out;
	}

	/* This scales linearly into the index of valid current
	 * settings which results in a linear scaling of perceived
	 * brightness due to the non-linear current settings provided
	 * by the hardware.
	 */
	uA = (led->max_uA_index * led->value) / LED_FULL;
	spin_unlock_irqrestore(&led->value_lock, flags);
	BUG_ON(uA >= ARRAY_SIZE(isink_cur));

	ret = regulator_set_current_limit(led->isink, isink_cur[uA],
					  isink_cur[uA]);
	if (ret != 0)
		dev_err(led->cdev.dev, "Failed to set %duA: %d\n",
			isink_cur[uA], ret);

	wm8350_led_enable(led);

out:
	mutex_unlock(&led->mutex);
}
int vcc_cmds_tx(struct platform_device *pdev, struct vcc_desc *cmds, int cnt)
{
    int ret = 0;
    struct vcc_desc *cm = NULL;
    int i = 0;

    cm = cmds;

    for (i = 0; i < cnt; i++) {
        if ((cm == NULL) || (cm->id == NULL)) {
            balongfb_loge("cm or cm->id is null! index=%d\n", i);
            ret = -1;
            goto error;
        }

        if (cm->dtype == DTYPE_VCC_GET) {
            BUG_ON(pdev == NULL);

            *(cm->regulator) = regulator_get(&pdev->dev, cm->id);
            if (IS_ERR(*(cm->regulator))) {
                balongfb_loge("failed to get %s regulator!\n", cm->id);
                ret = -1;
                goto error;
            }
        } else if (cm->dtype == DTYPE_VCC_PUT) {
            if (!IS_ERR(*(cm->regulator))) {
                regulator_put(*(cm->regulator));
            }
        } else if (cm->dtype == DTYPE_VCC_ENABLE) {
            if (!IS_ERR(*(cm->regulator))) {
                if (regulator_enable(*(cm->regulator)) != 0) {
                    balongfb_loge("failed to enable %s regulator!\n", cm->id);
                    ret = -1;
                    goto error;
                }
            }
        } else if (cm->dtype == DTYPE_VCC_DISABLE) {
            if (!IS_ERR(*(cm->regulator))) {
                if (regulator_disable(*(cm->regulator)) != 0) {
                    balongfb_loge("failed to disable %s regulator!\n", cm->id);
                    ret = -1;
                    goto error;
                }
            }
        } else if (cm->dtype == DTYPE_VCC_SET_VOLTAGE) {
            if (!IS_ERR(*(cm->regulator))) {
                if (regulator_set_voltage(*(cm->regulator), cm->min_uV, cm->max_uV) != 0) {
                    balongfb_loge("failed to set %s regulator voltage!\n", cm->id);
                    ret = -1;
                    goto error;
                }
            }
        } else if (cm->dtype == DTYPE_VCC_SET_CURRENT) {
            if (!IS_ERR(*(cm->regulator))) {
                if (regulator_set_current_limit(*(cm->regulator), cm->min_uA, cm->max_uA) != 0) {
                    balongfb_loge("failed to set %s regulator current!\n", cm->id);
                    ret = -1;
                    goto error;
                }
            }
        } else {
            balongfb_loge("dtype=%x NOT supported\n", cm->dtype);
            ret = -1;
            goto error;
        }

        if (cm->wait) {
            if (cm->waittype == WAIT_TYPE_US)
                udelay(cm->wait);
            else if (cm->waittype == WAIT_TYPE_MS)
                mdelay(cm->wait);
            else
                mdelay(cm->wait * 1000);
        }

        cm++;
    }

    return 0;

error:
    return ret;
}
static int hw_scharger_flash_mode(struct hw_flash_ctrl_t *flash_ctrl, int data)
{
    struct hw_scharger_private_data_t *pdata;
    int ret = 0;

    cam_debug("%s data=%d.\n", __func__, data);

    if (NULL == flash_ctrl) {
        cam_err("%s flash_ctrl is NULL.", __func__);
        return -1;
    }

    pdata = (struct hw_scharger_private_data_t *)flash_ctrl->pdata;

    if (data >= pdata->flash_led_num) {
        cam_err("Unsupport flash_lum_level: %d", data);
        return -1;
    }

    if ((NULL == pdata->flash_inter_ldo) || (NULL == pdata->flash_mode_ldo)) {
        cam_err("%s regulator is NULL", __func__);
        return -1;
    }

    /*if flash has already on do nothing*/
    if(BIT(FLASH_MODE) & pdata->status){
        cam_info("%s already in flash mode, do nothing",__func__);
        return 0;
    }

    ret = scharger_flash_led_timeout_config(FLASH_TIMEOUT_MS);
    if (ret < 0) {
        cam_err("%s scharger_flash_led_timeout_config  fail ret = %d ", __func__, ret);
        regulator_disable(pdata->flash_inter_ldo);
        return ret;
    }

    ret = scharger_flash_led_timeout_enable();
    if (ret < 0) {
        cam_err("%s scharger_flash_led_timeout_enable  fail ret = %d ", __func__, ret);
        return ret;
    }
    ret = regulator_enable(pdata->flash_inter_ldo);
    if (ret < 0) {
        cam_err("%s regulator_enable flash_inter_ldo fail ret = %d", __func__, ret);
/* #if defined (CONFIG_HUAWEI_DSM) */
/*         if (!dsm_client_ocuppy(client_ovisp22)){ */
/*             dsm_client_record(client_ovisp22,"[%s]regulator_enable flash_inter_ldo fail mode %d\n",__func__,mode); */
/*             dsm_client_notify(client_ovisp22, DSM_ISP22_FLASH_ERROR_NO); */
/*         } */
/* #endif */
        return ret;
    }
    udelay(500);

    ret = regulator_set_current_limit(pdata->flash_mode_ldo, pdata->flash_led[data], pdata->flash_led[data]);
    if (ret < 0) {
        cam_err("%s regulator_set_current_limit  fail ret = %d current is %d", __func__, ret, (pdata->flash_led[data]));
        regulator_disable(pdata->flash_inter_ldo);
        return ret;
    }

    ret = regulator_enable(pdata->flash_mode_ldo);
    if (ret < 0) {
        cam_err("%s regulator_enable torch_mode_ldo fail ret = %d", __func__, ret);
/* #if defined (CONFIG_HUAWEI_DSM) */
/*         if (!dsm_client_ocuppy(client_ovisp22)){ */
/*             dsm_client_record(client_ovisp22,"[%s]regulator_enable flash_mode_ldo fail mode %d\n",__func__,mode); */
/*             dsm_client_notify(client_ovisp22, DSM_ISP22_FLASH_ERROR_NO); */
/*         } */
/* #endif */
        regulator_disable(pdata->flash_inter_ldo);
        return ret;
    }

    pdata->status |= BIT(FLASH_MODE);
    return 0;
}
Example #17
0
/*
 * Assumption:
 * AC power can't be switched to USB w/o system reboot
 * and vice-versa
 */
static void state_machine_work(struct work_struct *work)
{
	struct stmp3xxx_info *info =
		container_of(work, struct stmp3xxx_info, sm_work);

	mutex_lock(&info->sm_lock);

	handle_battery_voltage_changes(info);

	check_and_handle_5v_connection(info);

	if ((info->sm_5v_connection_status != _5v_connected_verified) ||
			!(info->regulator)) {
		mod_timer(&info->sm_timer, jiffies + msecs_to_jiffies(100));
		goto out;
	}

	/* if we made it here, we have a verified 5v connection */

	if (is_ac_online()) {
		if (info->is_ac_online)
			goto done;

		/* ac supply connected */
		dev_info(info->dev, "changed power connection to ac/5v.\n)");
		dev_info(info->dev, "5v current limit set to %u.\n",
			NON_USB_5V_SUPPLY_CURRENT_LIMIT_MA);

		info->is_ac_online = 1;
		info->is_usb_online = 0;
		ddi_power_set_4p2_ilimit(
				NON_USB_5V_SUPPLY_CURRENT_LIMIT_MA);
		ddi_bc_SetCurrentLimit(
				NON_USB_5V_SUPPLY_CURRENT_LIMIT_MA /*mA*/);
		if (regulator_set_current_limit(info->regulator,
				0,
				NON_USB_5V_SUPPLY_CURRENT_LIMIT_MA*1000)) {
			dev_err(info->dev, "reg_set_current(%duA) failed\n",
				NON_USB_5V_SUPPLY_CURRENT_LIMIT_MA*1000);
		}
		ddi_bc_SetEnable();
		goto done;
	}

	if (!is_usb_online())
		goto out;

	if (info->is_usb_online & USB_REG_SET)
		goto done;

	info->is_ac_online = 0;
	info->is_usb_online |= USB_ONLINE;



	if (!(info->is_usb_online & USB_N_SEND)) {
		info->is_usb_online |= USB_N_SEND;
	}


	dev_dbg(info->dev, "%s: charge current set to %dmA\n", __func__,
			POWERED_USB_5V_CURRENT_LIMIT_MA);

	if (regulator_set_current_limit(info->regulator,
		0,
		POWERED_USB_5V_CURRENT_LIMIT_MA*1000)) {
		dev_err(info->dev, "reg_set_current(%duA) failed\n",
				POWERED_USB_5V_CURRENT_LIMIT_MA*1000);
	} else {
		ddi_bc_SetCurrentLimit(POWERED_USB_5V_CURRENT_LIMIT_MA/*mA*/);
		ddi_bc_SetEnable();
	}

	if (info->is_usb_online & USB_SM_RESTART) {
		info->is_usb_online &= ~USB_SM_RESTART;
		ddi_bc_SetEnable();
	}

	info->is_usb_online |= USB_REG_SET;

	dev_info(info->dev, "changed power connection to usb/5v present\n");


done:
	ddi_bc_StateMachine();
out:
	mutex_unlock(&info->sm_lock);
}
/*
 **************************************************************************
 * FunctionName: scharger_flash_turn_on;
 * Description : turn on flashlight;
 * Input       : NA;
 * Output      : NA;
 * ReturnValue : NA;
 * Other       : NA;
 **************************************************************************
 */
static int scharger_flash_turn_on(work_mode mode, flash_lum_level lum)
{
	int ret = 0;
	print_info("enter %s work_mode = %d , lum = %d",__func__, mode, lum);
	SAFE_DOWN(&switch_lock);
	if (mode == TORCH_MODE) {
		if (lum >= TORCH_LUM_LEVEL_NUM) {
			print_error("Unsupport torch_lum_level: %d", lum);
			ret = -1;
			goto out;
		}

		
		flash_mode = TORCH_MODE;

		/*if flash has already on go out do nothing*/
		if(FLASH_TORCH_MODE&flash_on){
			ret = 0;
			print_info("%s torch mode already in do nothing",__func__);
			goto out;
		}
		
		ret = regulator_set_current_limit(torch_mode_ldo, torch_lum_table[lum], torch_lum_table[lum]);
		if (ret < 0){
			print_error("%s regulator_set_current_limit  fail ret = %d current is %d", __func__, ret, (torch_lum_table[lum]));
			goto out;
		}
		ret = regulator_enable(flash_inter_ldo);
		if (ret < 0){
			print_error("%s regulator_enable flash_inter_ldo fail ret = %d", __func__, ret);
			#if defined (CONFIG_HUAWEI_DSM)
			if (!dsm_client_ocuppy(client_ovisp22)){
			    dsm_client_record(client_ovisp22,"[%s]regulator_enable flash_inter_ldo fail mode %d\n",__func__,mode);
			    dsm_client_notify(client_ovisp22, DSM_ISP22_FLASH_ERROR_NO);
			}
			#endif
			goto out;
		}

		udelay(500);

		ret = regulator_enable(torch_mode_ldo);
		if (ret < 0){
			print_error("%s regulator_enable torch_mode_ldo fail ret = %d", __func__, ret);
			#if defined (CONFIG_HUAWEI_DSM)
			if (!dsm_client_ocuppy(client_ovisp22)){
			    dsm_client_record(client_ovisp22,"[%s]regulator_enable torch_mode_ldo fail mode %d\n",__func__,mode);
			    dsm_client_notify(client_ovisp22, DSM_ISP22_FLASH_ERROR_NO);
			}
			#endif
			if (flash_inter_ldo){
				regulator_disable(flash_inter_ldo);
			}
			goto out;
		}
		flash_on |= FLASH_TORCH_MODE;
	} else {
		if (lum >= FLASH_LUM_LEVEL_NUM) {
			print_error("Unsupport flash_lum_level: %d", lum);
			ret = -1;
			goto out;
		}
		
		flash_mode = FLASH_MODE;
		
		if(FLASH_FLASH_MODE&flash_on){
			ret = 0;
			print_info("%s flash mode already in do nothing",__func__);
			goto out;
		}

		if(audio_codec_mute_flag){
			audio_codec_mute_pga(1);
			flash_mute = true;
		}
		ret = regulator_set_current_limit(flash_mode_ldo, flash_lum_table[lum], flash_lum_table[lum]);
		if (ret < 0){
			print_error("%s regulator_set_current_limit  fail ret = %d current is %d", __func__, ret, (flash_lum_table[lum]));
			goto out;
		}
		ret = scharger_flash_led_timeout_config(FLASH_TIMEOUT_MS);
		if (ret < 0){
			print_error("%s scharger_flash_led_timeout_config  fail ret = %d ", __func__, ret);
			goto out;
		}
		ret = scharger_flash_led_timeout_enable();
		if (ret < 0){
			print_error("%s scharger_flash_led_timeout_enable  fail ret = %d ", __func__, ret);
			goto out;
		}
		ret = regulator_enable(flash_inter_ldo);
		if (ret < 0){
			print_error("%s regulator_enable flash_inter_ldo fail ret = %d", __func__, ret);
			#if defined (CONFIG_HUAWEI_DSM)
			if (!dsm_client_ocuppy(client_ovisp22)){
			    dsm_client_record(client_ovisp22,"[%s]regulator_enable flash_inter_ldo fail mode %d\n",__func__,mode);
			    dsm_client_notify(client_ovisp22, DSM_ISP22_FLASH_ERROR_NO);
			}
			#endif
			goto out;
		}
		udelay(500);
		ret = regulator_enable(flash_mode_ldo);
		if (ret < 0){
			print_error("%s regulator_enable torch_mode_ldo fail ret = %d", __func__, ret);
			#if defined (CONFIG_HUAWEI_DSM)
			if (!dsm_client_ocuppy(client_ovisp22)){
			    dsm_client_record(client_ovisp22,"[%s]regulator_enable flash_mode_ldo fail mode %d\n",__func__,mode);
			    dsm_client_notify(client_ovisp22, DSM_ISP22_FLASH_ERROR_NO);
			}
			#endif
			if (flash_inter_ldo){
				regulator_disable(flash_inter_ldo);
			}
			goto out;
		}
		flash_on |= FLASH_FLASH_MODE;

	}
	
out:
	SAFE_UP(&switch_lock);
	return ret;
}
static void timer_func(unsigned long data)
{
	regulator_set_current_limit(reg, 0, 0);
	mutex_unlock(&run_mutex);
}
Example #20
0
static void check_and_handle_5v_connection(struct stmp3xxx_info *info)
{

	switch (ddi_power_GetPmu5vStatus()) {

	case new_5v_connection:
		ddi_power_enable_5v_disconnect_detection();
		info->sm_5v_connection_status = _5v_connected_unverified;

	case existing_5v_connection:
		if (info->sm_5v_connection_status != _5v_connected_verified) {
			/* we allow some time to pass before considering
			 * the 5v connection to be ready to use.  This
			 * will give the USB system time to enumerate
			 * (coordination with USB driver to be added
			 * in the future).
			 */

			/* handle jiffies rollover case */
			if ((jiffies - info->sm_new_5v_connection_jiffies)
				< 0) {
				info->sm_new_5v_connection_jiffies = jiffies;
				break;
			}

			if ((jiffies_to_msecs(jiffies -
				info->sm_new_5v_connection_jiffies)) >
				_5V_DEBOUNCE_TIME_MS) {
				info->sm_5v_connection_status =
					_5v_connected_verified;
				dev_info(info->dev,
					"5v connection verified\n");
				ddi_power_Enable4p2(450);


				/* part of handling for errata.  It is
				 *  now "somewhat" safe to
				 * turn on vddio interrupts again
				 */
				ddi_power_enable_vddio_interrupt(true);
			}
		}
		break;

	case new_5v_disconnection:

		ddi_bc_SetDisable();
		ddi_bc_SetCurrentLimit(0);
		if (info->regulator)
			regulator_set_current_limit(info->regulator, 0, 0);
		info->is_usb_online = 0;
		info->is_ac_online = 0;

		info->sm_5v_connection_status = _5v_disconnected_unverified;

	case existing_5v_disconnection:

		if (info->sm_5v_connection_status !=
			_5v_disconnected_verified) {
			if ((jiffies - info->sm_new_5v_disconnection_jiffies)
				< 0) {
				info->sm_new_5v_connection_jiffies = jiffies;
				break;
			}

			if ((jiffies_to_msecs(jiffies -
				info->sm_new_5v_disconnection_jiffies)) >
				_5V_DEBOUNCE_TIME_MS) {
				info->sm_5v_connection_status =
					_5v_disconnected_verified;
				ddi_power_execute_5v_to_battery_handoff();
				ddi_power_enable_5v_connect_detection();

				/* part of handling for errata.
				 * It is now safe to
				 * turn on vddio interrupts again
				 */
				ddi_power_enable_vddio_interrupt(true);
				dev_info(info->dev,
					"5v disconnection handled\n");

			}
		}

		break;
	}
}
Example #21
0
/* Send adtc command to the card */
static void stmp3xxx_mmc_adtc(struct stmp3xxx_mmc_host *host)
{
	struct mmc_command *cmd = host->cmd;
	struct stmp3xxx_dma_descriptor *dma_desc = &host->dma_desc;
	int ignore_crc, resp, long_resp;
	int is_reading = 0;
	unsigned int copy_size;

	u32 ssp_ctrl0;
	u32 ssp_cmd0;
	u32 ssp_cmd1;
	u32 timeout;
	u32 val;

	u32 data_size = cmd->data->blksz * cmd->data->blocks;
	u32 log2_block_size;

	ignore_crc = mmc_resp_type(cmd) & MMC_RSP_CRC ? 0 : 1;
	resp = mmc_resp_type(cmd) & MMC_RSP_PRESENT ? 1 : 0;
	long_resp = mmc_resp_type(cmd) & MMC_RSP_136 ? 1 : 0;

	dev_dbg(host->dev, "ADTC command:\n"
		"response: %d, ignore crc: %d\n"
		"data list: %u, blocksz: %u, blocks: %u, timeout: %uns %uclks, "
		"flags: 0x%x\n", resp, ignore_crc, cmd->data->sg_len,
		cmd->data->blksz, cmd->data->blocks, cmd->data->timeout_ns,
		cmd->data->timeout_clks, cmd->data->flags);

	if (cmd->data->flags & MMC_DATA_WRITE) {
		dev_dbg(host->dev, "Data Write\n");
		copy_size = stmp3xxx_sg_dma_copy(host, data_size, 1);
		BUG_ON(copy_size < data_size);
		is_reading = 0;
		if (!host->regulator)
			__init_reg(host->dev, &host->regulator);
		if (host->regulator)
			regulator_set_current_limit(host->regulator,
						    host->write_uA,
						    host->write_uA);
	} else if (cmd->data->flags & MMC_DATA_READ) {
		dev_dbg(host->dev, "Data Read\n");
		is_reading = 1;
		if (!host->regulator)
			__init_reg(host->dev, &host->regulator);
		if (host->regulator)
			regulator_set_current_limit(host->regulator,
						    host->read_uA,
						    host->read_uA);
	} else {
		dev_warn(host->dev, "Unsuspported data mode, 0x%x\n",
			 cmd->data->flags);
		BUG();
	}

	BUG_ON(cmd->data->flags & MMC_DATA_STREAM);
	BUG_ON((data_size % 8) > 0);

	dma_desc->command->cmd =
	    BM_APBH_CHn_CMD_WAIT4ENDCMD |
	    BM_APBH_CHn_CMD_SEMAPHORE |
	    BM_APBH_CHn_CMD_IRQONCMPLT |
	    BF(data_size, APBH_CHn_CMD_XFER_COUNT) |
	    BF(3, APBH_CHn_CMD_CMDWORDS);

	/* when is_reading is set, DMA controller performs WRITE operation. */
	dma_desc->command->cmd |=
	    BF(is_reading ? BV_APBH_CHn_CMD_COMMAND__DMA_WRITE :
			     BV_APBH_CHn_CMD_COMMAND__DMA_READ,
			     APBH_CHn_CMD_COMMAND);
	ssp_ctrl0 =
	    (ignore_crc ? BM_SSP_CTRL0_IGNORE_CRC : 0) | (resp ?
							  BM_SSP_CTRL0_GET_RESP
							  : 0) | (long_resp ?
								  BM_SSP_CTRL0_LONG_RESP
								  : 0) |
	    (is_reading ? BM_SSP_CTRL0_READ : 0) | BM_SSP_CTRL0_DATA_XFER |
	    BM_SSP_CTRL0_WAIT_FOR_IRQ | BM_SSP_CTRL0_ENABLE | BF(data_size,
								 SSP_CTRL0_XFER_COUNT)
	    | BF(host->bus_width_4 ? BV_SSP_CTRL0_BUS_WIDTH__FOUR_BIT :
				     BV_SSP_CTRL0_BUS_WIDTH__ONE_BIT,
				     SSP_CTRL0_BUS_WIDTH);

	/*
	 * We need to set the hardware register to the logarithm to base 2 of
	 * the block size.
	 */
	log2_block_size = ilog2(cmd->data->blksz);

	ssp_cmd0 =
	    BF(log2_block_size, SSP_CMD0_BLOCK_SIZE) |
	    BF(cmd->opcode, SSP_CMD0_CMD) |
	    BF(cmd->data->blocks - 1, SSP_CMD0_BLOCK_COUNT);

	if (cmd->opcode == 12)
		ssp_cmd0 |= BM_SSP_CMD0_APPEND_8CYC;

	ssp_cmd1 = BF(cmd->arg, SSP_CMD1_CMD_ARG);

	dma_desc->command->pio_words[0] = ssp_ctrl0;
	dma_desc->command->pio_words[1] = ssp_cmd0;
	dma_desc->command->pio_words[2] = ssp_cmd1;

	/* Set the timeout count */
	timeout = stmp3xxx_ns_to_ssp_ticks(host->clkrt, cmd->data->timeout_ns);
	val = __raw_readl(host->ssp_base + HW_SSP_TIMING);
	val &= ~(BM_SSP_TIMING_TIMEOUT);
	val |= BF(timeout, SSP_TIMING_TIMEOUT);
	__raw_writel(val, host->ssp_base + HW_SSP_TIMING);

	init_completion(&host->dma_done);
	stmp3xxx_dma_reset_channel(host->dmach);
	stmp3xxx_dma_go(host->dmach, dma_desc, 1);
	wait_for_completion(&host->dma_done);
	if (host->regulator)
		regulator_set_current_limit(host->regulator, 0, 0);

	switch (mmc_resp_type(cmd)) {
	case MMC_RSP_NONE:
		break;
	case MMC_RSP_R1:
	case MMC_RSP_R3:
		cmd->resp[0] =
		    __raw_readl(host->ssp_base + HW_SSP_SDRESP0);
		break;
	case MMC_RSP_R2:
		cmd->resp[3] =
		    __raw_readl(host->ssp_base + HW_SSP_SDRESP0);
		cmd->resp[2] =
		    __raw_readl(host->ssp_base + HW_SSP_SDRESP1);
		cmd->resp[1] =
		    __raw_readl(host->ssp_base + HW_SSP_SDRESP2);
		cmd->resp[0] =
		    __raw_readl(host->ssp_base + HW_SSP_SDRESP3);
		break;
	default:
		dev_warn(host->dev, "Unsupported response type 0x%x\n",
			 mmc_resp_type(cmd));
		BUG();
		break;
	}

	cmd->error = stmp3xxx_mmc_cmd_error(host->status);

	if (stmp3xxx_dma_running(host->dmach))
		dev_dbg(host->dev, "DMA command not finished\n");

	if (cmd->error) {
		dev_dbg(host->dev, "Command error 0x%x\n", cmd->error);
		stmp3xxx_dma_reset_channel(host->dmach);
	} else {
		if (is_reading)
			cmd->data->bytes_xfered =
			    stmp3xxx_sg_dma_copy(host, data_size, 0);
		else
			cmd->data->bytes_xfered = data_size;

		dev_dbg(host->dev, "Transferred %u bytes\n",
			cmd->data->bytes_xfered);
	}
}