Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Hardware monitoring driver for Renesas Digital Multiphase Voltage Regulators
0004  *
0005  * Copyright (c) 2017 Google Inc
0006  * Copyright (c) 2020 Renesas Electronics America
0007  *
0008  */
0009 
0010 #include <linux/err.h>
0011 #include <linux/hwmon-sysfs.h>
0012 #include <linux/i2c.h>
0013 #include <linux/init.h>
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/string.h>
0017 #include <linux/sysfs.h>
0018 
0019 #include "pmbus.h"
0020 
0021 #define ISL68137_VOUT_AVS   0x30
0022 #define RAA_DMPVR2_READ_VMON    0xc8
0023 
0024 enum chips {
0025     isl68137,
0026     isl68220,
0027     isl68221,
0028     isl68222,
0029     isl68223,
0030     isl68224,
0031     isl68225,
0032     isl68226,
0033     isl68227,
0034     isl68229,
0035     isl68233,
0036     isl68239,
0037     isl69222,
0038     isl69223,
0039     isl69224,
0040     isl69225,
0041     isl69227,
0042     isl69228,
0043     isl69234,
0044     isl69236,
0045     isl69239,
0046     isl69242,
0047     isl69243,
0048     isl69247,
0049     isl69248,
0050     isl69254,
0051     isl69255,
0052     isl69256,
0053     isl69259,
0054     isl69260,
0055     isl69268,
0056     isl69269,
0057     isl69298,
0058     raa228000,
0059     raa228004,
0060     raa228006,
0061     raa228228,
0062     raa229001,
0063     raa229004,
0064 };
0065 
0066 enum variants {
0067     raa_dmpvr1_2rail,
0068     raa_dmpvr2_1rail,
0069     raa_dmpvr2_2rail,
0070     raa_dmpvr2_2rail_nontc,
0071     raa_dmpvr2_3rail,
0072     raa_dmpvr2_hv,
0073 };
0074 
0075 static const struct i2c_device_id raa_dmpvr_id[];
0076 
0077 static ssize_t isl68137_avs_enable_show_page(struct i2c_client *client,
0078                          int page,
0079                          char *buf)
0080 {
0081     int val = pmbus_read_byte_data(client, page, PMBUS_OPERATION);
0082 
0083     return sprintf(buf, "%d\n",
0084                (val & ISL68137_VOUT_AVS) == ISL68137_VOUT_AVS ? 1 : 0);
0085 }
0086 
0087 static ssize_t isl68137_avs_enable_store_page(struct i2c_client *client,
0088                           int page,
0089                           const char *buf, size_t count)
0090 {
0091     int rc, op_val;
0092     bool result;
0093 
0094     rc = kstrtobool(buf, &result);
0095     if (rc)
0096         return rc;
0097 
0098     op_val = result ? ISL68137_VOUT_AVS : 0;
0099 
0100     /*
0101      * Writes to VOUT setpoint over AVSBus will persist after the VRM is
0102      * switched to PMBus control. Switching back to AVSBus control
0103      * restores this persisted setpoint rather than re-initializing to
0104      * PMBus VOUT_COMMAND. Writing VOUT_COMMAND first over PMBus before
0105      * enabling AVS control is the workaround.
0106      */
0107     if (op_val == ISL68137_VOUT_AVS) {
0108         rc = pmbus_read_word_data(client, page, 0xff,
0109                       PMBUS_VOUT_COMMAND);
0110         if (rc < 0)
0111             return rc;
0112 
0113         rc = pmbus_write_word_data(client, page, PMBUS_VOUT_COMMAND,
0114                        rc);
0115         if (rc < 0)
0116             return rc;
0117     }
0118 
0119     rc = pmbus_update_byte_data(client, page, PMBUS_OPERATION,
0120                     ISL68137_VOUT_AVS, op_val);
0121 
0122     return (rc < 0) ? rc : count;
0123 }
0124 
0125 static ssize_t isl68137_avs_enable_show(struct device *dev,
0126                     struct device_attribute *devattr,
0127                     char *buf)
0128 {
0129     struct i2c_client *client = to_i2c_client(dev->parent);
0130     struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
0131 
0132     return isl68137_avs_enable_show_page(client, attr->index, buf);
0133 }
0134 
0135 static ssize_t isl68137_avs_enable_store(struct device *dev,
0136                 struct device_attribute *devattr,
0137                 const char *buf, size_t count)
0138 {
0139     struct i2c_client *client = to_i2c_client(dev->parent);
0140     struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
0141 
0142     return isl68137_avs_enable_store_page(client, attr->index, buf, count);
0143 }
0144 
0145 static SENSOR_DEVICE_ATTR_RW(avs0_enable, isl68137_avs_enable, 0);
0146 static SENSOR_DEVICE_ATTR_RW(avs1_enable, isl68137_avs_enable, 1);
0147 
0148 static struct attribute *enable_attrs[] = {
0149     &sensor_dev_attr_avs0_enable.dev_attr.attr,
0150     &sensor_dev_attr_avs1_enable.dev_attr.attr,
0151     NULL,
0152 };
0153 
0154 static const struct attribute_group enable_group = {
0155     .attrs = enable_attrs,
0156 };
0157 
0158 static const struct attribute_group *isl68137_attribute_groups[] = {
0159     &enable_group,
0160     NULL,
0161 };
0162 
0163 static int raa_dmpvr2_read_word_data(struct i2c_client *client, int page,
0164                      int phase, int reg)
0165 {
0166     int ret;
0167 
0168     switch (reg) {
0169     case PMBUS_VIRT_READ_VMON:
0170         ret = pmbus_read_word_data(client, page, phase,
0171                        RAA_DMPVR2_READ_VMON);
0172         break;
0173     default:
0174         ret = -ENODATA;
0175         break;
0176     }
0177 
0178     return ret;
0179 }
0180 
0181 static struct pmbus_driver_info raa_dmpvr_info = {
0182     .pages = 3,
0183     .format[PSC_VOLTAGE_IN] = direct,
0184     .format[PSC_VOLTAGE_OUT] = direct,
0185     .format[PSC_CURRENT_IN] = direct,
0186     .format[PSC_CURRENT_OUT] = direct,
0187     .format[PSC_POWER] = direct,
0188     .format[PSC_TEMPERATURE] = direct,
0189     .m[PSC_VOLTAGE_IN] = 1,
0190     .b[PSC_VOLTAGE_IN] = 0,
0191     .R[PSC_VOLTAGE_IN] = 2,
0192     .m[PSC_VOLTAGE_OUT] = 1,
0193     .b[PSC_VOLTAGE_OUT] = 0,
0194     .R[PSC_VOLTAGE_OUT] = 3,
0195     .m[PSC_CURRENT_IN] = 1,
0196     .b[PSC_CURRENT_IN] = 0,
0197     .R[PSC_CURRENT_IN] = 2,
0198     .m[PSC_CURRENT_OUT] = 1,
0199     .b[PSC_CURRENT_OUT] = 0,
0200     .R[PSC_CURRENT_OUT] = 1,
0201     .m[PSC_POWER] = 1,
0202     .b[PSC_POWER] = 0,
0203     .R[PSC_POWER] = 0,
0204     .m[PSC_TEMPERATURE] = 1,
0205     .b[PSC_TEMPERATURE] = 0,
0206     .R[PSC_TEMPERATURE] = 0,
0207     .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | PMBUS_HAVE_PIN
0208         | PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2
0209         | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_TEMP
0210         | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
0211         | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT
0212         | PMBUS_HAVE_VMON,
0213     .func[1] = PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT
0214         | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_TEMP
0215         | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_IOUT
0216         | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT,
0217     .func[2] = PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT
0218         | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_TEMP
0219         | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_IOUT
0220         | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT,
0221 };
0222 
0223 static int isl68137_probe(struct i2c_client *client)
0224 {
0225     struct pmbus_driver_info *info;
0226 
0227     info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
0228     if (!info)
0229         return -ENOMEM;
0230     memcpy(info, &raa_dmpvr_info, sizeof(*info));
0231 
0232     switch (i2c_match_id(raa_dmpvr_id, client)->driver_data) {
0233     case raa_dmpvr1_2rail:
0234         info->pages = 2;
0235         info->R[PSC_VOLTAGE_IN] = 3;
0236         info->func[0] &= ~PMBUS_HAVE_VMON;
0237         info->func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
0238             | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
0239             | PMBUS_HAVE_POUT;
0240         info->groups = isl68137_attribute_groups;
0241         break;
0242     case raa_dmpvr2_1rail:
0243         info->pages = 1;
0244         info->read_word_data = raa_dmpvr2_read_word_data;
0245         break;
0246     case raa_dmpvr2_2rail_nontc:
0247         info->func[0] &= ~PMBUS_HAVE_TEMP3;
0248         info->func[1] &= ~PMBUS_HAVE_TEMP3;
0249         fallthrough;
0250     case raa_dmpvr2_2rail:
0251         info->pages = 2;
0252         info->read_word_data = raa_dmpvr2_read_word_data;
0253         break;
0254     case raa_dmpvr2_3rail:
0255         info->read_word_data = raa_dmpvr2_read_word_data;
0256         break;
0257     case raa_dmpvr2_hv:
0258         info->pages = 1;
0259         info->R[PSC_VOLTAGE_IN] = 1;
0260         info->m[PSC_VOLTAGE_OUT] = 2;
0261         info->R[PSC_VOLTAGE_OUT] = 2;
0262         info->m[PSC_CURRENT_IN] = 2;
0263         info->m[PSC_POWER] = 2;
0264         info->R[PSC_POWER] = -1;
0265         info->read_word_data = raa_dmpvr2_read_word_data;
0266         break;
0267     default:
0268         return -ENODEV;
0269     }
0270 
0271     return pmbus_do_probe(client, info);
0272 }
0273 
0274 static const struct i2c_device_id raa_dmpvr_id[] = {
0275     {"isl68137", raa_dmpvr1_2rail},
0276     {"isl68220", raa_dmpvr2_2rail},
0277     {"isl68221", raa_dmpvr2_3rail},
0278     {"isl68222", raa_dmpvr2_2rail},
0279     {"isl68223", raa_dmpvr2_2rail},
0280     {"isl68224", raa_dmpvr2_3rail},
0281     {"isl68225", raa_dmpvr2_2rail},
0282     {"isl68226", raa_dmpvr2_3rail},
0283     {"isl68227", raa_dmpvr2_1rail},
0284     {"isl68229", raa_dmpvr2_3rail},
0285     {"isl68233", raa_dmpvr2_2rail},
0286     {"isl68239", raa_dmpvr2_3rail},
0287 
0288     {"isl69222", raa_dmpvr2_2rail},
0289     {"isl69223", raa_dmpvr2_3rail},
0290     {"isl69224", raa_dmpvr2_2rail},
0291     {"isl69225", raa_dmpvr2_2rail},
0292     {"isl69227", raa_dmpvr2_3rail},
0293     {"isl69228", raa_dmpvr2_3rail},
0294     {"isl69234", raa_dmpvr2_2rail},
0295     {"isl69236", raa_dmpvr2_2rail},
0296     {"isl69239", raa_dmpvr2_3rail},
0297     {"isl69242", raa_dmpvr2_2rail},
0298     {"isl69243", raa_dmpvr2_1rail},
0299     {"isl69247", raa_dmpvr2_2rail},
0300     {"isl69248", raa_dmpvr2_2rail},
0301     {"isl69254", raa_dmpvr2_2rail},
0302     {"isl69255", raa_dmpvr2_2rail},
0303     {"isl69256", raa_dmpvr2_2rail},
0304     {"isl69259", raa_dmpvr2_2rail},
0305     {"isl69260", raa_dmpvr2_2rail},
0306     {"isl69268", raa_dmpvr2_2rail},
0307     {"isl69269", raa_dmpvr2_3rail},
0308     {"isl69298", raa_dmpvr2_2rail},
0309 
0310     {"raa228000", raa_dmpvr2_hv},
0311     {"raa228004", raa_dmpvr2_hv},
0312     {"raa228006", raa_dmpvr2_hv},
0313     {"raa228228", raa_dmpvr2_2rail_nontc},
0314     {"raa229001", raa_dmpvr2_2rail},
0315     {"raa229004", raa_dmpvr2_2rail},
0316     {}
0317 };
0318 
0319 MODULE_DEVICE_TABLE(i2c, raa_dmpvr_id);
0320 
0321 /* This is the driver that will be inserted */
0322 static struct i2c_driver isl68137_driver = {
0323     .driver = {
0324            .name = "isl68137",
0325            },
0326     .probe_new = isl68137_probe,
0327     .id_table = raa_dmpvr_id,
0328 };
0329 
0330 module_i2c_driver(isl68137_driver);
0331 
0332 MODULE_AUTHOR("Maxim Sloyko <maxims@google.com>");
0333 MODULE_DESCRIPTION("PMBus driver for Renesas digital multiphase voltage regulators");
0334 MODULE_LICENSE("GPL");
0335 MODULE_IMPORT_NS(PMBUS);