static int rt5033_fled_strobe(struct rt_fled_info *fled_info)
{
	int ret = 0;
	rt5033_fled_info_t *info = (rt5033_fled_info_t *)fled_info;
	rt5033_set_fled_osc_en(info->i2c_client, 1);
	if (info->strobe_status == 0) {
		/* Lock LED until setting to OFF MODE*/
		rt5033_fled_lock(fled_info);
		info->strobe_status = 1;
		rt5033_fled_set_ta_status(info->i2c_client, 0);
		rt5033_set_uug_status(info->i2c_client, 0);
	}
	switch (info->base.flashlight_dev->props.mode) {
	case FLASHLIGHT_MODE_FLASH:
		rt5033_set_bits(info->i2c_client, RT5033_FLED_FUNCTION2, 0x81);
		break;
	case FLASHLIGHT_MODE_MIXED:
		rt5033_assign_bits(info->i2c_client, RT5033_FLED_FUNCTION2, 0x81, 0x1);
		rt5033_set_bits(info->i2c_client, RT5033_FLED_FUNCTION1, 0x04);
		rt5033_clr_bits(info->i2c_client, RT5033_FLED_CONTROL2,
				(1 << 7)); // DISABLE AUTO TRACK
		rt5033_set_bits(info->i2c_client, RT5033_FLED_FUNCTION2, 0x81);
		break;
	default:
		RT5033_FLED_ERR("Error : not flash / mixed mode\n");
		ret = -EINVAL;
	}
	return ret;
}
/* For GPIO operation */
int32_t rt5033_charger_notification(struct rt_fled_info *fled_info,
				    int32_t attach)
{
	rt5033_fled_info_t *info = (rt5033_fled_info_t *)fled_info;
	int force_torch_en = 0;
	int chg_status;
	int reg0x1a;
	BUG_ON(info == NULL);
	rt5033_fled_lock(fled_info);
	info->ta_exist = attach;
	reg0x1a = rt5033_reg_read(info->i2c_client, 0x1a);
	reg0x1a |= 0xa0;
	rt5033_fled_set_ta_status(info->i2c_client, attach);
	if (attach == 0 && info->boost == 0) {
		chg_status = rt5033_reg_read(info->i2c_client, 0x00);
		/* remove TA, re-start FlashEN,
		 * and then become boost mode => torch enabled */
		force_torch_en = (chg_status & 0x08) ? 1 : 0;
		/* Enable hidden bit (Force boosting) for TA/USB detaching
		 * To fix flicking issue for torch while TA is removing
		 */
		if (force_torch_en)
			rt5033_reg_write(info->i2c_client, 0x1a, reg0x1a);
	}
	rt5033_set_uug_status(info->i2c_client, attach ? 0x02 : 0x00);

	if (attach) {
		/* GPIO mode, 0x1 means disable
		 * Disable it and then enable it */
		rt5033_assign_bits(info->i2c_client, RT5033_FLED_FUNCTION2, 0x81, 0x1);
		rt5033_assign_bits(info->i2c_client, RT5033_FLED_FUNCTION2, 0x81, 0x0);
	}

	rt5033_fled_unlock(fled_info);
	/* Disable hidden bit (Force boosting) for TA/USB detaching
	 * To fix flicking issue for torch while TA is removing
	 */
	if (force_torch_en) {
		usleep_range(2500, 2500);
		rt5033_clr_bits(info->i2c_client, 0x1a, 0x80);
	}
	RT5033_FLED_INFO("force_torch_en = %d\n",
			force_torch_en);
	return 0;
}
static int rt5033_fled_set_timeout_level_sel(struct rt_fled_info *fled_info,
		int selector)
{
	rt5033_fled_info_t *info = (rt5033_fled_info_t *)fled_info;
	RT5033_FLED_INFO("Set timeout level to %d\n", selector);
	if (selector < 0 || selector >=  ARRAY_SIZE(strobe_timeout_level))
		return -EINVAL;
	return rt5033_assign_bits(info->i2c_client, RT5033_FLED_STROBE_CONTROL1,
				  0xe0, selector << 5);
}
static int rt5033_fled_init(struct rt_fled_info *fled_info)
{
	rt5033_fled_info_t *info = (rt5033_fled_info_t *)fled_info;
	rt5033_mfd_platform_data_t *mfd_pdata;
	BUG_ON(info == NULL);
	mfd_pdata = info->chip->pdata;
	mutex_lock(&info->led_lock);
	rt5033_set_bits(info->i2c_client, RT5033_FLED_RESET, 0x80);
	rt5033_fled_set_ta_status(info->i2c_client, 0);
#ifdef  CONFIG_CHARGER_RT5033
	rt5033_chg_fled_init(info->i2c_client);
#else
	/* Force to do normal read (read from e-fuse) ==> let FLED current be more accurate */
	rt5033_set_bits(info->i2c_client, RT5033_OFF_EVENT_NRD, FORCE_NR);
	/* Delay 100 us to wait for normal read complete */
	usleep_range(100, 100);
	/* Finsh normal read and clear FORCE_NR bit */
	rt5033_clr_bits(info->i2c_client, RT5033_OFF_EVENT_NRD, FORCE_NR);
#endif
	if (!info->pdata->fled1_en)
		rt5033_clr_bits(info->i2c_client, RT5033_FLED_FUNCTION1, 0x01);
	if (!info->pdata->fled2_en)
		rt5033_clr_bits(info->i2c_client, RT5033_FLED_FUNCTION1, 0x02);
	if (info->pdata->fled_mid_track_alive)
		rt5033_set_bits(info->i2c_client, RT5033_FLED_CONTROL2, (1 << 6));
	if (info->pdata->fled_mid_auto_track_en)
		rt5033_set_bits(info->i2c_client, RT5033_FLED_CONTROL2, (1 << 7));
	rt5033_reg_write(info->i2c_client, RT5033_FLED_STROBE_CONTROL1,
			 (info->pdata->fled_timeout_current_level << 5) |
			 info->pdata->fled_strobe_current);
	info->base.flashlight_dev->props.strobe_brightness =
		info->pdata->fled_strobe_current;

	rt5033_reg_write(info->i2c_client, RT5033_FLED_STROBE_CONTROL2,
			 info->pdata->fled_strobe_timeout);
	info->base.flashlight_dev->props.strobe_timeout =
		info->base.hal->fled_strobe_timeout_list(fled_info,
				info->pdata->fled_strobe_timeout);
	RT5033_FLED_INFO("Strobe timeout = %d ms\n",
			 info->base.flashlight_dev->props.strobe_timeout);
	rt5033_reg_write(info->i2c_client, RT5033_FLED_CONTROL1,
			 (info->pdata->fled_torch_current << 4) |
			 info->pdata->fled_lv_protection);
	info->base.flashlight_dev->props.torch_brightness =
		info->pdata->fled_torch_current;
	rt5033_assign_bits(info->i2c_client, RT5033_FLED_CONTROL2,
			   0x3f, info->pdata->fled_mid_level);
	info->led_count = info->pdata->fled1_en + info->pdata->fled2_en;
#ifdef CONFIG_FLED_RT5033_I2C
	rt5033_set_bits(info->i2c_client, RT5033_FLED_FUNCTION1, RT5033_FLED_PIN_CTRL);
#endif
	mutex_unlock(&info->led_lock);
	return 0;
}
static int rt5033_fled_set_lv_protection_sel(struct rt_fled_info *fled_info,
		int selector)
{
	rt5033_fled_info_t *info = (rt5033_fled_info_t *)fled_info;
	RT5033_FLED_INFO("Set lv protection to %d\n", selector);
	if (selector < 0 || selector >=  ARRAY_SIZE(lv_protection))
		return -EINVAL;

	return rt5033_assign_bits(info->i2c_client, RT5033_FLED_CONTROL1,
				  0x07, selector);
}
int32_t rt5033_charger_notification(struct rt_fled_info *fled_info,
				    int32_t attach)
{
	rt5033_fled_info_t *info = (rt5033_fled_info_t *)fled_info;
	int mode = fled_info->hal->fled_get_mode(fled_info);
	BUG_ON(info == NULL);
	rt5033_fled_lock(fled_info);
	info->ta_exist = attach;
	/* Enable hidden bit (Force boosting) for TA/USB detaching
	 * To fix flicking issue for torch while TA is removing
	 */
	if (attach == 0) {
		/* For i2c FlashLED operation,
		 * we will check torch had already been on or not
		 */
		if (mode == FLASHLIGHT_MODE_TORCH || mode == FLASHLIGHT_MODE_MIXED)
			rt5033_set_bits(info->i2c_client, 0x1a, 0x80);
	}
	rt5033_fled_set_ta_status(info->i2c_client, attach);
	rt5033_set_uug_status(info->i2c_client, attach ? 0x02 : 0x00);

	if (mode == FLASHLIGHT_MODE_TORCH || mode == FLASHLIGHT_MODE_MIXED) {
		/* disable FlashEN and then enable it*/
		rt5033_assign_bits(info->i2c_client, RT5033_FLED_FUNCTION2, 0x81, 0x0);
		rt5033_assign_bits(info->i2c_client, RT5033_FLED_FUNCTION2, 0x81, 0x1);
	}
	rt5033_fled_unlock(fled_info);
	/* Disable hidden bit (Force boosting) for TA/USB detaching
	 * To fix flicking issue for torch while TA is removing
	 */
	if (attach == 0) {
		/* For i2c FlashLED operation,
		* we will check torch had already been on or not
		*/
		if (mode == FLASHLIGHT_MODE_TORCH || mode == FLASHLIGHT_MODE_MIXED) {
			usleep(2500);
			rt5033_clr_bits(info->i2c_client, 0x1a, 0x80);
		}
	}
	return 0;
}
static int rt5033_fled_set_mode(struct rt_fled_info *fled_info,
				flashlight_mode_t mode)
{
	rt5033_fled_info_t *info = (rt5033_fled_info_t *)fled_info;

	if (info->strobe_status) {
		info->strobe_status = 0;
		rt5033_fled_set_ta_status(info->i2c_client, info->ta_exist);
		rt5033_set_uug_status(info->i2c_client,
				      (info->ta_exist | info->boost) ? 0x02 : 0x00);
		rt5033_fled_unlock(fled_info);
	}
	rt5033_fled_lock(fled_info);
	switch (mode) {
	case FLASHLIGHT_MODE_OFF:
		rt5033_clr_bits(info->i2c_client, RT5033_FLED_FUNCTION2, 0x80);
		usleep_range(500, 1000);
		rt5033_clr_bits(info->i2c_client, RT5033_FLED_FUNCTION2, 0x01);
		rt5033_set_fled_osc_en(info->i2c_client, 0);

		break;
	case FLASHLIGHT_MODE_TORCH:
	case FLASHLIGHT_MODE_MIXED:
		rt5033_clr_bits(info->i2c_client, RT5033_FLED_FUNCTION1, 0x04);
		rt5033_assign_bits(info->i2c_client, RT5033_FLED_FUNCTION2, 0x81, 0x1);
		break;
	case FLASHLIGHT_MODE_FLASH:
		rt5033_assign_bits(info->i2c_client, RT5033_FLED_FUNCTION2, 0x81, 0x0);
		rt5033_set_bits(info->i2c_client, RT5033_FLED_FUNCTION1, 0x04);
		rt5033_assign_bits(info->i2c_client, RT5033_FLED_FUNCTION2, 0x81, 0x1);
		break;
	default:
		return -EINVAL;
	}
	rt5033_fled_unlock(fled_info);
	info->base.flashlight_dev->props.mode = mode;
	return 0;
}
int rt5033_regulator_set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
{
	struct rt5033_regulator_info *info = rdev_get_drvdata(rdev);
	unsigned char data;

	pr_info("select = %d, output list count = %d\n",
			selector, info->output_list_count);
	if (selector>=info->output_list_count)
		return -EINVAL;
	pr_info("Vout = %d\n", info->output_list[selector]);
	data = (unsigned char)selector;
	data <<= info->vol_shift;
	return rt5033_assign_bits(info->i2c, info->vol_reg, info->vol_mask, data);
}
static int rt5033_regulator_set_voltage(struct regulator_dev *rdev,
		int min_uV, int max_uV,int *selector)
{
	struct rt5033_regulator_info *info = rdev_get_drvdata(rdev);
	unsigned char data;

	if (rt5033_regulator_check_range(info, min_uV, max_uV)) {
		dev_err(info->chip->dev, "invalid voltage range (%d, %d) uV\n",
				min_uV, max_uV);
		return -EINVAL;
	}
	data = rt5033_regulator_find_voltage(rdev,min_uV,max_uV);
	data <<= info->vol_shift;
	return rt5033_assign_bits(info->i2c, info->vol_reg, info->vol_mask, data);
}
Example #10
0
static int rt5033_fled_set_strobe_timeout_sel(struct rt_fled_info *fled_info,
		int selector)
{
	int rc;
	rt5033_fled_info_t *info = (rt5033_fled_info_t *)fled_info;
	RT5033_FLED_INFO("Set strobe timeout to %d\n", selector);
	if (selector < 0 || selector >=  37)
		return -EINVAL;
	rc = rt5033_assign_bits(info->i2c_client, RT5033_FLED_STROBE_CONTROL2,
				0x3f, selector);
	if (rc == 0)
		fled_info->flashlight_dev->props.strobe_timeout =
			rt5033_fled_strobe_timeout_list(fled_info, selector);
	return rc;
}
Example #11
0
static int rt5033_fled_set_strobe_current_sel(struct rt_fled_info *fled_info,
		int selector)
{
	int rc;
	rt5033_fled_info_t *info = (rt5033_fled_info_t *)fled_info;
	RT5033_FLED_INFO("Set strobe current to %d\n", selector);
	if (selector < 0 || selector >  info->
	    base.flashlight_dev->props.strobe_max_brightness)
		return -EINVAL;
	rc = rt5033_assign_bits(info->i2c_client, RT5033_FLED_STROBE_CONTROL1,
				0x1f, selector);
	if (rc == 0)
		info->base.flashlight_dev->props.strobe_brightness = selector;
	return 0;
}
static int rt5033_regulator_set_voltage(struct regulator_dev *rdev,
		int min_uV, int max_uV,unsigned *selector)
{
	struct rt5033_regulator_info *info = rdev_get_drvdata(rdev);
	unsigned char data;

	if (rt5033_regulator_check_range(info, min_uV, max_uV)) {
		pr_err("%s %s invalid voltage range (%d, %d) uV\n",
				ALIAS_NAME, rdev->desc->name, min_uV, max_uV);
		return -EINVAL;
	}
	*selector = rt5033_regulator_find_voltage(rdev,min_uV,max_uV);
	data = *selector << info->vol_shift;

	return rt5033_assign_bits(info->i2c, info->vol_reg, info->vol_mask, data);
}
int rt5033_regulator_set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
{
	struct rt5033_regulator_info *info = rdev_get_drvdata(rdev);
	unsigned char data;
	int ret;

	pr_info("%s select = %d, output list count = %d\n",
			ALIAS_NAME, selector, info->output_list_count);
	if (selector>=info->output_list_count)
		return -EINVAL;
	pr_info("%s Vout = %d\n", ALIAS_NAME, info->output_list[selector]);
	data = (unsigned char)selector;
	data <<= info->vol_shift;
	ret = rt5033_assign_bits(info->i2c, info->vol_reg, info->vol_mask, data);

	pr_info("%s %s %s ret (%d)", ALIAS_NAME, rdev->desc->name, __func__, ret);

	return ret;
}
int rt5033_clr_bits(struct i2c_client *i2c, int reg,
		unsigned char mask)
{
	return rt5033_assign_bits(i2c,reg,mask,0);
}
Example #15
0
static int rt5033_fled_set_ta_status(struct i2c_client *iic, int ta_good_and_exist)
{
	return rt5033_assign_bits(iic, RT5033_FLED_CONTROL5, (0x03 << 6),
				  ta_good_and_exist ? (0x03 << 6) : 0);
}
Example #16
0
inline static int rt5033_set_uug_status(struct i2c_client *iic, int uug)
{
	return rt5033_assign_bits(iic, 0x19, 0x02, uug);
}
static int rt5033_regulator_get_status(struct regulator_dev *rdev)
{
	struct rt5033_regulator_info *info = rdev_get_drvdata(rdev);
	/* REGULATOR_STATUS_OFF, REGULATOR_STATUS_ON, REGULATOR_STATUS_OFF */
	int ret = REGULATOR_STATUS_ERROR; /* 2 */
	int org_regval, dump_reg;
	//int sta1, sta2;
	uint16_t sta1, sta2;
#ifndef CONFIG_MFD_RT5033_RESET_GPIO
	/* if there are no reset solution(MRSTB or I2C),
       skip reset workaround(always return true) */
	if (chip_rev < RT5033A_REV)
		return REGULATOR_STATUS_ON;
#endif
	rt5033_lock_regulator(info->i2c);
	/* First time to check it */
	msleep(2);
	org_regval = rt5033_reg_read(info->i2c, 0xf0);
	rt5033_reg_write(info->i2c, 0xf0, 0x1e);
	rt5033_assign_bits(info->i2c, 0xf3, 0x03 << 6, 0x2 << 6);
	sta1 = rt5033_reg_read(info->i2c, 0xf6) & 0x1f;
	rt5033_assign_bits(info->i2c, 0xf3, 0x03 << 6, 0x3 << 6);
	sta2 = rt5033_reg_read(info->i2c, 0xf7) & 0x1f;
	printk("%s status #1[0x%2x]\n", __func__, (sta2 << 8) | sta1);
	if (check_status_is_vaild(sta1, 0xf6) && check_status_is_vaild(sta2, 0xf7))
		goto rt5033_reg_status_ok;

	/* Failed case, we need to check again */
	msleep(2);
	org_regval = rt5033_reg_read(info->i2c, 0xf0);
	rt5033_reg_write(info->i2c, 0xf0, 0x1e);
	rt5033_assign_bits(info->i2c, 0xf3, 0x03 << 6, 0x2 << 6);
	sta1 = rt5033_reg_read(info->i2c, 0xf6) & 0x1f;
	rt5033_assign_bits(info->i2c, 0xf3, 0x03 << 6, 0x3 << 6);
	sta2 = rt5033_reg_read(info->i2c, 0xf7) & 0x1f;
	printk("%s status #2[0x%2x]\n", __func__, (sta2 << 8) | sta1);
	if (check_status_is_vaild(sta1, 0xf6) && check_status_is_vaild(sta2, 0xf7))
		goto rt5033_reg_status_ok;

	/* Failed case, dump registers */
	dump_reg = rt5033_reg_read(info->i2c, 0x41);
	printk("%s LDO_CTRL:0x%2X\n", __func__, dump_reg);
	dump_reg = rt5033_reg_read(info->i2c, 0x47);
	printk("%s LDO_CTRL:0x%2X\n", __func__, dump_reg);
	dump_reg = rt5033_reg_read(info->i2c, 0x68);
	printk("%s PMIC_IRQ_STAT:0x%2X\n", __func__, dump_reg);
	dump_reg = rt5033_reg_read(info->i2c, 0x69);
	printk("%s PMIC_IRQ_CTRL:0x%2X\n", __func__, dump_reg);
	dump_reg = rt5033_reg_read(info->i2c, 0x6A);
	printk("%s SHDN_CTRL:0x%2X\n", __func__, dump_reg);
	dump_reg = rt5033_reg_read(info->i2c, 0x6B);
	printk("%s SHDN_CTRL:0x%2X\n", __func__, dump_reg);
		goto rt5033_reg_status_exit;

rt5033_reg_status_ok:
	ret = rt5033_regulator_is_enabled(rdev) ?
		REGULATOR_STATUS_ON :  REGULATOR_STATUS_OFF;

rt5033_reg_status_exit:
	rt5033_reg_write(info->i2c, 0xf0, org_regval);
	rt5033_unlock_regulator(info->i2c);
	if (ret==REGULATOR_STATUS_ERROR && chip_rev >= RT5033A_REV)
		ret = REGULATOR_STATUS_UNDEFINED; /* 8 */
	pr_err("%s ret:%d\n", __func__, ret);
	return ret;
}