コード例 #1
0
static int rt5033_regulator_disable(struct regulator_dev *rdev)
{
	struct rt5033_regulator_info *info = rdev_get_drvdata(rdev);
	int ret;
	bool prev_pmic_state, pmic_state;
	rt5033_lock_regulator(info->i2c);

	mdelay(1);
	pr_info("%s Disable regulator %s\n", ALIAS_NAME, rdev->desc->name);
#if EN_DCDC_FORCE_PWM
	/* Disable Force PWM for Buck */
	if (info->desc.id == RT5033_ID_DCDC1) {
		rt5033_clr_bits(info->i2c, 0x41, 0x01);
		udelay(100);
	}
#endif /* EN_DCDC_FORCE_PWM */
	ret = rt5033_clr_bits(info->i2c, info->enable_reg,
			info->enable_bit);
	pr_info("%s %s ret (%d)\n", ALIAS_NAME, __func__, ret);
	udelay(500);
	prev_pmic_state = rt5033_get_pmic_state(info->i2c);
	rt5033_set_regulator_state(info->i2c, info->desc.id, false);
	pmic_state = rt5033_get_pmic_state(info->i2c);
	if (chip_rev >= RT5033A_REV && prev_pmic_state == true && pmic_state == false)
		rt5033_set_bits(info->i2c, 0x6b, 0x01);
	rt5033_unlock_regulator(info->i2c);

	return ret;
}
コード例 #2
0
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;
}
コード例 #3
0
static int rt5033_regulator_disable(struct regulator_dev *rdev)
{
	struct rt5033_regulator_info *info = rdev_get_drvdata(rdev);
	pr_info("Disable regulator %s\n",rdev->desc->name);
	return rt5033_clr_bits(info->i2c, info->enable_reg,
			info->enable_bit);
}
コード例 #4
0
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;
}
コード例 #5
0
static void rt5033_regulator_shutdown(struct device *dev)
{
    struct rt5033_mfd_chip *chip = dev_get_drvdata(dev->parent);
    static int once = ARRAY_SIZE(rt5033_regulator_infos);

    if ( chip_rev >= RT5033A_REV ) {
        once--;
        if ( once==0 ) {
            printk("RT5033#SLDO enable by shutdown\n");
            rt5033_read_dump(chip->i2c_client);
            rt5033_lock_regulator(chip->i2c_client);
            msleep(1);

            // OSC clear, SafeLDO enable
            rt5033_clr_bits(chip->i2c_client, 0x6b, 0x01);
            msleep(1);

            // SafeLDO enable for charger booting
            rt5033_set_bits(chip->i2c_client, RT5033_REGULATOR_REG_OUTPUT_EN, RT5033_REGULATOR_EN_MASK_LDO_SAFE);
            msleep(1);
            rt5033_unlock_regulator(chip->i2c_client);
            rt5033_read_dump(chip->i2c_client);
        }
    }
}
static int rt5033_regulator_disable(struct regulator_dev *rdev)
{
	struct rt5033_regulator_info *info = rdev_get_drvdata(rdev);
	int ret;

	pr_info("%s Disable regulator %s\n", ALIAS_NAME, rdev->desc->name);
	ret = rt5033_clr_bits(info->i2c, info->enable_reg,
			info->enable_bit);
	pr_info("%s %s ret (%d)", ALIAS_NAME, __func__, ret);

	return ret;
}
コード例 #7
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;
}
コード例 #8
0
/* 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;
}
コード例 #9
0
int32_t rt5033_fled_enable(struct rt_fled_info *fled_info,
					int enable)
{
	int32_t ret;
	rt5033_fled_info_t *info =
			(rt5033_fled_info_t *)fled_info;
	if (enable)
		ret = rt5033_clr_bits(info->i2c_client,
			RT5033_FLED_FUNCTION2, 0x01);
	else {
		rt5033_set_fled_osc_en(info->i2c_client, 1);
		ret = rt5033_set_bits(info->i2c_client,
			RT5033_FLED_FUNCTION2, 0x01);
		rt5033_set_fled_osc_en(info->i2c_client, 0);
	}

	return ret;
}
コード例 #10
0
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;
}
コード例 #11
0
static int rt5033_regulator_init_regs(struct regulator_dev* rdev)
{
	int ret;
	struct rt5033_regulator_info *info = rdev_get_drvdata(rdev);
	if (info->desc.id == RT5033_ID_LDO_SAFE)
	{
		ret = rt5033_reg_read(info->i2c, 0x00);
		if (ret < 0) {
			pr_info("I2C read failed (%d)\n",ret);
			return ret;
		}
		if (ret & (0x01<<2)) //Power Good
			rt5033_set_bits(info->i2c,
					RT5033_REGULATOR_REG_OUTPUT_EN,
					RT5033_REGULATOR_EN_MASK_LDO_SAFE);
		else
			rt5033_clr_bits(info->i2c,
					RT5033_REGULATOR_REG_OUTPUT_EN,
					RT5033_REGULATOR_EN_MASK_LDO_SAFE);
	}
	return 0;
}
コード例 #12
0
static int __devinit rt5033_mfd_probe(struct i2c_client *i2c,
		const struct i2c_device_id *id)
{
	int ret = 0;
	u8 data = 0;

	rt5033_mfd_chip_t *chip;
	rt5033_mfd_platform_data_t *pdata = i2c->dev.platform_data;

	pr_info("%s : RT5033 MFD Driver start probe\n", __func__);

	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
	if (chip ==  NULL) {
		dev_err(chip->dev, "Memory is not enough.\n");
		ret = -ENOMEM;
		goto err_mfd_nomem;
	}

	ret = i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
			I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_I2C_BLOCK);
	if (!ret) {
		ret = i2c_get_functionality(i2c->adapter);
		dev_err(chip->dev, "I2C functionality is not supported.\n");
		ret = -ENOSYS;
		goto err_i2cfunc_not_support;
	}

	chip->dev = &i2c->dev;
	chip->i2c_client = i2c;
	chip->pdata = pdata;

	pdata->irq_base = irq_alloc_descs(-1, 0, RT5033_IRQS_NR, -1);
	if (pdata->irq_base < 0) {
		pr_err("%s:%s irq_alloc_descs Fail! ret(%d)\n",
				"rt5033-mfd", __func__, pdata->irq_base);
		ret = -EINVAL;
		goto irq_base_err;
	} else {
		chip->irq_base = pdata->irq_base;
	}

	i2c_set_clientdata(i2c, chip);
	mutex_init(&chip->io_lock);

	wake_lock_init(&(chip->irq_wake_lock), WAKE_LOCK_SUSPEND,
			"rt5033mfd_wakelock");

	ret = rt5033_clr_bits(i2c, 0x47, 1<<3);
	pr_info("Diable MANUAL RESET (%d)\n", ret);

	ret = rt5033_init_irq(chip);

	if (ret < 0) {
		dev_err(chip->dev,
				"Error : can't initialize RT5033 MFD irq\n");
		goto err_init_irq;
	}

#ifdef CONFIG_REGULATOR_RT5033
#if (LINUX_VERSION_CODE>=KERNEL_VERSION(3,6,0))
	ret = mfd_add_devices(chip->dev, 0, &rt5033_regulator_devs[0],
			ARRAY_SIZE(rt5033_regulator_devs),
			NULL, chip->irq_base, NULL);
#else
	ret = mfd_add_devices(chip->dev, 0, &rt5033_regulator_devs[0],
			ARRAY_SIZE(rt5033_regulator_devs),
			NULL, chip->irq_base);
#endif
	if (ret < 0) {
		dev_err(chip->dev,
				"Error : can't add regulator\n");
		goto err_add_regulator_devs;
	}
#endif /*CONFIG_REGULATOR_RT5033*/

