Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Hardware monitoring driver for ZL6100 and compatibles
0004  *
0005  * Copyright (c) 2011 Ericsson AB.
0006  * Copyright (c) 2012 Guenter Roeck
0007  */
0008 
0009 #include <linux/bitops.h>
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/init.h>
0013 #include <linux/err.h>
0014 #include <linux/slab.h>
0015 #include <linux/i2c.h>
0016 #include <linux/ktime.h>
0017 #include <linux/delay.h>
0018 #include "pmbus.h"
0019 
0020 enum chips { zl2004, zl2005, zl2006, zl2008, zl2105, zl2106, zl6100, zl6105,
0021          zl8802, zl9101, zl9117, zls1003, zls4009 };
0022 
0023 struct zl6100_data {
0024     int id;
0025     ktime_t access;     /* chip access time */
0026     int delay;      /* Delay between chip accesses in uS */
0027     struct pmbus_driver_info info;
0028 };
0029 
0030 #define to_zl6100_data(x)  container_of(x, struct zl6100_data, info)
0031 
0032 #define ZL6100_MFR_CONFIG       0xd0
0033 #define ZL6100_DEVICE_ID        0xe4
0034 
0035 #define ZL6100_MFR_XTEMP_ENABLE     BIT(7)
0036 
0037 #define ZL8802_MFR_USER_GLOBAL_CONFIG   0xe9
0038 #define ZL8802_MFR_TMON_ENABLE      BIT(12)
0039 #define ZL8802_MFR_USER_CONFIG      0xd1
0040 #define ZL8802_MFR_XTEMP_ENABLE_2   BIT(1)
0041 #define ZL8802_MFR_DDC_CONFIG       0xd3
0042 #define ZL8802_MFR_PHASES_MASK      0x0007
0043 
0044 #define MFR_VMON_OV_FAULT_LIMIT     0xf5
0045 #define MFR_VMON_UV_FAULT_LIMIT     0xf6
0046 #define MFR_READ_VMON           0xf7
0047 
0048 #define VMON_UV_WARNING         BIT(5)
0049 #define VMON_OV_WARNING         BIT(4)
0050 #define VMON_UV_FAULT           BIT(1)
0051 #define VMON_OV_FAULT           BIT(0)
0052 
0053 #define ZL6100_WAIT_TIME        1000    /* uS   */
0054 
0055 static ushort delay = ZL6100_WAIT_TIME;
0056 module_param(delay, ushort, 0644);
0057 MODULE_PARM_DESC(delay, "Delay between chip accesses in uS");
0058 
0059 /* Convert linear sensor value to milli-units */
0060 static long zl6100_l2d(s16 l)
0061 {
0062     s16 exponent;
0063     s32 mantissa;
0064     long val;
0065 
0066     exponent = l >> 11;
0067     mantissa = ((s16)((l & 0x7ff) << 5)) >> 5;
0068 
0069     val = mantissa;
0070 
0071     /* scale result to milli-units */
0072     val = val * 1000L;
0073 
0074     if (exponent >= 0)
0075         val <<= exponent;
0076     else
0077         val >>= -exponent;
0078 
0079     return val;
0080 }
0081 
0082 #define MAX_MANTISSA    (1023 * 1000)
0083 #define MIN_MANTISSA    (511 * 1000)
0084 
0085 static u16 zl6100_d2l(long val)
0086 {
0087     s16 exponent = 0, mantissa;
0088     bool negative = false;
0089 
0090     /* simple case */
0091     if (val == 0)
0092         return 0;
0093 
0094     if (val < 0) {
0095         negative = true;
0096         val = -val;
0097     }
0098 
0099     /* Reduce large mantissa until it fits into 10 bit */
0100     while (val >= MAX_MANTISSA && exponent < 15) {
0101         exponent++;
0102         val >>= 1;
0103     }
0104     /* Increase small mantissa to improve precision */
0105     while (val < MIN_MANTISSA && exponent > -15) {
0106         exponent--;
0107         val <<= 1;
0108     }
0109 
0110     /* Convert mantissa from milli-units to units */
0111     mantissa = DIV_ROUND_CLOSEST(val, 1000);
0112 
0113     /* Ensure that resulting number is within range */
0114     if (mantissa > 0x3ff)
0115         mantissa = 0x3ff;
0116 
0117     /* restore sign */
0118     if (negative)
0119         mantissa = -mantissa;
0120 
0121     /* Convert to 5 bit exponent, 11 bit mantissa */
0122     return (mantissa & 0x7ff) | ((exponent << 11) & 0xf800);
0123 }
0124 
0125 /* Some chips need a delay between accesses */
0126 static inline void zl6100_wait(const struct zl6100_data *data)
0127 {
0128     if (data->delay) {
0129         s64 delta = ktime_us_delta(ktime_get(), data->access);
0130         if (delta < data->delay)
0131             udelay(data->delay - delta);
0132     }
0133 }
0134 
0135 static int zl6100_read_word_data(struct i2c_client *client, int page,
0136                  int phase, int reg)
0137 {
0138     const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
0139     struct zl6100_data *data = to_zl6100_data(info);
0140     int ret, vreg;
0141 
0142     if (page >= info->pages)
0143         return -ENXIO;
0144 
0145     if (data->id == zl2005) {
0146         /*
0147          * Limit register detection is not reliable on ZL2005.
0148          * Make sure registers are not erroneously detected.
0149          */
0150         switch (reg) {
0151         case PMBUS_VOUT_OV_WARN_LIMIT:
0152         case PMBUS_VOUT_UV_WARN_LIMIT:
0153         case PMBUS_IOUT_OC_WARN_LIMIT:
0154             return -ENXIO;
0155         }
0156     }
0157 
0158     switch (reg) {
0159     case PMBUS_VIRT_READ_VMON:
0160         vreg = MFR_READ_VMON;
0161         break;
0162     case PMBUS_VIRT_VMON_OV_WARN_LIMIT:
0163     case PMBUS_VIRT_VMON_OV_FAULT_LIMIT:
0164         vreg = MFR_VMON_OV_FAULT_LIMIT;
0165         break;
0166     case PMBUS_VIRT_VMON_UV_WARN_LIMIT:
0167     case PMBUS_VIRT_VMON_UV_FAULT_LIMIT:
0168         vreg = MFR_VMON_UV_FAULT_LIMIT;
0169         break;
0170     default:
0171         if (reg >= PMBUS_VIRT_BASE)
0172             return -ENXIO;
0173         vreg = reg;
0174         break;
0175     }
0176 
0177     zl6100_wait(data);
0178     ret = pmbus_read_word_data(client, page, phase, vreg);
0179     data->access = ktime_get();
0180     if (ret < 0)
0181         return ret;
0182 
0183     switch (reg) {
0184     case PMBUS_VIRT_VMON_OV_WARN_LIMIT:
0185         ret = zl6100_d2l(DIV_ROUND_CLOSEST(zl6100_l2d(ret) * 9, 10));
0186         break;
0187     case PMBUS_VIRT_VMON_UV_WARN_LIMIT:
0188         ret = zl6100_d2l(DIV_ROUND_CLOSEST(zl6100_l2d(ret) * 11, 10));
0189         break;
0190     }
0191 
0192     return ret;
0193 }
0194 
0195 static int zl6100_read_byte_data(struct i2c_client *client, int page, int reg)
0196 {
0197     const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
0198     struct zl6100_data *data = to_zl6100_data(info);
0199     int ret, status;
0200 
0201     if (page >= info->pages)
0202         return -ENXIO;
0203 
0204     zl6100_wait(data);
0205 
0206     switch (reg) {
0207     case PMBUS_VIRT_STATUS_VMON:
0208         ret = pmbus_read_byte_data(client, 0,
0209                        PMBUS_STATUS_MFR_SPECIFIC);
0210         if (ret < 0)
0211             break;
0212 
0213         status = 0;
0214         if (ret & VMON_UV_WARNING)
0215             status |= PB_VOLTAGE_UV_WARNING;
0216         if (ret & VMON_OV_WARNING)
0217             status |= PB_VOLTAGE_OV_WARNING;
0218         if (ret & VMON_UV_FAULT)
0219             status |= PB_VOLTAGE_UV_FAULT;
0220         if (ret & VMON_OV_FAULT)
0221             status |= PB_VOLTAGE_OV_FAULT;
0222         ret = status;
0223         break;
0224     default:
0225         ret = pmbus_read_byte_data(client, page, reg);
0226         break;
0227     }
0228     data->access = ktime_get();
0229 
0230     return ret;
0231 }
0232 
0233 static int zl6100_write_word_data(struct i2c_client *client, int page, int reg,
0234                   u16 word)
0235 {
0236     const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
0237     struct zl6100_data *data = to_zl6100_data(info);
0238     int ret, vreg;
0239 
0240     if (page >= info->pages)
0241         return -ENXIO;
0242 
0243     switch (reg) {
0244     case PMBUS_VIRT_VMON_OV_WARN_LIMIT:
0245         word = zl6100_d2l(DIV_ROUND_CLOSEST(zl6100_l2d(word) * 10, 9));
0246         vreg = MFR_VMON_OV_FAULT_LIMIT;
0247         pmbus_clear_cache(client);
0248         break;
0249     case PMBUS_VIRT_VMON_OV_FAULT_LIMIT:
0250         vreg = MFR_VMON_OV_FAULT_LIMIT;
0251         pmbus_clear_cache(client);
0252         break;
0253     case PMBUS_VIRT_VMON_UV_WARN_LIMIT:
0254         word = zl6100_d2l(DIV_ROUND_CLOSEST(zl6100_l2d(word) * 10, 11));
0255         vreg = MFR_VMON_UV_FAULT_LIMIT;
0256         pmbus_clear_cache(client);
0257         break;
0258     case PMBUS_VIRT_VMON_UV_FAULT_LIMIT:
0259         vreg = MFR_VMON_UV_FAULT_LIMIT;
0260         pmbus_clear_cache(client);
0261         break;
0262     default:
0263         if (reg >= PMBUS_VIRT_BASE)
0264             return -ENXIO;
0265         vreg = reg;
0266     }
0267 
0268     zl6100_wait(data);
0269     ret = pmbus_write_word_data(client, page, vreg, word);
0270     data->access = ktime_get();
0271 
0272     return ret;
0273 }
0274 
0275 static int zl6100_write_byte(struct i2c_client *client, int page, u8 value)
0276 {
0277     const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
0278     struct zl6100_data *data = to_zl6100_data(info);
0279     int ret;
0280 
0281     if (page >= info->pages)
0282         return -ENXIO;
0283 
0284     zl6100_wait(data);
0285     ret = pmbus_write_byte(client, page, value);
0286     data->access = ktime_get();
0287 
0288     return ret;
0289 }
0290 
0291 static const struct i2c_device_id zl6100_id[] = {
0292     {"bmr450", zl2005},
0293     {"bmr451", zl2005},
0294     {"bmr462", zl2008},
0295     {"bmr463", zl2008},
0296     {"bmr464", zl2008},
0297     {"bmr465", zls4009},
0298     {"bmr466", zls1003},
0299     {"bmr467", zls4009},
0300     {"bmr469", zl8802},
0301     {"zl2004", zl2004},
0302     {"zl2005", zl2005},
0303     {"zl2006", zl2006},
0304     {"zl2008", zl2008},
0305     {"zl2105", zl2105},
0306     {"zl2106", zl2106},
0307     {"zl6100", zl6100},
0308     {"zl6105", zl6105},
0309     {"zl8802", zl8802},
0310     {"zl9101", zl9101},
0311     {"zl9117", zl9117},
0312     {"zls1003", zls1003},
0313     {"zls4009", zls4009},
0314     { }
0315 };
0316 MODULE_DEVICE_TABLE(i2c, zl6100_id);
0317 
0318 static int zl6100_probe(struct i2c_client *client)
0319 {
0320     int ret, i;
0321     struct zl6100_data *data;
0322     struct pmbus_driver_info *info;
0323     u8 device_id[I2C_SMBUS_BLOCK_MAX + 1];
0324     const struct i2c_device_id *mid;
0325 
0326     if (!i2c_check_functionality(client->adapter,
0327                      I2C_FUNC_SMBUS_READ_WORD_DATA
0328                      | I2C_FUNC_SMBUS_READ_BLOCK_DATA))
0329         return -ENODEV;
0330 
0331     ret = i2c_smbus_read_block_data(client, ZL6100_DEVICE_ID,
0332                     device_id);
0333     if (ret < 0) {
0334         dev_err(&client->dev, "Failed to read device ID\n");
0335         return ret;
0336     }
0337     device_id[ret] = '\0';
0338     dev_info(&client->dev, "Device ID %s\n", device_id);
0339 
0340     mid = NULL;
0341     for (mid = zl6100_id; mid->name[0]; mid++) {
0342         if (!strncasecmp(mid->name, device_id, strlen(mid->name)))
0343             break;
0344     }
0345     if (!mid->name[0]) {
0346         dev_err(&client->dev, "Unsupported device\n");
0347         return -ENODEV;
0348     }
0349     if (strcmp(client->name, mid->name) != 0)
0350         dev_notice(&client->dev,
0351                "Device mismatch: Configured %s, detected %s\n",
0352                client->name, mid->name);
0353 
0354     data = devm_kzalloc(&client->dev, sizeof(struct zl6100_data),
0355                 GFP_KERNEL);
0356     if (!data)
0357         return -ENOMEM;
0358 
0359     data->id = mid->driver_data;
0360 
0361     /*
0362      * According to information from the chip vendor, all currently
0363      * supported chips are known to require a wait time between I2C
0364      * accesses.
0365      */
0366     data->delay = delay;
0367 
0368     /*
0369      * Since there was a direct I2C device access above, wait before
0370      * accessing the chip again.
0371      */
0372     data->access = ktime_get();
0373     zl6100_wait(data);
0374 
0375     info = &data->info;
0376 
0377     info->pages = 1;
0378     info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT
0379       | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
0380       | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
0381       | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
0382 
0383     /*
0384      * ZL2004, ZL8802, ZL9101M, ZL9117M and ZLS4009 support monitoring
0385      * an extra voltage (VMON for ZL2004, ZL8802 and ZLS4009,
0386      * VDRV for ZL9101M and ZL9117M). Report it as vmon.
0387      */
0388     if (data->id == zl2004 || data->id == zl8802 || data->id == zl9101 ||
0389         data->id == zl9117 || data->id == zls4009)
0390         info->func[0] |= PMBUS_HAVE_VMON | PMBUS_HAVE_STATUS_VMON;
0391 
0392     /*
0393      * ZL8802 has two outputs that can be used either independently or in
0394      * a current sharing configuration. The driver uses the DDC_CONFIG
0395      * register to check if the module is running with independent or
0396      * shared outputs. If the module is in shared output mode, only one
0397      * output voltage will be reported.
0398      */
0399     if (data->id == zl8802) {
0400         info->pages = 2;
0401         info->func[0] |= PMBUS_HAVE_IIN;
0402 
0403         ret = i2c_smbus_read_word_data(client, ZL8802_MFR_DDC_CONFIG);
0404         if (ret < 0)
0405             return ret;
0406 
0407         data->access = ktime_get();
0408         zl6100_wait(data);
0409 
0410         if (ret & ZL8802_MFR_PHASES_MASK)
0411             info->func[1] |= PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT;
0412         else
0413             info->func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
0414                 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT;
0415 
0416         for (i = 0; i < 2; i++) {
0417             ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, i);
0418             if (ret < 0)
0419                 return ret;
0420 
0421             data->access = ktime_get();
0422             zl6100_wait(data);
0423 
0424             ret = i2c_smbus_read_word_data(client, ZL8802_MFR_USER_CONFIG);
0425             if (ret < 0)
0426                 return ret;
0427 
0428             if (ret & ZL8802_MFR_XTEMP_ENABLE_2)
0429                 info->func[i] |= PMBUS_HAVE_TEMP2;
0430 
0431             data->access = ktime_get();
0432             zl6100_wait(data);
0433         }
0434         ret = i2c_smbus_read_word_data(client, ZL8802_MFR_USER_GLOBAL_CONFIG);
0435         if (ret < 0)
0436             return ret;
0437 
0438         if (ret & ZL8802_MFR_TMON_ENABLE)
0439             info->func[0] |= PMBUS_HAVE_TEMP3;
0440     } else {
0441         ret = i2c_smbus_read_word_data(client, ZL6100_MFR_CONFIG);
0442         if (ret < 0)
0443             return ret;
0444 
0445         if (ret & ZL6100_MFR_XTEMP_ENABLE)
0446             info->func[0] |= PMBUS_HAVE_TEMP2;
0447     }
0448 
0449     data->access = ktime_get();
0450     zl6100_wait(data);
0451 
0452     info->read_word_data = zl6100_read_word_data;
0453     info->read_byte_data = zl6100_read_byte_data;
0454     info->write_word_data = zl6100_write_word_data;
0455     info->write_byte = zl6100_write_byte;
0456 
0457     return pmbus_do_probe(client, info);
0458 }
0459 
0460 static struct i2c_driver zl6100_driver = {
0461     .driver = {
0462            .name = "zl6100",
0463            },
0464     .probe_new = zl6100_probe,
0465     .id_table = zl6100_id,
0466 };
0467 
0468 module_i2c_driver(zl6100_driver);
0469 
0470 MODULE_AUTHOR("Guenter Roeck");
0471 MODULE_DESCRIPTION("PMBus driver for ZL6100 and compatibles");
0472 MODULE_LICENSE("GPL");
0473 MODULE_IMPORT_NS(PMBUS);