int qpnp_vib_set(struct qpnp_vib *vib, int on) { int rc; u8 val; if (on) { val = vib->reg_vtg_ctl; val &= ~QPNP_VIB_VTG_SET_MASK; val |= (vib->vtg_level & QPNP_VIB_VTG_SET_MASK); rc = qpnp_vib_write_u8(vib, &val, QPNP_VIB_VTG_CTL(vib->base)); if (rc < 0) return rc; vib->reg_vtg_ctl = val; val = vib->reg_en_ctl; val |= QPNP_VIB_EN; rc = qpnp_vib_write_u8(vib, &val, QPNP_VIB_EN_CTL(vib->base)); if (rc < 0) return rc; vib->reg_en_ctl = val; } else { val = vib->reg_en_ctl; val &= ~QPNP_VIB_EN; rc = qpnp_vib_write_u8(vib, &val, QPNP_VIB_EN_CTL(vib->base)); if (rc < 0) return rc; vib->reg_en_ctl = val; } return rc; }
/* Begin Immersion changes */ int qpnp_vib_set_with_vtglevel(struct qpnp_vib *vib, int vtglevel, int on) { int rc; u8 val; if(vtglevel < QPNP_VIB_MIN_LEVEL) vtglevel = QPNP_VIB_MIN_LEVEL; if(vtglevel > QPNP_VIB_MAX_LEVEL) vtglevel = QPNP_VIB_MAX_LEVEL; if (on) { val = vib->reg_vtg_ctl; val &= ~QPNP_VIB_VTG_SET_MASK; val |= (vtglevel & QPNP_VIB_VTG_SET_MASK); rc = qpnp_vib_write_u8(vib, &val, QPNP_VIB_VTG_CTL(vib->base)); if (rc < 0) return rc; vib->reg_vtg_ctl = val; val = vib->reg_en_ctl; val |= QPNP_VIB_EN; rc = qpnp_vib_write_u8(vib, &val, QPNP_VIB_EN_CTL(vib->base)); if (rc < 0) return rc; vib->reg_en_ctl = val; } else { val = vib->reg_en_ctl; val &= ~QPNP_VIB_EN; rc = qpnp_vib_write_u8(vib, &val, QPNP_VIB_EN_CTL(vib->base)); if (rc < 0) return rc; vib->reg_en_ctl = val; } return rc; }
static int qpnp_vib_set(struct qpnp_vib *vib, int on) { int rc; u8 val; if (on) { if (vib->mode != QPNP_VIB_MANUAL) pwm_enable(vib->pwm_info.pwm_dev); else { val = vib->reg_en_ctl; val |= QPNP_VIB_EN; rc = qpnp_vib_write_u8(vib, &val, QPNP_VIB_EN_CTL(vib->base)); if (rc < 0) return rc; vib->reg_en_ctl = val; } } else { if (vib->mode != QPNP_VIB_MANUAL) pwm_disable(vib->pwm_info.pwm_dev); else { val = vib->reg_en_ctl; val &= ~QPNP_VIB_EN; rc = qpnp_vib_write_u8(vib, &val, QPNP_VIB_EN_CTL(vib->base)); if (rc < 0) return rc; vib->reg_en_ctl = val; } } return 0; }
static int qpnp_vib_set(struct qpnp_vib *vib, int on) { int rc; u8 val; if (on) { val = vib->reg_vtg_ctl; val &= ~QPNP_VIB_VTG_SET_MASK; val |= (vib->vtg_level & QPNP_VIB_VTG_SET_MASK); printk(KERN_INFO "[VIB] on, reg0=0x%x.\n", val); rc = qpnp_vib_write_u8(vib, &val, QPNP_VIB_VTG_CTL(vib->base)); if (rc < 0) return rc; vib->reg_vtg_ctl = val; val = vib->reg_en_ctl; val |= QPNP_VIB_EN; printk(KERN_INFO "[VIB] on, reg1=0x%x.\n", val); rc = qpnp_vib_write_u8(vib, &val, QPNP_VIB_EN_CTL(vib->base)); if (rc < 0) return rc; vib->reg_en_ctl = val; } else { val = vib->reg_en_ctl; val &= ~QPNP_VIB_EN; printk(KERN_INFO "[VIB] off, reg1=0x%x.\n", val); rc = qpnp_vib_write_u8(vib, &val, QPNP_VIB_EN_CTL(vib->base)); if (rc < 0) return rc; vib->reg_en_ctl = val; } return rc; }
static int qpnp_vib_set(struct qpnp_vib *vib, int on) { int rc; u8 val; if (on) { val = vib->reg_vtg_ctl; val &= ~QPNP_VIB_VTG_SET_MASK; val |= (vib->vtg_level & QPNP_VIB_VTG_SET_MASK); rc = qpnp_vib_write_u8(vib, &val, QPNP_VIB_VTG_CTL(vib->base)); if (rc < 0) return rc; vib->reg_vtg_ctl = val; val = vib->reg_en_ctl; val |= QPNP_VIB_EN; rc = qpnp_vib_write_u8(vib, &val, QPNP_VIB_EN_CTL(vib->base)); #ifdef CONFIG_QPNP_SCVIBRATOR if (rc < 0) { return rc; } else { #ifdef CONFIG_SHTERM shterm_k_set_info( SHTERM_INFO_VIB, 1 ); #endif /* CONFIG_SHTERM */ } #else /* CONFIG_QPNP_SCVIBRATOR */ if (rc < 0) return rc; #endif /* CONFIG_QPNP_SCVIBRATOR */ vib->reg_en_ctl = val; } else { val = vib->reg_en_ctl; val &= ~QPNP_VIB_EN; rc = qpnp_vib_write_u8(vib, &val, QPNP_VIB_EN_CTL(vib->base)); #ifdef CONFIG_QPNP_SCVIBRATOR if (rc < 0) { return rc; } else { #ifdef CONFIG_SHTERM shterm_k_set_info( SHTERM_INFO_VIB, 0 ); #endif /* CONFIG_SHTERM */ } #else /* CONFIG_QPNP_SCVIBRATOR */ if (rc < 0) return rc; #endif /* CONFIG_QPNP_SCVIBRATOR */ vib->reg_en_ctl = val; } return rc; }
static int qpnp_vibrator_config(struct qpnp_vib *vib) { u8 reg = 0; int rc; /* Configure the VTG CTL regiser */ rc = qpnp_vib_read_u8(vib, ®, QPNP_VIB_VTG_CTL(vib->base)); if (rc < 0) return rc; reg &= ~QPNP_VIB_VTG_SET_MASK; reg |= (vib->vtg_level & QPNP_VIB_VTG_SET_MASK); rc = qpnp_vib_write_u8(vib, ®, QPNP_VIB_VTG_CTL(vib->base)); if (rc) return rc; vib->reg_vtg_ctl = reg; /* Configure the VIB ENABLE regiser */ rc = qpnp_vib_read_u8(vib, ®, QPNP_VIB_EN_CTL(vib->base)); if (rc < 0) return rc; reg |= (!!vib->active_low) << QPNP_VIB_LOGIC_SHIFT; if (vib->mode != QPNP_VIB_MANUAL) { vib->pwm_info.pwm_dev = pwm_request(vib->pwm_info.pwm_channel, "qpnp-vib"); if (IS_ERR_OR_NULL(vib->pwm_info.pwm_dev)) { dev_err(&vib->spmi->dev, "vib pwm request failed\n"); return -ENODEV; } rc = pwm_config(vib->pwm_info.pwm_dev, vib->pwm_info.duty_us, vib->pwm_info.period_us); if (rc < 0) { dev_err(&vib->spmi->dev, "vib pwm config failed\n"); pwm_free(vib->pwm_info.pwm_dev); return -ENODEV; } reg |= BIT(vib->mode - 1); } rc = qpnp_vib_write_u8(vib, ®, QPNP_VIB_EN_CTL(vib->base)); if (rc < 0) return rc; vib->reg_en_ctl = reg; return rc; }
int qpnp_vibrator_config(struct qpnp_vib_config *vib_cfg) { u8 reg = 0; int rc = -EINVAL, level; if (!vib_dev) { pr_err("%s: vib_dev is NULL\n", __func__); rc = -ENODEV; goto gen_err; } level = vib_cfg->drive_mV / QPNP_VIB_UV_PER_MV; if (level) { if ((level < QPNP_VIB_MIN_LEVEL) || (level > QPNP_VIB_MAX_LEVEL)) { dev_err(&vib_dev->spmi->dev, "Invalid voltage level\n"); goto gen_err; } } else { dev_err(&vib_dev->spmi->dev, "Voltage level not specified\n"); goto gen_err; } /* Configure the VTG CTL regiser */ reg = vib_dev->reg_vtg_ctl; reg &= ~QPNP_VIB_VTG_SET_MASK; reg |= (level & QPNP_VIB_VTG_SET_MASK); rc = qpnp_vib_write_u8(vib_dev, ®, QPNP_VIB_VTG_CTL(vib_dev->base)); if (rc) goto gen_err; vib_dev->reg_vtg_ctl = reg; /* Configure the VIB ENABLE regiser */ reg = vib_dev->reg_en_ctl; reg |= (!!vib_cfg->active_low) << QPNP_VIB_LOGIC_SHIFT; if (vib_cfg->enable_mode == QPNP_VIB_MANUAL) reg |= QPNP_VIB_EN; else reg |= BIT(vib_cfg->enable_mode - 1); rc = qpnp_vib_write_u8(vib_dev, ®, QPNP_VIB_EN_CTL(vib_dev->base)); if (rc < 0) goto gen_err; vib_dev->reg_en_ctl = reg; gen_err: return rc; }
static int qpnp_vib_set(struct qpnp_vib *vib, int on) { int rc; u8 val; if (on) { if (vib->mode != QPNP_VIB_MANUAL) { printk(KERN_INFO "[VIB] on, pwm_enable\n"); pwm_enable(vib->pwm_info.pwm_dev); } else { printk(KERN_INFO "[VIB] on, reg0=0x%x.\n", vib->vtg_level); val = vib->reg_en_ctl; val |= QPNP_VIB_EN; printk(KERN_INFO "[VIB] on, reg1=0x%x.\n", val); rc = qpnp_vib_write_u8(vib, &val, QPNP_VIB_EN_CTL(vib->base)); if (rc < 0) return rc; vib->reg_en_ctl = val; } } else { if (vib->mode != QPNP_VIB_MANUAL) { printk(KERN_INFO "[VIB] off, pwm_enable\n"); pwm_disable(vib->pwm_info.pwm_dev); } else { val = vib->reg_en_ctl; val &= ~QPNP_VIB_EN; printk(KERN_INFO "[VIB] off, reg1=0x%x.\n", val); rc = qpnp_vib_write_u8(vib, &val, QPNP_VIB_EN_CTL(vib->base)); if (rc < 0) return rc; vib->reg_en_ctl = val; } } return 0; }
static ssize_t qpnp_vib_level_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct timed_output_dev *tdev = dev_get_drvdata(dev); struct qpnp_vib *vib = container_of(tdev, struct qpnp_vib, timed_dev); int val; int rc; u8 reg = 0; rc = kstrtoint(buf, 10, &val); if (rc) { pr_err("%s: error getting level\n", __func__); return -EINVAL; } if (val < QPNP_VIB_MIN_LEVEL) { pr_err("%s: level %d not in range (%d - %d), using min.", __func__, val, QPNP_VIB_MIN_LEVEL, QPNP_VIB_MAX_LEVEL); val = QPNP_VIB_MIN_LEVEL; } else if (val > QPNP_VIB_MAX_LEVEL) { pr_err("%s: level %d not in range (%d - %d), using max.", __func__, val, QPNP_VIB_MIN_LEVEL, QPNP_VIB_MAX_LEVEL); val = QPNP_VIB_MAX_LEVEL; } vib->vtg_level = val; /* Configure the VTG CTL regiser */ rc = qpnp_vib_read_u8(vib, ®, QPNP_VIB_VTG_CTL(vib->base)); if (rc < 0) { pr_info("qpnp: error while reading vibration control register\n"); } reg &= ~QPNP_VIB_VTG_SET_MASK; reg |= (vib->vtg_level & QPNP_VIB_VTG_SET_MASK); rc = qpnp_vib_write_u8(vib, ®, QPNP_VIB_VTG_CTL(vib->base)); if (rc) pr_info("qpnp: error while writing vibration control register\n"); return strnlen(buf, count); }