#ifdef CONFIG_FLED_RT5033
#if (LINUX_VERSION_CODE>=KERNEL_VERSION(3,6,0))
	ret = mfd_add_devices(chip->dev, 0, &rt5033_fled_devs[0],
			ARRAY_SIZE(rt5033_fled_devs),
			NULL, chip->irq_base, NULL);
#else
	ret = mfd_add_devices(chip->dev, 0, &rt5033_fled_devs[0],
			ARRAY_SIZE(rt5033_fled_devs),
			NULL, chip->irq_base);
#endif
	if (ret < 0)
	{
		dev_err(chip->dev,"Failed : add FlashLED devices");
		goto err_add_fled_devs;
	}
#endif /*CONFIG_FLED_RT5033*/


#ifdef CONFIG_CHARGER_RT5033
#if (LINUX_VERSION_CODE>=KERNEL_VERSION(3,6,0))
	ret = mfd_add_devices(chip->dev, 0, &rt5033_charger_devs[0],
			ARRAY_SIZE(rt5033_charger_devs),
			NULL, chip->irq_base, NULL);
#else
	ret = mfd_add_devices(chip->dev, 0, &rt5033_charger_devs[0],
			ARRAY_SIZE(rt5033_charger_devs),
			NULL, chip->irq_base);
#endif
	if (ret<0) {
		dev_err(chip->dev, "Failed : add charger devices\n");
		goto err_add_chg_devs;
	}
#endif /*CONFIG_CHARGER_RT5033*/

	pr_info("%s : RT5033 MFD Driver Fin probe\n", __func__);
	return ret;

#ifdef CONFIG_CHARGER_RT5033
err_add_chg_devs:
#endif /*CONFIG_CHARGER_RT5033*/

#ifdef CONFIG_FLED_RT5033
err_add_fled_devs:
#endif /*CONFIG_FLED_RT5033*/
	mfd_remove_devices(chip->dev);
#ifdef CONFIG_REGULATOR_RT5033
err_add_regulator_devs:
#endif /*CONFIG_REGULATOR_RT5033*/
err_init_irq:
	wake_lock_destroy(&(chip->irq_wake_lock));
	mutex_destroy(&chip->io_lock);
	kfree(chip);
irq_base_err:
err_mfd_nomem:
err_i2cfunc_not_support:
	return ret;
}