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); }
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; }
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); }
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); }
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; }