0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/err.h>
0011 #include <linux/i2c.h>
0012 #include <linux/init.h>
0013 #include <linux/hwmon.h>
0014 #include <linux/module.h>
0015 #include <linux/mutex.h>
0016 #include <linux/of_device.h>
0017 #include <linux/of.h>
0018
0019
0020
0021
0022
0023
0024 #define SBTSI_REG_TEMP_INT 0x01
0025 #define SBTSI_REG_STATUS 0x02
0026 #define SBTSI_REG_CONFIG 0x03
0027 #define SBTSI_REG_TEMP_HIGH_INT 0x07
0028 #define SBTSI_REG_TEMP_LOW_INT 0x08
0029 #define SBTSI_REG_TEMP_DEC 0x10
0030 #define SBTSI_REG_TEMP_HIGH_DEC 0x13
0031 #define SBTSI_REG_TEMP_LOW_DEC 0x14
0032
0033 #define SBTSI_CONFIG_READ_ORDER_SHIFT 5
0034
0035 #define SBTSI_TEMP_MIN 0
0036 #define SBTSI_TEMP_MAX 255875
0037
0038
0039 struct sbtsi_data {
0040 struct i2c_client *client;
0041 struct mutex lock;
0042 };
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055 static inline int sbtsi_reg_to_mc(s32 integer, s32 decimal)
0056 {
0057 return ((integer << 3) + (decimal >> 5)) * 125;
0058 }
0059
0060
0061
0062
0063
0064
0065
0066 static inline void sbtsi_mc_to_reg(s32 temp, u8 *integer, u8 *decimal)
0067 {
0068 temp /= 125;
0069 *integer = temp >> 3;
0070 *decimal = (temp & 0x7) << 5;
0071 }
0072
0073 static int sbtsi_read(struct device *dev, enum hwmon_sensor_types type,
0074 u32 attr, int channel, long *val)
0075 {
0076 struct sbtsi_data *data = dev_get_drvdata(dev);
0077 s32 temp_int, temp_dec;
0078 int err;
0079
0080 switch (attr) {
0081 case hwmon_temp_input:
0082
0083
0084
0085
0086
0087
0088
0089 err = i2c_smbus_read_byte_data(data->client, SBTSI_REG_CONFIG);
0090 if (err < 0)
0091 return err;
0092
0093 mutex_lock(&data->lock);
0094 if (err & BIT(SBTSI_CONFIG_READ_ORDER_SHIFT)) {
0095 temp_dec = i2c_smbus_read_byte_data(data->client, SBTSI_REG_TEMP_DEC);
0096 temp_int = i2c_smbus_read_byte_data(data->client, SBTSI_REG_TEMP_INT);
0097 } else {
0098 temp_int = i2c_smbus_read_byte_data(data->client, SBTSI_REG_TEMP_INT);
0099 temp_dec = i2c_smbus_read_byte_data(data->client, SBTSI_REG_TEMP_DEC);
0100 }
0101 mutex_unlock(&data->lock);
0102 break;
0103 case hwmon_temp_max:
0104 mutex_lock(&data->lock);
0105 temp_int = i2c_smbus_read_byte_data(data->client, SBTSI_REG_TEMP_HIGH_INT);
0106 temp_dec = i2c_smbus_read_byte_data(data->client, SBTSI_REG_TEMP_HIGH_DEC);
0107 mutex_unlock(&data->lock);
0108 break;
0109 case hwmon_temp_min:
0110 mutex_lock(&data->lock);
0111 temp_int = i2c_smbus_read_byte_data(data->client, SBTSI_REG_TEMP_LOW_INT);
0112 temp_dec = i2c_smbus_read_byte_data(data->client, SBTSI_REG_TEMP_LOW_DEC);
0113 mutex_unlock(&data->lock);
0114 break;
0115 default:
0116 return -EINVAL;
0117 }
0118
0119
0120 if (temp_int < 0)
0121 return temp_int;
0122 if (temp_dec < 0)
0123 return temp_dec;
0124
0125 *val = sbtsi_reg_to_mc(temp_int, temp_dec);
0126
0127 return 0;
0128 }
0129
0130 static int sbtsi_write(struct device *dev, enum hwmon_sensor_types type,
0131 u32 attr, int channel, long val)
0132 {
0133 struct sbtsi_data *data = dev_get_drvdata(dev);
0134 int reg_int, reg_dec, err;
0135 u8 temp_int, temp_dec;
0136
0137 switch (attr) {
0138 case hwmon_temp_max:
0139 reg_int = SBTSI_REG_TEMP_HIGH_INT;
0140 reg_dec = SBTSI_REG_TEMP_HIGH_DEC;
0141 break;
0142 case hwmon_temp_min:
0143 reg_int = SBTSI_REG_TEMP_LOW_INT;
0144 reg_dec = SBTSI_REG_TEMP_LOW_DEC;
0145 break;
0146 default:
0147 return -EINVAL;
0148 }
0149
0150 val = clamp_val(val, SBTSI_TEMP_MIN, SBTSI_TEMP_MAX);
0151 sbtsi_mc_to_reg(val, &temp_int, &temp_dec);
0152
0153 mutex_lock(&data->lock);
0154 err = i2c_smbus_write_byte_data(data->client, reg_int, temp_int);
0155 if (err)
0156 goto exit;
0157
0158 err = i2c_smbus_write_byte_data(data->client, reg_dec, temp_dec);
0159 exit:
0160 mutex_unlock(&data->lock);
0161 return err;
0162 }
0163
0164 static umode_t sbtsi_is_visible(const void *data,
0165 enum hwmon_sensor_types type,
0166 u32 attr, int channel)
0167 {
0168 switch (type) {
0169 case hwmon_temp:
0170 switch (attr) {
0171 case hwmon_temp_input:
0172 return 0444;
0173 case hwmon_temp_min:
0174 return 0644;
0175 case hwmon_temp_max:
0176 return 0644;
0177 }
0178 break;
0179 default:
0180 break;
0181 }
0182 return 0;
0183 }
0184
0185 static const struct hwmon_channel_info *sbtsi_info[] = {
0186 HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
0187 HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX),
0188 NULL
0189 };
0190
0191 static const struct hwmon_ops sbtsi_hwmon_ops = {
0192 .is_visible = sbtsi_is_visible,
0193 .read = sbtsi_read,
0194 .write = sbtsi_write,
0195 };
0196
0197 static const struct hwmon_chip_info sbtsi_chip_info = {
0198 .ops = &sbtsi_hwmon_ops,
0199 .info = sbtsi_info,
0200 };
0201
0202 static int sbtsi_probe(struct i2c_client *client,
0203 const struct i2c_device_id *id)
0204 {
0205 struct device *dev = &client->dev;
0206 struct device *hwmon_dev;
0207 struct sbtsi_data *data;
0208
0209 data = devm_kzalloc(dev, sizeof(struct sbtsi_data), GFP_KERNEL);
0210 if (!data)
0211 return -ENOMEM;
0212
0213 data->client = client;
0214 mutex_init(&data->lock);
0215
0216 hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, data, &sbtsi_chip_info,
0217 NULL);
0218
0219 return PTR_ERR_OR_ZERO(hwmon_dev);
0220 }
0221
0222 static const struct i2c_device_id sbtsi_id[] = {
0223 {"sbtsi", 0},
0224 {}
0225 };
0226 MODULE_DEVICE_TABLE(i2c, sbtsi_id);
0227
0228 static const struct of_device_id __maybe_unused sbtsi_of_match[] = {
0229 {
0230 .compatible = "amd,sbtsi",
0231 },
0232 { },
0233 };
0234 MODULE_DEVICE_TABLE(of, sbtsi_of_match);
0235
0236 static struct i2c_driver sbtsi_driver = {
0237 .class = I2C_CLASS_HWMON,
0238 .driver = {
0239 .name = "sbtsi",
0240 .of_match_table = of_match_ptr(sbtsi_of_match),
0241 },
0242 .probe = sbtsi_probe,
0243 .id_table = sbtsi_id,
0244 };
0245
0246 module_i2c_driver(sbtsi_driver);
0247
0248 MODULE_AUTHOR("Kun Yi <kunyi@google.com>");
0249 MODULE_DESCRIPTION("Hwmon driver for AMD SB-TSI emulated sensor");
0250 MODULE_LICENSE("GPL");