#define PMBUS_USE_COEFFICIENTS_CMD BIT(5)
+ #define PMBUS_OP_PROTECTED BIT(6)
+
+ #define PMBUS_VOUT_PROTECTED BIT(7)
+
struct pmbus_platform_data {
u32 flags; /* Device specific flags */
When this flag is set the PMBus core driver will use the COEFFICIENTS
register to initialize the coefficients for the direct mode format.
+
+PMBUS_OP_PROTECTED
+
+Set if the chip OPERATION command is protected and protection is not
+determined by the standard WRITE_PROTECT command.
+
+PMBUS_VOUT_PROTECTED
+
+Set if the chip VOUT_COMMAND command is protected and protection is not
+determined by the standard WRITE_PROTECT command.
/* Regulator ops */
extern const struct regulator_ops pmbus_regulator_ops;
+int pmbus_regulator_init_cb(struct regulator_dev *rdev,
+ struct regulator_config *config);
/* Macros for filling in array of struct regulator_desc */
#define PMBUS_REGULATOR_STEP(_name, _id, _voltages, _step, _min_uV) \
.n_voltages = _voltages, \
.uV_step = _step, \
.min_uV = _min_uV, \
+ .init_cb = pmbus_regulator_init_cb, \
}
#define PMBUS_REGULATOR(_name, _id) PMBUS_REGULATOR_STEP(_name, _id, 0, 0, 0)
.n_voltages = _voltages, \
.uV_step = _step, \
.min_uV = _min_uV, \
+ .init_cb = pmbus_regulator_init_cb, \
}
#define PMBUS_REGULATOR_ONE(_name) PMBUS_REGULATOR_STEP_ONE(_name, 0, 0, 0)
device_remove_file(dev, &dev_attr_pec);
}
+static void pmbus_init_wp(struct i2c_client *client, struct pmbus_data *data)
+{
+ int ret;
+
+ ret = _pmbus_read_byte_data(client, -1, PMBUS_WRITE_PROTECT);
+ if (ret < 0)
+ return;
+
+ switch (ret & PB_WP_ANY) {
+ case PB_WP_ALL:
+ data->flags |= PMBUS_OP_PROTECTED;
+ fallthrough;
+ case PB_WP_OP:
+ data->flags |= PMBUS_VOUT_PROTECTED;
+ fallthrough;
+ case PB_WP_VOUT:
+ data->flags |= PMBUS_WRITE_PROTECTED | PMBUS_SKIP_STATUS_CHECK;
+ break;
+
+ default:
+ break;
+ }
+}
+
static int pmbus_init_common(struct i2c_client *client, struct pmbus_data *data,
struct pmbus_driver_info *info)
{
* faults, and we should not try it. Also, in that case, writes into
* limit registers need to be disabled.
*/
- if (!(data->flags & PMBUS_NO_WRITE_PROTECT)) {
- ret = _pmbus_read_byte_data(client, -1, PMBUS_WRITE_PROTECT);
-
- if (ret > 0 && (ret & PB_WP_ANY))
- data->flags |= PMBUS_WRITE_PROTECTED | PMBUS_SKIP_STATUS_CHECK;
- }
+ if (!(data->flags & PMBUS_NO_WRITE_PROTECT))
+ pmbus_init_wp(client, data);
ret = i2c_smbus_read_byte_data(client, PMBUS_REVISION);
if (ret >= 0)
{
struct device *dev = rdev_get_dev(rdev);
struct i2c_client *client = to_i2c_client(dev->parent);
+ struct pmbus_data *data = i2c_get_clientdata(client);
int val, low, high;
+ if (data->flags & PMBUS_VOUT_PROTECTED)
+ return 0;
+
if (selector >= rdev->desc->n_voltages ||
selector < rdev->desc->linear_min_sel)
return -EINVAL;
};
EXPORT_SYMBOL_NS_GPL(pmbus_regulator_ops, "PMBUS");
+int pmbus_regulator_init_cb(struct regulator_dev *rdev,
+ struct regulator_config *config)
+{
+ struct pmbus_data *data = config->driver_data;
+ struct regulation_constraints *constraints = rdev->constraints;
+
+ if (data->flags & PMBUS_OP_PROTECTED)
+ constraints->valid_ops_mask &= ~REGULATOR_CHANGE_STATUS;
+
+ if (data->flags & PMBUS_VOUT_PROTECTED)
+ constraints->valid_ops_mask &= ~REGULATOR_CHANGE_VOLTAGE;
+
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(pmbus_regulator_init_cb, "PMBUS");
+
static int pmbus_regulator_register(struct pmbus_data *data)
{
struct device *dev = data->dev;
*/
#define PMBUS_USE_COEFFICIENTS_CMD BIT(5)
+/*
+ * PMBUS_OP_PROTECTED
+ * Set if the chip OPERATION command is protected and protection is not
+ * determined by the standard WRITE_PROTECT command.
+ */
+#define PMBUS_OP_PROTECTED BIT(6)
+
+/*
+ * PMBUS_VOUT_PROTECTED
+ * Set if the chip VOUT_COMMAND command is protected and protection is not
+ * determined by the standard WRITE_PROTECT command.
+ */
+#define PMBUS_VOUT_PROTECTED BIT(7)
+
struct pmbus_platform_data {
u32 flags; /* Device specific flags */