static void voltage_to_req(int uV, struct vreg *vreg) { if (vreg->part->uV.mask) SET_PART(vreg, uV, uV); else if (vreg->part->mV.mask) SET_PART(vreg, mV, MICRO_TO_MILLI(uV)); else if (vreg->part->enable_state.mask) SET_PART(vreg, enable_state, uV); else SET_PART(vreg, mV, MICRO_TO_MILLI(uV)); }
static void set_enable(struct vreg *vreg, unsigned int *mask, unsigned int *val) { switch (vreg->type) { case RPM_REGULATOR_TYPE_LDO: case RPM_REGULATOR_TYPE_SMPS: /* Enable by setting a voltage. */ if (vreg->part->uV.mask) { val[vreg->part->uV.word] |= vreg->save_uV << vreg->part->uV.shift; mask[vreg->part->uV.word] |= vreg->part->uV.mask; } else { val[vreg->part->mV.word] |= MICRO_TO_MILLI(vreg->save_uV) << vreg->part->mV.shift; mask[vreg->part->mV.word] |= vreg->part->mV.mask; } break; case RPM_REGULATOR_TYPE_VS: case RPM_REGULATOR_TYPE_NCP: /* Enable by setting enable_state. */ val[vreg->part->enable_state.word] |= RPM_VREG_STATE_ON << vreg->part->enable_state.shift; mask[vreg->part->enable_state.word] |= vreg->part->enable_state.mask; } }
int main(int argc, char* argv[]){ if(argc==1){ printUsage(argv[0]); exit(-1); } char options[]="l:t:h"; int flag; unsigned int blinks=3; float timeout=MICRO_TO_MILLI(20.0f); while((flag=getopt(argc, argv, options)) != -1){ switch(flag){ case 'h': printUsage(argv[0]); exit(-1); case 'l': blinks=atoi(optarg); break; case 't': timeout=MICRO_TO_MILLI(atof(optarg)); break; case '?': printUsage(argv[0]); exit(-1); default: printUsage(argv[0]); exit(-1); } } int i=0; for(i=0; blinks>i; i++){ writeToFile(&LIGHT_ON); //printf("on\n"); usleep(timeout); writeToFile(&LIGHT_OFF); //printf("off\n"); usleep(timeout); } //fclose(filePtr); }
static unsigned int vreg_get_optimum_mode(struct regulator_dev *rdev, int input_uV, int output_uV, int load_uA) { struct vreg *vreg = rdev_get_drvdata(rdev); unsigned int mode; load_uA += vreg->pdata.system_uA; mutex_lock(&vreg->pc_lock); SET_PART(vreg, ip, MICRO_TO_MILLI(saturate_peak_load(vreg, load_uA))); if (config->ia_follows_ip) SET_PART(vreg, ia, MICRO_TO_MILLI(saturate_avg_load(vreg, load_uA))); mutex_unlock(&vreg->pc_lock); if (load_uA >= vreg->hpm_min_load) mode = config->mode_hpm; else mode = config->mode_lpm; return mode; }
static unsigned int vreg_legacy_get_optimum_mode(struct regulator_dev *rdev, int input_uV, int output_uV, int load_uA) { struct vreg *vreg = rdev_get_drvdata(rdev); if (MICRO_TO_MILLI(load_uA) <= 0) { /* * vreg_legacy_get_optimum_mode is being called before consumers * have specified their load currents via * regulator_set_optimum_mode. Return whatever the existing mode * is. */ return vreg->mode; } return vreg_get_optimum_mode(rdev, input_uV, output_uV, load_uA); }
static int vreg_set_mode(struct regulator_dev *rdev, unsigned int mode) { struct vreg *vreg = rdev_get_drvdata(rdev); unsigned int mask[2] = {0}, val[2] = {0}; int rc = 0; int peak_uA; mutex_lock(&vreg->pc_lock); peak_uA = MILLI_TO_MICRO((vreg->req[vreg->part->ip.word].value & vreg->part->ip.mask) >> vreg->part->ip.shift); if (mode == config->mode_hpm) { /* Make sure that request currents are in HPM range. */ if (peak_uA < vreg_hpm_min_uA(vreg)) { val[vreg->part->ip.word] = MICRO_TO_MILLI(vreg_hpm_min_uA(vreg)) << vreg->part->ip.shift; mask[vreg->part->ip.word] = vreg->part->ip.mask; if (config->ia_follows_ip) { val[vreg->part->ia.word] |= MICRO_TO_MILLI(vreg_hpm_min_uA(vreg)) << vreg->part->ia.shift; mask[vreg->part->ia.word] |= vreg->part->ia.mask; } } } else if (mode == config->mode_lpm) { /* Make sure that request currents are in LPM range. */ if (peak_uA > vreg_lpm_max_uA(vreg)) { val[vreg->part->ip.word] = MICRO_TO_MILLI(vreg_lpm_max_uA(vreg)) << vreg->part->ip.shift; mask[vreg->part->ip.word] = vreg->part->ip.mask; if (config->ia_follows_ip) { val[vreg->part->ia.word] |= MICRO_TO_MILLI(vreg_lpm_max_uA(vreg)) << vreg->part->ia.shift; mask[vreg->part->ia.word] |= vreg->part->ia.mask; } } } else { vreg_err(vreg, "invalid mode: %u\n", mode); mutex_unlock(&vreg->pc_lock); return -EINVAL; } if (vreg->is_enabled) { rc = vreg_set(vreg, mask[0], val[0], mask[1], val[1], vreg->part->request_len); } else { /* Regulator is disabled; store but don't send new request. */ rc = vreg_store(vreg, mask[0], val[0], mask[1], val[1]); } if (rc) vreg_err(vreg, "vreg_set failed, rc=%d\n", rc); else vreg->mode = mode; mutex_unlock(&vreg->pc_lock); return rc; }
static int vreg_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, unsigned *selector) { struct vreg *vreg = rdev_get_drvdata(rdev); struct vreg_range *range = &vreg->set_points->range[0]; unsigned int mask[2] = {0}, val[2] = {0}; int rc = 0, uV = min_uV; int lim_min_uV, lim_max_uV, i; /* Check if request voltage is outside of physically settable range. */ lim_min_uV = vreg->set_points->range[0].min_uV; lim_max_uV = vreg->set_points->range[vreg->set_points->count - 1].max_uV; if (uV < lim_min_uV && max_uV >= lim_min_uV) uV = lim_min_uV; if (uV < lim_min_uV || uV > lim_max_uV) { vreg_err(vreg, "request v=[%d, %d] is outside possible v=[%d, %d]\n", min_uV, max_uV, lim_min_uV, lim_max_uV); return -EINVAL; } /* Find the range which uV is inside of. */ for (i = vreg->set_points->count - 1; i > 0; i--) { if (uV > vreg->set_points->range[i - 1].max_uV) { range = &vreg->set_points->range[i]; break; } } /* * Force uV to be an allowed set point and apply a ceiling function * to non-set point values. */ uV = (uV - range->min_uV + range->step_uV - 1) / range->step_uV; uV = uV * range->step_uV + range->min_uV; if (uV > max_uV) { vreg_err(vreg, "request v=[%d, %d] cannot be met by any set point; " "next set point: %d\n", min_uV, max_uV, uV); return -EINVAL; } if (vreg->part->uV.mask) { val[vreg->part->uV.word] = uV << vreg->part->uV.shift; mask[vreg->part->uV.word] = vreg->part->uV.mask; } else { val[vreg->part->mV.word] = MICRO_TO_MILLI(uV) << vreg->part->mV.shift; mask[vreg->part->mV.word] = vreg->part->mV.mask; } mutex_lock(&vreg->pc_lock); /* * Only send a request for a new voltage if the regulator is currently * enabled. This will ensure that LDO and SMPS regulators are not * inadvertently turned on because voltage > 0 is equivalent to * enabling. For NCP, this just removes unnecessary RPM requests. */ if (vreg->is_enabled) { rc = vreg_set(vreg, mask[0], val[0], mask[1], val[1], vreg->part->request_len); if (rc) vreg_err(vreg, "vreg_set failed, rc=%d\n", rc); } else if (vreg->type == RPM_REGULATOR_TYPE_NCP) { /* Regulator is disabled; store but don't send new request. */ rc = vreg_store(vreg, mask[0], val[0], mask[1], val[1]); } if (!rc && (!vreg->pdata.sleep_selectable || !vreg->is_enabled)) vreg->save_uV = uV; mutex_unlock(&vreg->pc_lock); return rc; }
/** * rpm_vreg_set_voltage - vote for a min_uV value of specified regualtor * @vreg: ID for regulator * @voter: ID for the voter * @min_uV: minimum acceptable voltage (in uV) that is voted for * @max_uV: maximum acceptable voltage (in uV) that is voted for * @sleep_also: 0 for active set only, non-0 for active set and sleep set * * Returns 0 on success or errno. * * This function is used to vote for the voltage of a regulator without * using the regulator framework. It is needed by consumers which hold spin * locks or have interrupts disabled because the regulator framework can sleep. * It is also needed by consumers which wish to only vote for active set * regulator voltage. * * If sleep_also == 0, then a sleep-set value of 0V will be voted for. * * This function may only be called for regulators which have the sleep flag * specified in their private data. * * Consumers can vote to disable a regulator with this function by passing * min_uV = 0 and max_uV = 0. */ int rpm_vreg_set_voltage(int vreg_id, enum rpm_vreg_voter voter, int min_uV, int max_uV, int sleep_also) { unsigned int mask[2] = {0}, val[2] = {0}; struct vreg_range *range; struct vreg *vreg; int uV = min_uV; int lim_min_uV, lim_max_uV, i, rc; /* * HACK: make this function a no-op for 8064 so that it can be called by * consumers on 8064 before RPM capabilities are present. (needed for * acpuclock driver) */ if (cpu_is_apq8064()) return 0; if (!config) { pr_err("rpm-regulator driver has not probed yet.\n"); return -ENODEV; } if (vreg_id < config->vreg_id_min || vreg_id > config->vreg_id_max) { pr_err("invalid regulator id=%d\n", vreg_id); return -EINVAL; } vreg = &config->vregs[vreg_id]; range = &vreg->set_points->range[0]; if (!vreg->pdata.sleep_selectable) { vreg_err(vreg, "regulator is not marked sleep selectable\n"); return -EINVAL; } /* Allow min_uV == max_uV == 0 to represent a disable request. */ if (min_uV != 0 || max_uV != 0) { /* * Check if request voltage is outside of allowed range. The * regulator core has already checked that constraint range * is inside of the physically allowed range. */ lim_min_uV = vreg->pdata.init_data.constraints.min_uV; lim_max_uV = vreg->pdata.init_data.constraints.max_uV; if (uV < lim_min_uV && max_uV >= lim_min_uV) uV = lim_min_uV; if (uV < lim_min_uV || uV > lim_max_uV) { vreg_err(vreg, "request v=[%d, %d] is outside allowed " "v=[%d, %d]\n", min_uV, max_uV, lim_min_uV, lim_max_uV); return -EINVAL; } /* Find the range which uV is inside of. */ for (i = vreg->set_points->count - 1; i > 0; i--) { if (uV > vreg->set_points->range[i - 1].max_uV) { range = &vreg->set_points->range[i]; break; } } /* * Force uV to be an allowed set point and apply a ceiling * function to non-set point values. */ uV = (uV - range->min_uV + range->step_uV - 1) / range->step_uV; uV = uV * range->step_uV + range->min_uV; if (uV > max_uV) { vreg_err(vreg, "request v=[%d, %d] cannot be met by any set point; " "next set point: %d\n", min_uV, max_uV, uV); return -EINVAL; } } if (vreg->part->uV.mask) { val[vreg->part->uV.word] = uV << vreg->part->uV.shift; mask[vreg->part->uV.word] = vreg->part->uV.mask; } else { val[vreg->part->mV.word] = MICRO_TO_MILLI(uV) << vreg->part->mV.shift; mask[vreg->part->mV.word] = vreg->part->mV.mask; } rc = vreg_set_noirq(vreg, voter, sleep_also, mask[0], val[0], mask[1], val[1], vreg->part->request_len, 1); if (rc) vreg_err(vreg, "vreg_set_noirq failed, rc=%d\n", rc); return rc; }
static int __devinit rpm_vreg_init_regulator(const struct rpm_regulator_init_data *pdata, struct device *dev) { struct regulator_desc *rdesc = NULL; struct regulator_dev *rdev; struct vreg *vreg; unsigned pin_ctrl; int id, pin_fn; int rc = 0; if (!pdata) { pr_err("platform data missing\n"); return -EINVAL; } id = pdata->id; if (id < config->vreg_id_min || id > config->vreg_id_max) { pr_err("invalid regulator id: %d\n", id); return -ENODEV; } if (!config->is_real_id(pdata->id)) id = config->pc_id_to_real_id(pdata->id); vreg = &config->vregs[id]; if (config->is_real_id(pdata->id)) rdesc = &vreg->rdesc; else rdesc = &vreg->rdesc_pc; if (vreg->type < 0 || vreg->type > RPM_REGULATOR_TYPE_MAX) { pr_err("%s: invalid regulator type: %d\n", vreg->rdesc.name, vreg->type); return -EINVAL; } mutex_lock(&vreg->pc_lock); if (vreg->set_points) rdesc->n_voltages = vreg->set_points->n_voltages; else rdesc->n_voltages = 0; rdesc->id = pdata->id; rdesc->owner = THIS_MODULE; rdesc->type = REGULATOR_VOLTAGE; if (config->is_real_id(pdata->id)) { /* * Real regulator; do not modify pin control and pin function * values. */ rdesc->ops = vreg_ops[vreg->type]; pin_ctrl = vreg->pdata.pin_ctrl; pin_fn = vreg->pdata.pin_fn; memcpy(&(vreg->pdata), pdata, sizeof(struct rpm_regulator_init_data)); vreg->pdata.pin_ctrl = pin_ctrl; vreg->pdata.pin_fn = pin_fn; vreg->save_uV = vreg->pdata.default_uV; if (vreg->pdata.peak_uA >= vreg->hpm_min_load) vreg->mode = config->mode_hpm; else vreg->mode = config->mode_lpm; /* Initialize the RPM request. */ SET_PART(vreg, ip, MICRO_TO_MILLI(saturate_peak_load(vreg, vreg->pdata.peak_uA))); SET_PART(vreg, fm, vreg->pdata.force_mode); SET_PART(vreg, pm, vreg->pdata.power_mode); SET_PART(vreg, pd, vreg->pdata.pull_down_enable); SET_PART(vreg, ia, MICRO_TO_MILLI(saturate_avg_load(vreg, vreg->pdata.avg_uA))); SET_PART(vreg, freq, vreg->pdata.freq); SET_PART(vreg, freq_clk_src, 0); SET_PART(vreg, comp_mode, 0); SET_PART(vreg, hpm, 0); if (!vreg->is_enabled_pc) { SET_PART(vreg, pf, config->pin_func_none); SET_PART(vreg, pc, RPM_VREG_PIN_CTRL_NONE); } } else { if ((pdata->pin_ctrl & RPM_VREG_PIN_CTRL_ALL) == RPM_VREG_PIN_CTRL_NONE && pdata->pin_fn != config->pin_func_sleep_b) { pr_err("%s: no pin control input specified\n", vreg->rdesc.name); mutex_unlock(&vreg->pc_lock); return -EINVAL; } rdesc->ops = &pin_control_ops; vreg->pdata.pin_ctrl = pdata->pin_ctrl; vreg->pdata.pin_fn = pdata->pin_fn; /* Initialize the RPM request. */ pin_fn = config->pin_func_none; /* Allow pf=sleep_b to be specified by platform data. */ if (vreg->pdata.pin_fn == config->pin_func_sleep_b) pin_fn = config->pin_func_sleep_b; SET_PART(vreg, pf, pin_fn); SET_PART(vreg, pc, RPM_VREG_PIN_CTRL_NONE); } mutex_unlock(&vreg->pc_lock); if (rc) goto bail; rdev = regulator_register(rdesc, dev, &(pdata->init_data), vreg); if (IS_ERR(rdev)) { rc = PTR_ERR(rdev); pr_err("regulator_register failed: %s, rc=%d\n", vreg->rdesc.name, rc); return rc; } else { if (config->is_real_id(pdata->id)) vreg->rdev = rdev; else vreg->rdev_pc = rdev; } bail: if (rc) pr_err("error for %s, rc=%d\n", vreg->rdesc.name, rc); return rc; }