Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2020 Sartura Ltd.
0004  *
0005  * Driver for the TI TPS23861 PoE PSE.
0006  *
0007  * Author: Robert Marko <robert.marko@sartura.hr>
0008  */
0009 
0010 #include <linux/bitfield.h>
0011 #include <linux/debugfs.h>
0012 #include <linux/delay.h>
0013 #include <linux/hwmon-sysfs.h>
0014 #include <linux/hwmon.h>
0015 #include <linux/i2c.h>
0016 #include <linux/module.h>
0017 #include <linux/of_device.h>
0018 #include <linux/regmap.h>
0019 
0020 #define TEMPERATURE         0x2c
0021 #define INPUT_VOLTAGE_LSB       0x2e
0022 #define INPUT_VOLTAGE_MSB       0x2f
0023 #define PORT_1_CURRENT_LSB      0x30
0024 #define PORT_1_CURRENT_MSB      0x31
0025 #define PORT_1_VOLTAGE_LSB      0x32
0026 #define PORT_1_VOLTAGE_MSB      0x33
0027 #define PORT_2_CURRENT_LSB      0x34
0028 #define PORT_2_CURRENT_MSB      0x35
0029 #define PORT_2_VOLTAGE_LSB      0x36
0030 #define PORT_2_VOLTAGE_MSB      0x37
0031 #define PORT_3_CURRENT_LSB      0x38
0032 #define PORT_3_CURRENT_MSB      0x39
0033 #define PORT_3_VOLTAGE_LSB      0x3a
0034 #define PORT_3_VOLTAGE_MSB      0x3b
0035 #define PORT_4_CURRENT_LSB      0x3c
0036 #define PORT_4_CURRENT_MSB      0x3d
0037 #define PORT_4_VOLTAGE_LSB      0x3e
0038 #define PORT_4_VOLTAGE_MSB      0x3f
0039 #define PORT_N_CURRENT_LSB_OFFSET   0x04
0040 #define PORT_N_VOLTAGE_LSB_OFFSET   0x04
0041 #define VOLTAGE_CURRENT_MASK        GENMASK(13, 0)
0042 #define PORT_1_RESISTANCE_LSB       0x60
0043 #define PORT_1_RESISTANCE_MSB       0x61
0044 #define PORT_2_RESISTANCE_LSB       0x62
0045 #define PORT_2_RESISTANCE_MSB       0x63
0046 #define PORT_3_RESISTANCE_LSB       0x64
0047 #define PORT_3_RESISTANCE_MSB       0x65
0048 #define PORT_4_RESISTANCE_LSB       0x66
0049 #define PORT_4_RESISTANCE_MSB       0x67
0050 #define PORT_N_RESISTANCE_LSB_OFFSET    0x02
0051 #define PORT_RESISTANCE_MASK        GENMASK(13, 0)
0052 #define PORT_RESISTANCE_RSN_MASK    GENMASK(15, 14)
0053 #define PORT_RESISTANCE_RSN_OTHER   0
0054 #define PORT_RESISTANCE_RSN_LOW     1
0055 #define PORT_RESISTANCE_RSN_OPEN    2
0056 #define PORT_RESISTANCE_RSN_SHORT   3
0057 #define PORT_1_STATUS           0x0c
0058 #define PORT_2_STATUS           0x0d
0059 #define PORT_3_STATUS           0x0e
0060 #define PORT_4_STATUS           0x0f
0061 #define PORT_STATUS_CLASS_MASK      GENMASK(7, 4)
0062 #define PORT_STATUS_DETECT_MASK     GENMASK(3, 0)
0063 #define PORT_CLASS_UNKNOWN      0
0064 #define PORT_CLASS_1            1
0065 #define PORT_CLASS_2            2
0066 #define PORT_CLASS_3            3
0067 #define PORT_CLASS_4            4
0068 #define PORT_CLASS_RESERVED     5
0069 #define PORT_CLASS_0            6
0070 #define PORT_CLASS_OVERCURRENT      7
0071 #define PORT_CLASS_MISMATCH     8
0072 #define PORT_DETECT_UNKNOWN     0
0073 #define PORT_DETECT_SHORT       1
0074 #define PORT_DETECT_RESERVED        2
0075 #define PORT_DETECT_RESISTANCE_LOW  3
0076 #define PORT_DETECT_RESISTANCE_OK   4
0077 #define PORT_DETECT_RESISTANCE_HIGH 5
0078 #define PORT_DETECT_OPEN_CIRCUIT    6
0079 #define PORT_DETECT_RESERVED_2      7
0080 #define PORT_DETECT_MOSFET_FAULT    8
0081 #define PORT_DETECT_LEGACY      9
0082 /* Measurment beyond clamp voltage */
0083 #define PORT_DETECT_CAPACITANCE_INVALID_BEYOND  10
0084 /* Insufficient voltage delta */
0085 #define PORT_DETECT_CAPACITANCE_INVALID_DELTA   11
0086 #define PORT_DETECT_CAPACITANCE_OUT_OF_RANGE    12
0087 #define POE_PLUS            0x40
0088 #define OPERATING_MODE          0x12
0089 #define OPERATING_MODE_OFF      0
0090 #define OPERATING_MODE_MANUAL       1
0091 #define OPERATING_MODE_SEMI     2
0092 #define OPERATING_MODE_AUTO     3
0093 #define OPERATING_MODE_PORT_1_MASK  GENMASK(1, 0)
0094 #define OPERATING_MODE_PORT_2_MASK  GENMASK(3, 2)
0095 #define OPERATING_MODE_PORT_3_MASK  GENMASK(5, 4)
0096 #define OPERATING_MODE_PORT_4_MASK  GENMASK(7, 6)
0097 
0098 #define DETECT_CLASS_RESTART        0x18
0099 #define POWER_ENABLE            0x19
0100 #define TPS23861_NUM_PORTS      4
0101 
0102 #define TPS23861_GENERAL_MASK_1     0x17
0103 #define TPS23861_CURRENT_SHUNT_MASK BIT(0)
0104 
0105 #define TEMPERATURE_LSB         652 /* 0.652 degrees Celsius */
0106 #define VOLTAGE_LSB         3662 /* 3.662 mV */
0107 #define SHUNT_RESISTOR_DEFAULT      255000 /* 255 mOhm */
0108 #define CURRENT_LSB_250         62260 /* 62.260 uA */
0109 #define CURRENT_LSB_255         61039 /* 61.039 uA */
0110 #define RESISTANCE_LSB          110966 /* 11.0966 Ohm*/
0111 #define RESISTANCE_LSB_LOW      157216 /* 15.7216 Ohm*/
0112 
0113 struct tps23861_data {
0114     struct regmap *regmap;
0115     u32 shunt_resistor;
0116     struct i2c_client *client;
0117     struct dentry *debugfs_dir;
0118 };
0119 
0120 static struct regmap_config tps23861_regmap_config = {
0121     .reg_bits = 8,
0122     .val_bits = 8,
0123     .max_register = 0x6f,
0124 };
0125 
0126 static int tps23861_read_temp(struct tps23861_data *data, long *val)
0127 {
0128     unsigned int regval;
0129     int err;
0130 
0131     err = regmap_read(data->regmap, TEMPERATURE, &regval);
0132     if (err < 0)
0133         return err;
0134 
0135     *val = (regval * TEMPERATURE_LSB) - 20000;
0136 
0137     return 0;
0138 }
0139 
0140 static int tps23861_read_voltage(struct tps23861_data *data, int channel,
0141                  long *val)
0142 {
0143     __le16 regval;
0144     long raw_val;
0145     int err;
0146 
0147     if (channel < TPS23861_NUM_PORTS) {
0148         err = regmap_bulk_read(data->regmap,
0149                        PORT_1_VOLTAGE_LSB + channel * PORT_N_VOLTAGE_LSB_OFFSET,
0150                        &regval, 2);
0151     } else {
0152         err = regmap_bulk_read(data->regmap,
0153                        INPUT_VOLTAGE_LSB,
0154                        &regval, 2);
0155     }
0156     if (err < 0)
0157         return err;
0158 
0159     raw_val = le16_to_cpu(regval);
0160     *val = (FIELD_GET(VOLTAGE_CURRENT_MASK, raw_val) * VOLTAGE_LSB) / 1000;
0161 
0162     return 0;
0163 }
0164 
0165 static int tps23861_read_current(struct tps23861_data *data, int channel,
0166                  long *val)
0167 {
0168     long raw_val, current_lsb;
0169     __le16 regval;
0170 
0171     int err;
0172 
0173     if (data->shunt_resistor == SHUNT_RESISTOR_DEFAULT)
0174         current_lsb = CURRENT_LSB_255;
0175     else
0176         current_lsb = CURRENT_LSB_250;
0177 
0178     err = regmap_bulk_read(data->regmap,
0179                    PORT_1_CURRENT_LSB + channel * PORT_N_CURRENT_LSB_OFFSET,
0180                    &regval, 2);
0181     if (err < 0)
0182         return err;
0183 
0184     raw_val = le16_to_cpu(regval);
0185     *val = (FIELD_GET(VOLTAGE_CURRENT_MASK, raw_val) * current_lsb) / 1000000;
0186 
0187     return 0;
0188 }
0189 
0190 static int tps23861_port_disable(struct tps23861_data *data, int channel)
0191 {
0192     unsigned int regval = 0;
0193     int err;
0194 
0195     regval |= BIT(channel + 4);
0196     err = regmap_write(data->regmap, POWER_ENABLE, regval);
0197 
0198     return err;
0199 }
0200 
0201 static int tps23861_port_enable(struct tps23861_data *data, int channel)
0202 {
0203     unsigned int regval = 0;
0204     int err;
0205 
0206     regval |= BIT(channel);
0207     regval |= BIT(channel + 4);
0208     err = regmap_write(data->regmap, DETECT_CLASS_RESTART, regval);
0209 
0210     return err;
0211 }
0212 
0213 static umode_t tps23861_is_visible(const void *data, enum hwmon_sensor_types type,
0214                    u32 attr, int channel)
0215 {
0216     switch (type) {
0217     case hwmon_temp:
0218         switch (attr) {
0219         case hwmon_temp_input:
0220         case hwmon_temp_label:
0221             return 0444;
0222         default:
0223             return 0;
0224         }
0225     case hwmon_in:
0226         switch (attr) {
0227         case hwmon_in_input:
0228         case hwmon_in_label:
0229             return 0444;
0230         case hwmon_in_enable:
0231             return 0200;
0232         default:
0233             return 0;
0234         }
0235     case hwmon_curr:
0236         switch (attr) {
0237         case hwmon_curr_input:
0238         case hwmon_curr_label:
0239             return 0444;
0240         default:
0241             return 0;
0242         }
0243     default:
0244         return 0;
0245     }
0246 }
0247 
0248 static int tps23861_write(struct device *dev, enum hwmon_sensor_types type,
0249               u32 attr, int channel, long val)
0250 {
0251     struct tps23861_data *data = dev_get_drvdata(dev);
0252     int err;
0253 
0254     switch (type) {
0255     case hwmon_in:
0256         switch (attr) {
0257         case hwmon_in_enable:
0258             if (val == 0)
0259                 err = tps23861_port_disable(data, channel);
0260             else if (val == 1)
0261                 err = tps23861_port_enable(data, channel);
0262             else
0263                 err = -EINVAL;
0264             break;
0265         default:
0266             return -EOPNOTSUPP;
0267         }
0268         break;
0269     default:
0270         return -EOPNOTSUPP;
0271     }
0272 
0273     return err;
0274 }
0275 
0276 static int tps23861_read(struct device *dev, enum hwmon_sensor_types type,
0277              u32 attr, int channel, long *val)
0278 {
0279     struct tps23861_data *data = dev_get_drvdata(dev);
0280     int err;
0281 
0282     switch (type) {
0283     case hwmon_temp:
0284         switch (attr) {
0285         case hwmon_temp_input:
0286             err = tps23861_read_temp(data, val);
0287             break;
0288         default:
0289             return -EOPNOTSUPP;
0290         }
0291         break;
0292     case hwmon_in:
0293         switch (attr) {
0294         case hwmon_in_input:
0295             err = tps23861_read_voltage(data, channel, val);
0296             break;
0297         default:
0298             return -EOPNOTSUPP;
0299         }
0300         break;
0301     case hwmon_curr:
0302         switch (attr) {
0303         case hwmon_curr_input:
0304             err = tps23861_read_current(data, channel, val);
0305             break;
0306         default:
0307             return -EOPNOTSUPP;
0308         }
0309         break;
0310     default:
0311         return -EOPNOTSUPP;
0312     }
0313 
0314     return err;
0315 }
0316 
0317 static const char * const tps23861_port_label[] = {
0318     "Port1",
0319     "Port2",
0320     "Port3",
0321     "Port4",
0322     "Input",
0323 };
0324 
0325 static int tps23861_read_string(struct device *dev,
0326                 enum hwmon_sensor_types type,
0327                 u32 attr, int channel, const char **str)
0328 {
0329     switch (type) {
0330     case hwmon_in:
0331     case hwmon_curr:
0332         *str = tps23861_port_label[channel];
0333         break;
0334     case hwmon_temp:
0335         *str = "Die";
0336         break;
0337     default:
0338         return -EOPNOTSUPP;
0339     }
0340 
0341     return 0;
0342 }
0343 
0344 static const struct hwmon_channel_info *tps23861_info[] = {
0345     HWMON_CHANNEL_INFO(chip,
0346                HWMON_C_REGISTER_TZ),
0347     HWMON_CHANNEL_INFO(temp,
0348                HWMON_T_INPUT | HWMON_T_LABEL),
0349     HWMON_CHANNEL_INFO(in,
0350                HWMON_I_INPUT | HWMON_I_ENABLE | HWMON_I_LABEL,
0351                HWMON_I_INPUT | HWMON_I_ENABLE | HWMON_I_LABEL,
0352                HWMON_I_INPUT | HWMON_I_ENABLE | HWMON_I_LABEL,
0353                HWMON_I_INPUT | HWMON_I_ENABLE | HWMON_I_LABEL,
0354                HWMON_I_INPUT | HWMON_I_LABEL),
0355     HWMON_CHANNEL_INFO(curr,
0356                HWMON_C_INPUT | HWMON_C_LABEL,
0357                HWMON_C_INPUT | HWMON_C_LABEL,
0358                HWMON_C_INPUT | HWMON_C_LABEL,
0359                HWMON_C_INPUT | HWMON_C_LABEL),
0360     NULL
0361 };
0362 
0363 static const struct hwmon_ops tps23861_hwmon_ops = {
0364     .is_visible = tps23861_is_visible,
0365     .write = tps23861_write,
0366     .read = tps23861_read,
0367     .read_string = tps23861_read_string,
0368 };
0369 
0370 static const struct hwmon_chip_info tps23861_chip_info = {
0371     .ops = &tps23861_hwmon_ops,
0372     .info = tps23861_info,
0373 };
0374 
0375 static char *tps23861_port_operating_mode(struct tps23861_data *data, int port)
0376 {
0377     unsigned int regval;
0378     int mode;
0379 
0380     regmap_read(data->regmap, OPERATING_MODE, &regval);
0381 
0382     switch (port) {
0383     case 1:
0384         mode = FIELD_GET(OPERATING_MODE_PORT_1_MASK, regval);
0385         break;
0386     case 2:
0387         mode = FIELD_GET(OPERATING_MODE_PORT_2_MASK, regval);
0388         break;
0389     case 3:
0390         mode = FIELD_GET(OPERATING_MODE_PORT_3_MASK, regval);
0391         break;
0392     case 4:
0393         mode = FIELD_GET(OPERATING_MODE_PORT_4_MASK, regval);
0394         break;
0395     default:
0396         mode = -EINVAL;
0397     }
0398 
0399     switch (mode) {
0400     case OPERATING_MODE_OFF:
0401         return "Off";
0402     case OPERATING_MODE_MANUAL:
0403         return "Manual";
0404     case OPERATING_MODE_SEMI:
0405         return "Semi-Auto";
0406     case OPERATING_MODE_AUTO:
0407         return "Auto";
0408     default:
0409         return "Invalid";
0410     }
0411 }
0412 
0413 static char *tps23861_port_detect_status(struct tps23861_data *data, int port)
0414 {
0415     unsigned int regval;
0416 
0417     regmap_read(data->regmap,
0418             PORT_1_STATUS + (port - 1),
0419             &regval);
0420 
0421     switch (FIELD_GET(PORT_STATUS_DETECT_MASK, regval)) {
0422     case PORT_DETECT_UNKNOWN:
0423         return "Unknown device";
0424     case PORT_DETECT_SHORT:
0425         return "Short circuit";
0426     case PORT_DETECT_RESISTANCE_LOW:
0427         return "Too low resistance";
0428     case PORT_DETECT_RESISTANCE_OK:
0429         return "Valid resistance";
0430     case PORT_DETECT_RESISTANCE_HIGH:
0431         return "Too high resistance";
0432     case PORT_DETECT_OPEN_CIRCUIT:
0433         return "Open circuit";
0434     case PORT_DETECT_MOSFET_FAULT:
0435         return "MOSFET fault";
0436     case PORT_DETECT_LEGACY:
0437         return "Legacy device";
0438     case PORT_DETECT_CAPACITANCE_INVALID_BEYOND:
0439         return "Invalid capacitance, beyond clamp voltage";
0440     case PORT_DETECT_CAPACITANCE_INVALID_DELTA:
0441         return "Invalid capacitance, insufficient voltage delta";
0442     case PORT_DETECT_CAPACITANCE_OUT_OF_RANGE:
0443         return "Valid capacitance, outside of legacy range";
0444     case PORT_DETECT_RESERVED:
0445     case PORT_DETECT_RESERVED_2:
0446     default:
0447         return "Invalid";
0448     }
0449 }
0450 
0451 static char *tps23861_port_class_status(struct tps23861_data *data, int port)
0452 {
0453     unsigned int regval;
0454 
0455     regmap_read(data->regmap,
0456             PORT_1_STATUS + (port - 1),
0457             &regval);
0458 
0459     switch (FIELD_GET(PORT_STATUS_CLASS_MASK, regval)) {
0460     case PORT_CLASS_UNKNOWN:
0461         return "Unknown";
0462     case PORT_CLASS_RESERVED:
0463     case PORT_CLASS_0:
0464         return "0";
0465     case PORT_CLASS_1:
0466         return "1";
0467     case PORT_CLASS_2:
0468         return "2";
0469     case PORT_CLASS_3:
0470         return "3";
0471     case PORT_CLASS_4:
0472         return "4";
0473     case PORT_CLASS_OVERCURRENT:
0474         return "Overcurrent";
0475     case PORT_CLASS_MISMATCH:
0476         return "Mismatch";
0477     default:
0478         return "Invalid";
0479     }
0480 }
0481 
0482 static char *tps23861_port_poe_plus_status(struct tps23861_data *data, int port)
0483 {
0484     unsigned int regval;
0485 
0486     regmap_read(data->regmap, POE_PLUS, &regval);
0487 
0488     if (BIT(port + 3) & regval)
0489         return "Yes";
0490     else
0491         return "No";
0492 }
0493 
0494 static int tps23861_port_resistance(struct tps23861_data *data, int port)
0495 {
0496     unsigned int raw_val;
0497     __le16 regval;
0498 
0499     regmap_bulk_read(data->regmap,
0500              PORT_1_RESISTANCE_LSB + PORT_N_RESISTANCE_LSB_OFFSET * (port - 1),
0501              &regval,
0502              2);
0503 
0504     raw_val = le16_to_cpu(regval);
0505     switch (FIELD_GET(PORT_RESISTANCE_RSN_MASK, raw_val)) {
0506     case PORT_RESISTANCE_RSN_OTHER:
0507         return (FIELD_GET(PORT_RESISTANCE_MASK, raw_val) * RESISTANCE_LSB) / 10000;
0508     case PORT_RESISTANCE_RSN_LOW:
0509         return (FIELD_GET(PORT_RESISTANCE_MASK, raw_val) * RESISTANCE_LSB_LOW) / 10000;
0510     case PORT_RESISTANCE_RSN_SHORT:
0511     case PORT_RESISTANCE_RSN_OPEN:
0512     default:
0513         return 0;
0514     }
0515 }
0516 
0517 static int tps23861_port_status_show(struct seq_file *s, void *data)
0518 {
0519     struct tps23861_data *priv = s->private;
0520     int i;
0521 
0522     for (i = 1; i < TPS23861_NUM_PORTS + 1; i++) {
0523         seq_printf(s, "Port: \t\t%d\n", i);
0524         seq_printf(s, "Operating mode: %s\n", tps23861_port_operating_mode(priv, i));
0525         seq_printf(s, "Detected: \t%s\n", tps23861_port_detect_status(priv, i));
0526         seq_printf(s, "Class: \t\t%s\n", tps23861_port_class_status(priv, i));
0527         seq_printf(s, "PoE Plus: \t%s\n", tps23861_port_poe_plus_status(priv, i));
0528         seq_printf(s, "Resistance: \t%d\n", tps23861_port_resistance(priv, i));
0529         seq_putc(s, '\n');
0530     }
0531 
0532     return 0;
0533 }
0534 
0535 DEFINE_SHOW_ATTRIBUTE(tps23861_port_status);
0536 
0537 static void tps23861_init_debugfs(struct tps23861_data *data)
0538 {
0539     data->debugfs_dir = debugfs_create_dir(data->client->name, NULL);
0540 
0541     debugfs_create_file("port_status",
0542                 0400,
0543                 data->debugfs_dir,
0544                 data,
0545                 &tps23861_port_status_fops);
0546 }
0547 
0548 static int tps23861_probe(struct i2c_client *client)
0549 {
0550     struct device *dev = &client->dev;
0551     struct tps23861_data *data;
0552     struct device *hwmon_dev;
0553     u32 shunt_resistor;
0554 
0555     data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
0556     if (!data)
0557         return -ENOMEM;
0558 
0559     data->client = client;
0560     i2c_set_clientdata(client, data);
0561 
0562     data->regmap = devm_regmap_init_i2c(client, &tps23861_regmap_config);
0563     if (IS_ERR(data->regmap)) {
0564         dev_err(dev, "failed to allocate register map\n");
0565         return PTR_ERR(data->regmap);
0566     }
0567 
0568     if (!of_property_read_u32(dev->of_node, "shunt-resistor-micro-ohms", &shunt_resistor))
0569         data->shunt_resistor = shunt_resistor;
0570     else
0571         data->shunt_resistor = SHUNT_RESISTOR_DEFAULT;
0572 
0573     if (data->shunt_resistor == SHUNT_RESISTOR_DEFAULT)
0574         regmap_clear_bits(data->regmap,
0575                   TPS23861_GENERAL_MASK_1,
0576                   TPS23861_CURRENT_SHUNT_MASK);
0577     else
0578         regmap_set_bits(data->regmap,
0579                 TPS23861_GENERAL_MASK_1,
0580                 TPS23861_CURRENT_SHUNT_MASK);
0581 
0582     hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
0583                              data, &tps23861_chip_info,
0584                              NULL);
0585     if (IS_ERR(hwmon_dev))
0586         return PTR_ERR(hwmon_dev);
0587 
0588     tps23861_init_debugfs(data);
0589 
0590     return 0;
0591 }
0592 
0593 static int tps23861_remove(struct i2c_client *client)
0594 {
0595     struct tps23861_data *data = i2c_get_clientdata(client);
0596 
0597     debugfs_remove_recursive(data->debugfs_dir);
0598 
0599     return 0;
0600 }
0601 
0602 static const struct of_device_id __maybe_unused tps23861_of_match[] = {
0603     { .compatible = "ti,tps23861", },
0604     { },
0605 };
0606 MODULE_DEVICE_TABLE(of, tps23861_of_match);
0607 
0608 static struct i2c_driver tps23861_driver = {
0609     .probe_new      = tps23861_probe,
0610     .remove         = tps23861_remove,
0611     .driver = {
0612         .name       = "tps23861",
0613         .of_match_table = of_match_ptr(tps23861_of_match),
0614     },
0615 };
0616 module_i2c_driver(tps23861_driver);
0617 
0618 MODULE_LICENSE("GPL");
0619 MODULE_AUTHOR("Robert Marko <robert.marko@sartura.hr>");
0620 MODULE_DESCRIPTION("TI TPS23861 PoE PSE");