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; }
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_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); }
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; }
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; }
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; }
/* 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; }
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; }
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_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; }
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; }