struct fan53555_device_info { enum fan53555_vendor vendor; struct device *dev; struct regulator_desc desc; struct regulator_init_data *regulator; /* IC Type and Rev */ int chip_id; int chip_rev; /* Voltage setting register */ unsignedint vol_reg; unsignedint sleep_reg; unsignedint en_reg; unsignedint sleep_en_reg; /* Voltage range and step(linear) */ unsignedint vsel_min; unsignedint vsel_step; unsignedint vsel_count; /* Mode */ unsignedint mode_reg; unsignedint mode_mask; /* Sleep voltage cache */ unsignedint sleep_vol_cache; /* Slew rate */ unsignedint slew_reg; unsignedint slew_mask; constunsignedint *ramp_delay_table; unsignedint n_ramp_values; unsignedint enable_time; unsignedint slew_rate;
};
staticint fan53555_set_suspend_voltage(struct regulator_dev *rdev, int uV)
{ struct fan53555_device_info *di = rdev_get_drvdata(rdev); int ret;
if (di->sleep_vol_cache == uV) return 0;
ret = regulator_map_voltage_linear(rdev, uV, uV); if (ret < 0) return ret;
ret = regmap_update_bits(rdev->regmap, di->sleep_reg,
di->desc.vsel_mask, ret); if (ret < 0) return ret; /* Cache the sleep voltage setting.
* Might not be the real voltage which is rounded */
di->sleep_vol_cache = uV;
/* Init voltage range and step */
di->vsel_min = 600000;
di->vsel_step = 6250;
di->vsel_count = FAN53526_NVOLTAGES; break; default:
dev_err(di->dev, "Chip ID %d not supported!\n", di->chip_id); return -EINVAL;
}
return 0;
}
/* For 00,01,03,05 options: * VOUT = 0.60V + NSELx * 10mV, from 0.60 to 1.23V. * For 04 option: * VOUT = 0.603V + NSELx * 12.826mV, from 0.603 to 1.411V.
* */ staticint fan53555_device_setup(struct fan53555_device_info *di, struct fan53555_platform_data *pdata)
{ int ret = 0;
/* Setup voltage control register */ switch (di->vendor) { case FAN53526_VENDOR_FAIRCHILD: case FAN53555_VENDOR_FAIRCHILD: case FAN53555_VENDOR_ROCKCHIP: case FAN53555_VENDOR_SILERGY: switch (pdata->sleep_vsel_id) { case FAN53555_VSEL_ID_0:
di->sleep_reg = FAN53555_VSEL0;
di->vol_reg = FAN53555_VSEL1; break; case FAN53555_VSEL_ID_1:
di->sleep_reg = FAN53555_VSEL1;
di->vol_reg = FAN53555_VSEL0; break; default:
dev_err(di->dev, "Invalid VSEL ID!\n"); return -EINVAL;
}
di->sleep_en_reg = di->sleep_reg;
di->en_reg = di->vol_reg; break; case RK8602_VENDOR_ROCKCHIP: switch (pdata->sleep_vsel_id) { case FAN53555_VSEL_ID_0:
di->sleep_reg = RK8602_VSEL0;
di->vol_reg = RK8602_VSEL1;
di->sleep_en_reg = FAN53555_VSEL0;
di->en_reg = FAN53555_VSEL1; break; case FAN53555_VSEL_ID_1:
di->sleep_reg = RK8602_VSEL1;
di->vol_reg = RK8602_VSEL0;
di->sleep_en_reg = FAN53555_VSEL1;
di->en_reg = FAN53555_VSEL0; break; default:
dev_err(di->dev, "Invalid VSEL ID!\n"); return -EINVAL;
} break; case FAN53526_VENDOR_TCS: switch (pdata->sleep_vsel_id) { case FAN53555_VSEL_ID_0:
di->sleep_reg = TCS4525_VSEL0;
di->vol_reg = TCS4525_VSEL1; break; case FAN53555_VSEL_ID_1:
di->sleep_reg = TCS4525_VSEL1;
di->vol_reg = TCS4525_VSEL0; break; default:
dev_err(di->dev, "Invalid VSEL ID!\n"); return -EINVAL;
}
di->sleep_en_reg = di->sleep_reg;
di->en_reg = di->vol_reg; break; default:
dev_err(di->dev, "vendor %d not supported!\n", di->vendor); return -EINVAL;
}
/* Setup mode control register */ switch (di->vendor) { case FAN53526_VENDOR_FAIRCHILD:
di->mode_reg = FAN53555_CONTROL;
switch (pdata->sleep_vsel_id) { case FAN53555_VSEL_ID_0:
di->mode_mask = CTL_MODE_VSEL1_MODE; break; case FAN53555_VSEL_ID_1:
di->mode_mask = CTL_MODE_VSEL0_MODE; break;
} break; case FAN53555_VENDOR_FAIRCHILD: case FAN53555_VENDOR_ROCKCHIP: case FAN53555_VENDOR_SILERGY:
di->mode_reg = di->vol_reg;
di->mode_mask = VSEL_MODE; break; case RK8602_VENDOR_ROCKCHIP:
di->mode_mask = VSEL_MODE;
switch (pdata->sleep_vsel_id) { case FAN53555_VSEL_ID_0:
di->mode_reg = FAN53555_VSEL1; break; case FAN53555_VSEL_ID_1:
di->mode_reg = FAN53555_VSEL0; break;
} break; case FAN53526_VENDOR_TCS:
di->mode_reg = TCS4525_COMMAND;
switch (pdata->sleep_vsel_id) { case FAN53555_VSEL_ID_0:
di->mode_mask = TCS_VSEL1_MODE; break; case FAN53555_VSEL_ID_1:
di->mode_mask = TCS_VSEL0_MODE; break;
} break; default:
dev_err(di->dev, "vendor %d not supported!\n", di->vendor); return -EINVAL;
}
/* Setup voltage range */ switch (di->vendor) { case FAN53526_VENDOR_FAIRCHILD:
ret = fan53526_voltages_setup_fairchild(di); break; case FAN53555_VENDOR_FAIRCHILD:
ret = fan53555_voltages_setup_fairchild(di); break; case FAN53555_VENDOR_ROCKCHIP:
ret = fan53555_voltages_setup_rockchip(di); break; case RK8602_VENDOR_ROCKCHIP:
ret = rk8602_voltages_setup_rockchip(di); break; case FAN53555_VENDOR_SILERGY:
ret = fan53555_voltages_setup_silergy(di); break; case FAN53526_VENDOR_TCS:
ret = fan53526_voltages_setup_tcs(di); break; default:
dev_err(di->dev, "vendor %d not supported!\n", di->vendor); return -EINVAL;
}
di = devm_kzalloc(&client->dev, sizeof(struct fan53555_device_info),
GFP_KERNEL); if (!di) return -ENOMEM;
pdata = dev_get_platdata(&client->dev); if (!pdata)
pdata = fan53555_parse_dt(&client->dev, np, &di->desc);
if (!pdata || !pdata->regulator) return dev_err_probe(&client->dev, -ENODEV, "Platform data not found!\n");
di->regulator = pdata->regulator;
di->vendor = (uintptr_t)i2c_get_match_data(client); if (!dev_fwnode(&client->dev)) { /* if no ramp constraint set, get the pdata ramp_delay */ if (!di->regulator->constraints.ramp_delay) { if (pdata->slew_rate >= ARRAY_SIZE(slew_rates)) return dev_err_probe(&client->dev, -EINVAL, "Invalid slew_rate\n");
regmap = devm_regmap_init_i2c(client, &fan53555_regmap_config); if (IS_ERR(regmap)) return dev_err_probe(&client->dev, PTR_ERR(regmap), "Failed to allocate regmap!\n");
di->dev = &client->dev;
i2c_set_clientdata(client, di); /* Get chip ID */
ret = regmap_read(regmap, FAN53555_ID1, &val); if (ret < 0) return dev_err_probe(&client->dev, ret, "Failed to get chip ID!\n");
di->chip_id = val & DIE_ID; /* Get chip revision */
ret = regmap_read(regmap, FAN53555_ID2, &val); if (ret < 0) return dev_err_probe(&client->dev, ret, "Failed to get chip Rev!\n");
di->chip_rev = val & DIE_REV;
dev_info(&client->dev, "FAN53555 Option[%d] Rev[%d] Detected!\n",
di->chip_id, di->chip_rev); /* Device init */
ret = fan53555_device_setup(di, pdata); if (ret < 0) return dev_err_probe(&client->dev, ret, "Failed to setup device!\n");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.