Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Hardware monitoring driver for Maxim MAX8688
0004  *
0005  * Copyright (c) 2011 Ericsson AB.
0006  */
0007 
0008 #include <linux/bitops.h>
0009 #include <linux/kernel.h>
0010 #include <linux/module.h>
0011 #include <linux/init.h>
0012 #include <linux/err.h>
0013 #include <linux/i2c.h>
0014 #include "pmbus.h"
0015 
0016 #define MAX8688_MFR_VOUT_PEAK       0xd4
0017 #define MAX8688_MFR_IOUT_PEAK       0xd5
0018 #define MAX8688_MFR_TEMPERATURE_PEAK    0xd6
0019 #define MAX8688_MFG_STATUS      0xd8
0020 
0021 #define MAX8688_STATUS_OC_FAULT     BIT(4)
0022 #define MAX8688_STATUS_OV_FAULT     BIT(5)
0023 #define MAX8688_STATUS_OV_WARNING   BIT(8)
0024 #define MAX8688_STATUS_UV_FAULT     BIT(9)
0025 #define MAX8688_STATUS_UV_WARNING   BIT(10)
0026 #define MAX8688_STATUS_UC_FAULT     BIT(11)
0027 #define MAX8688_STATUS_OC_WARNING   BIT(12)
0028 #define MAX8688_STATUS_OT_FAULT     BIT(13)
0029 #define MAX8688_STATUS_OT_WARNING   BIT(14)
0030 
0031 static int max8688_read_word_data(struct i2c_client *client, int page,
0032                   int phase, int reg)
0033 {
0034     int ret;
0035 
0036     if (page > 0)
0037         return -ENXIO;
0038 
0039     switch (reg) {
0040     case PMBUS_VIRT_READ_VOUT_MAX:
0041         ret = pmbus_read_word_data(client, 0, 0xff,
0042                        MAX8688_MFR_VOUT_PEAK);
0043         break;
0044     case PMBUS_VIRT_READ_IOUT_MAX:
0045         ret = pmbus_read_word_data(client, 0, 0xff,
0046                        MAX8688_MFR_IOUT_PEAK);
0047         break;
0048     case PMBUS_VIRT_READ_TEMP_MAX:
0049         ret = pmbus_read_word_data(client, 0, 0xff,
0050                        MAX8688_MFR_TEMPERATURE_PEAK);
0051         break;
0052     case PMBUS_VIRT_RESET_VOUT_HISTORY:
0053     case PMBUS_VIRT_RESET_IOUT_HISTORY:
0054     case PMBUS_VIRT_RESET_TEMP_HISTORY:
0055         ret = 0;
0056         break;
0057     default:
0058         ret = -ENODATA;
0059         break;
0060     }
0061     return ret;
0062 }
0063 
0064 static int max8688_write_word_data(struct i2c_client *client, int page, int reg,
0065                    u16 word)
0066 {
0067     int ret;
0068 
0069     switch (reg) {
0070     case PMBUS_VIRT_RESET_VOUT_HISTORY:
0071         ret = pmbus_write_word_data(client, 0, MAX8688_MFR_VOUT_PEAK,
0072                         0);
0073         break;
0074     case PMBUS_VIRT_RESET_IOUT_HISTORY:
0075         ret = pmbus_write_word_data(client, 0, MAX8688_MFR_IOUT_PEAK,
0076                         0);
0077         break;
0078     case PMBUS_VIRT_RESET_TEMP_HISTORY:
0079         ret = pmbus_write_word_data(client, 0,
0080                         MAX8688_MFR_TEMPERATURE_PEAK,
0081                         0xffff);
0082         break;
0083     default:
0084         ret = -ENODATA;
0085         break;
0086     }
0087     return ret;
0088 }
0089 
0090 static int max8688_read_byte_data(struct i2c_client *client, int page, int reg)
0091 {
0092     int ret = 0;
0093     int mfg_status;
0094 
0095     if (page > 0)
0096         return -ENXIO;
0097 
0098     switch (reg) {
0099     case PMBUS_STATUS_VOUT:
0100         mfg_status = pmbus_read_word_data(client, 0, 0xff,
0101                           MAX8688_MFG_STATUS);
0102         if (mfg_status < 0)
0103             return mfg_status;
0104         if (mfg_status & MAX8688_STATUS_UV_WARNING)
0105             ret |= PB_VOLTAGE_UV_WARNING;
0106         if (mfg_status & MAX8688_STATUS_UV_FAULT)
0107             ret |= PB_VOLTAGE_UV_FAULT;
0108         if (mfg_status & MAX8688_STATUS_OV_WARNING)
0109             ret |= PB_VOLTAGE_OV_WARNING;
0110         if (mfg_status & MAX8688_STATUS_OV_FAULT)
0111             ret |= PB_VOLTAGE_OV_FAULT;
0112         break;
0113     case PMBUS_STATUS_IOUT:
0114         mfg_status = pmbus_read_word_data(client, 0, 0xff,
0115                           MAX8688_MFG_STATUS);
0116         if (mfg_status < 0)
0117             return mfg_status;
0118         if (mfg_status & MAX8688_STATUS_UC_FAULT)
0119             ret |= PB_IOUT_UC_FAULT;
0120         if (mfg_status & MAX8688_STATUS_OC_WARNING)
0121             ret |= PB_IOUT_OC_WARNING;
0122         if (mfg_status & MAX8688_STATUS_OC_FAULT)
0123             ret |= PB_IOUT_OC_FAULT;
0124         break;
0125     case PMBUS_STATUS_TEMPERATURE:
0126         mfg_status = pmbus_read_word_data(client, 0, 0xff,
0127                           MAX8688_MFG_STATUS);
0128         if (mfg_status < 0)
0129             return mfg_status;
0130         if (mfg_status & MAX8688_STATUS_OT_WARNING)
0131             ret |= PB_TEMP_OT_WARNING;
0132         if (mfg_status & MAX8688_STATUS_OT_FAULT)
0133             ret |= PB_TEMP_OT_FAULT;
0134         break;
0135     default:
0136         ret = -ENODATA;
0137         break;
0138     }
0139     return ret;
0140 }
0141 
0142 static struct pmbus_driver_info max8688_info = {
0143     .pages = 1,
0144     .format[PSC_VOLTAGE_IN] = direct,
0145     .format[PSC_VOLTAGE_OUT] = direct,
0146     .format[PSC_TEMPERATURE] = direct,
0147     .format[PSC_CURRENT_OUT] = direct,
0148     .m[PSC_VOLTAGE_IN] = 19995,
0149     .b[PSC_VOLTAGE_IN] = 0,
0150     .R[PSC_VOLTAGE_IN] = -1,
0151     .m[PSC_VOLTAGE_OUT] = 19995,
0152     .b[PSC_VOLTAGE_OUT] = 0,
0153     .R[PSC_VOLTAGE_OUT] = -1,
0154     .m[PSC_CURRENT_OUT] = 23109,
0155     .b[PSC_CURRENT_OUT] = 0,
0156     .R[PSC_CURRENT_OUT] = -2,
0157     .m[PSC_TEMPERATURE] = -7612,
0158     .b[PSC_TEMPERATURE] = 335,
0159     .R[PSC_TEMPERATURE] = -3,
0160     .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | PMBUS_HAVE_TEMP
0161         | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT
0162         | PMBUS_HAVE_STATUS_TEMP,
0163     .read_byte_data = max8688_read_byte_data,
0164     .read_word_data = max8688_read_word_data,
0165     .write_word_data = max8688_write_word_data,
0166 };
0167 
0168 static int max8688_probe(struct i2c_client *client)
0169 {
0170     return pmbus_do_probe(client, &max8688_info);
0171 }
0172 
0173 static const struct i2c_device_id max8688_id[] = {
0174     {"max8688", 0},
0175     { }
0176 };
0177 
0178 MODULE_DEVICE_TABLE(i2c, max8688_id);
0179 
0180 /* This is the driver that will be inserted */
0181 static struct i2c_driver max8688_driver = {
0182     .driver = {
0183            .name = "max8688",
0184            },
0185     .probe_new = max8688_probe,
0186     .id_table = max8688_id,
0187 };
0188 
0189 module_i2c_driver(max8688_driver);
0190 
0191 MODULE_AUTHOR("Guenter Roeck");
0192 MODULE_DESCRIPTION("PMBus driver for Maxim MAX8688");
0193 MODULE_LICENSE("GPL");
0194 MODULE_IMPORT_NS(PMBUS);