1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2024 Maya Matuszczyk <maccraft123mc@gmail.com> 4 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 */ 6 7 #include <linux/bitfield.h> 8 #include <linux/bits.h> 9 #include <linux/device.h> 10 #include <linux/dev_printk.h> 11 #include <linux/err.h> 12 #include <linux/i2c.h> 13 #include <linux/interrupt.h> 14 #include <linux/kernel.h> 15 #include <linux/module.h> 16 #include <linux/pm.h> 17 #include <linux/slab.h> 18 #include <linux/thermal.h> 19 20 #define EC_SCI_EVT_READ_CMD 0x05 21 #define EC_FW_VERSION_CMD 0x0e 22 #define EC_MODERN_STANDBY_CMD 0x23 23 #define EC_FAN_DBG_CONTROL_CMD 0x30 24 #define EC_SCI_EVT_CONTROL_CMD 0x35 25 #define EC_THERMAL_CAP_CMD 0x42 26 27 #define EC_FW_VERSION_RESP_LEN 4 28 #define EC_THERMAL_CAP_RESP_LEN 3 29 #define EC_FAN_DEBUG_CMD_LEN 6 30 #define EC_FAN_SPEED_DATA_SIZE 4 31 32 #define EC_MODERN_STANDBY_ENTER 0x01 33 #define EC_MODERN_STANDBY_EXIT 0x00 34 35 #define EC_FAN_DEBUG_MODE_OFF 0 36 #define EC_FAN_DEBUG_MODE_ON BIT(0) 37 #define EC_FAN_ON BIT(1) 38 #define EC_FAN_DEBUG_TYPE_PWM BIT(2) 39 #define EC_MAX_FAN_CNT 2 40 #define EC_FAN_NAME_SIZE 20 41 #define EC_FAN_MAX_PWM 255 42 43 enum qcom_ec_sci_events { 44 EC_FAN1_STATUS_CHANGE_EVT = 0x30, 45 EC_FAN2_STATUS_CHANGE_EVT, 46 EC_FAN1_SPEED_CHANGE_EVT, 47 EC_FAN2_SPEED_CHANGE_EVT, 48 EC_NEW_LUT_SET_EVT, 49 EC_FAN_PROFILE_SWITCH_EVT, 50 EC_THERMISTOR_1_THRESHOLD_CROSS_EVT, 51 EC_THERMISTOR_2_THRESHOLD_CROSS_EVT, 52 EC_THERMISTOR_3_THRESHOLD_CROSS_EVT, 53 /* Reserved: 0x39 - 0x3c/0x3f */ 54 EC_RECOVERED_FROM_RESET_EVT = 0x3d, 55 }; 56 57 struct qcom_ec_version { 58 u8 main_version; 59 u8 sub_version; 60 u8 test_version; 61 }; 62 63 struct qcom_ec_thermal_cap { 64 #define EC_THERMAL_FAN_CNT(x) (FIELD_GET(GENMASK(1, 0), (x))) 65 #define EC_THERMAL_FAN_TYPE(x) (FIELD_GET(GENMASK(4, 2), (x))) 66 #define EC_THERMAL_THERMISTOR_MASK(x) (FIELD_GET(GENMASK(7, 0), (x))) 67 u8 fan_cnt; 68 u8 fan_type; 69 u8 thermistor_mask; 70 }; 71 72 struct qcom_ec_cooling_dev { 73 struct thermal_cooling_device *cdev; 74 struct device *parent_dev; 75 u8 fan_id; 76 u8 state; 77 }; 78 79 struct qcom_ec { 80 struct qcom_ec_cooling_dev *ec_cdev; 81 struct qcom_ec_thermal_cap thermal_cap; 82 struct qcom_ec_version version; 83 struct i2c_client *client; 84 }; 85 86 static int qcom_ec_read(struct qcom_ec *ec, u8 cmd, u8 resp_len, u8 *resp) 87 { 88 int ret; 89 90 ret = i2c_smbus_read_i2c_block_data(ec->client, cmd, resp_len, resp); 91 if (ret < 0) 92 return ret; 93 else if (ret == 0 || ret == 0xff) 94 return -EOPNOTSUPP; 95 96 if (resp[0] >= resp_len) 97 return -EINVAL; 98 99 return 0; 100 } 101 102 /* 103 * EC Device Firmware Version: 104 * 105 * Read Response: 106 * ---------------------------------------------------------------------- 107 * | Offset | Name | Description | 108 * ---------------------------------------------------------------------- 109 * | 0x00 | Byte count | Number of bytes in response | 110 * | | | (excluding byte count) | 111 * ---------------------------------------------------------------------- 112 * | 0x01 | Test-version | Test-version of EC firmware | 113 * ---------------------------------------------------------------------- 114 * | 0x02 | Sub-version | Sub-version of EC firmware | 115 * ---------------------------------------------------------------------- 116 * | 0x03 | Main-version | Main-version of EC firmware | 117 * ---------------------------------------------------------------------- 118 * 119 */ 120 static int qcom_ec_read_fw_version(struct device *dev) 121 { 122 struct i2c_client *client = to_i2c_client(dev); 123 struct qcom_ec *ec = i2c_get_clientdata(client); 124 struct qcom_ec_version *version = &ec->version; 125 u8 resp[EC_FW_VERSION_RESP_LEN]; 126 int ret; 127 128 ret = qcom_ec_read(ec, EC_FW_VERSION_CMD, EC_FW_VERSION_RESP_LEN, resp); 129 if (ret < 0) 130 return ret; 131 132 version->main_version = resp[3]; 133 version->sub_version = resp[2]; 134 version->test_version = resp[1]; 135 136 dev_dbg(dev, "EC Version %d.%d.%d\n", 137 version->main_version, version->sub_version, version->test_version); 138 139 return 0; 140 } 141 142 /* 143 * EC Device Thermal Capabilities: 144 * 145 * Read Response: 146 * ------------------------------------------------------------------------------ 147 * | Offset | Name | Description | 148 * ------------------------------------------------------------------------------ 149 * | 0x00 | Byte count | Number of bytes in response | 150 * | | | (excluding byte count) | 151 * ------------------------------------------------------------------------------ 152 * | 0x02 (LSB) | EC Thermal | Bit 0-1: Number of fans | 153 * | 0x03 | Capabilities | Bit 2-4: Type of fan | 154 * | | | Bit 5-6: Reserved | 155 * | | | Bit 7: Data Valid/Invalid | 156 * | | | (Valid - 1, Invalid - 0) | 157 * | | | Bit 8-15: Thermistor 0 - 7 presence | 158 * | | | (1 present, 0 absent) | 159 * ------------------------------------------------------------------------------ 160 * 161 */ 162 static int qcom_ec_thermal_capabilities(struct device *dev) 163 { 164 struct i2c_client *client = to_i2c_client(dev); 165 struct qcom_ec *ec = i2c_get_clientdata(client); 166 struct qcom_ec_thermal_cap *cap = &ec->thermal_cap; 167 u8 resp[EC_THERMAL_CAP_RESP_LEN]; 168 int ret; 169 170 ret = qcom_ec_read(ec, EC_THERMAL_CAP_CMD, EC_THERMAL_CAP_RESP_LEN, resp); 171 if (ret < 0) 172 return ret; 173 174 cap->fan_cnt = min(EC_MAX_FAN_CNT, EC_THERMAL_FAN_CNT(resp[1])); 175 cap->fan_type = EC_THERMAL_FAN_TYPE(resp[1]); 176 cap->thermistor_mask = EC_THERMAL_THERMISTOR_MASK(resp[2]); 177 178 dev_dbg(dev, "Fan count: %d Fan Type: %d Thermistor Mask: %x\n", 179 cap->fan_cnt, cap->fan_type, cap->thermistor_mask); 180 181 return 0; 182 } 183 184 static irqreturn_t qcom_ec_irq(int irq, void *data) 185 { 186 struct qcom_ec *ec = data; 187 struct device *dev = &ec->client->dev; 188 int val; 189 190 val = i2c_smbus_read_byte_data(ec->client, EC_SCI_EVT_READ_CMD); 191 if (val < 0) { 192 dev_err_ratelimited(dev, "Failed to read EC SCI Event: %d\n", val); 193 return IRQ_HANDLED; 194 } 195 196 switch (val) { 197 case EC_FAN1_STATUS_CHANGE_EVT: 198 dev_dbg_ratelimited(dev, "Fan1 status changed\n"); 199 break; 200 case EC_FAN2_STATUS_CHANGE_EVT: 201 dev_dbg_ratelimited(dev, "Fan2 status changed\n"); 202 break; 203 case EC_FAN1_SPEED_CHANGE_EVT: 204 dev_dbg_ratelimited(dev, "Fan1 speed crossed low/high trip point\n"); 205 break; 206 case EC_FAN2_SPEED_CHANGE_EVT: 207 dev_dbg_ratelimited(dev, "Fan2 speed crossed low/high trip point\n"); 208 break; 209 case EC_NEW_LUT_SET_EVT: 210 dev_dbg_ratelimited(dev, "New LUT set\n"); 211 break; 212 case EC_FAN_PROFILE_SWITCH_EVT: 213 dev_dbg_ratelimited(dev, "FAN Profile switched\n"); 214 break; 215 case EC_THERMISTOR_1_THRESHOLD_CROSS_EVT: 216 dev_dbg_ratelimited(dev, "Thermistor 1 threshold crossed\n"); 217 break; 218 case EC_THERMISTOR_2_THRESHOLD_CROSS_EVT: 219 dev_dbg_ratelimited(dev, "Thermistor 2 threshold crossed\n"); 220 break; 221 case EC_THERMISTOR_3_THRESHOLD_CROSS_EVT: 222 dev_dbg_ratelimited(dev, "Thermistor 3 threshold crossed\n"); 223 break; 224 case EC_RECOVERED_FROM_RESET_EVT: 225 dev_dbg_ratelimited(dev, "EC recovered from reset\n"); 226 break; 227 default: 228 dev_notice_ratelimited(dev, "Unknown EC event: %d\n", val); 229 break; 230 } 231 232 return IRQ_HANDLED; 233 } 234 235 static int qcom_ec_sci_evt_control(struct device *dev, bool enable) 236 { 237 struct i2c_client *client = to_i2c_client(dev); 238 239 return i2c_smbus_write_byte_data(client, EC_SCI_EVT_CONTROL_CMD, enable ? 1 : 0); 240 } 241 242 static int qcom_ec_fan_get_max_state(struct thermal_cooling_device *cdev, unsigned long *state) 243 { 244 *state = EC_FAN_MAX_PWM; 245 246 return 0; 247 } 248 249 static int qcom_ec_fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long *state) 250 { 251 struct qcom_ec_cooling_dev *ec_cdev = cdev->devdata; 252 253 *state = ec_cdev->state; 254 255 return 0; 256 } 257 258 /* 259 * Fan Debug control command: 260 * 261 * Command Payload: 262 * -------------------------------------------------------------------------------------- 263 * | Offset | Name | Description | 264 * -------------------------------------------------------------------------------------- 265 * | 0x00 | Command | Fan control command | 266 * -------------------------------------------------------------------------------------- 267 * | 0x01 | Fan ID | 0x1 : Fan 1 | 268 * | | | 0x2 : Fan 2 | 269 * -------------------------------------------------------------------------------------- 270 * | 0x02 | Byte count = 4| Size of data to set fan speed | 271 * -------------------------------------------------------------------------------------- 272 * | 0x03 | Mode | Bit 0: Debug Mode On/Off (0 - OFF, 1 - ON ) | 273 * | | | Bit 1: Fan On/Off (0 - Off, 1 - ON) | 274 * | | | Bit 2: Debug Type (0 - RPM, 1 - PWM) | 275 * -------------------------------------------------------------------------------------- 276 * | 0x04 (LSB) | Speed in RPM | RPM value, if mode selected is RPM | 277 * | 0x05 | | | 278 * -------------------------------------------------------------------------------------- 279 * | 0x06 | Speed in PWM | PWM value, if mode selected is PWM (0 - 255) | 280 * ______________________________________________________________________________________ 281 * 282 */ 283 static int qcom_ec_fan_debug_mode_off(struct qcom_ec_cooling_dev *ec_cdev) 284 { 285 struct device *dev = ec_cdev->parent_dev; 286 struct i2c_client *client = to_i2c_client(dev); 287 u8 request[6] = { ec_cdev->fan_id, EC_FAN_SPEED_DATA_SIZE, 288 EC_FAN_DEBUG_MODE_OFF, 0, 0, 0 }; 289 int ret; 290 291 ret = i2c_smbus_write_i2c_block_data(client, EC_FAN_DBG_CONTROL_CMD, 292 sizeof(request), request); 293 if (ret) { 294 dev_err(dev, "Failed to turn off fan%d debug mode: %d\n", 295 ec_cdev->fan_id, ret); 296 } 297 298 return ret; 299 } 300 301 static int qcom_ec_fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state) 302 { 303 struct qcom_ec_cooling_dev *ec_cdev = cdev->devdata; 304 struct device *dev = ec_cdev->parent_dev; 305 struct i2c_client *client = to_i2c_client(dev); 306 u8 request[6] = { ec_cdev->fan_id, EC_FAN_SPEED_DATA_SIZE, 307 EC_FAN_DEBUG_MODE_ON | EC_FAN_ON | EC_FAN_DEBUG_TYPE_PWM, 308 0, 0, state }; 309 int ret; 310 311 ret = i2c_smbus_write_i2c_block_data(client, EC_FAN_DBG_CONTROL_CMD, 312 sizeof(request), request); 313 if (ret) { 314 dev_err(dev, "Failed to set fan pwm: %d\n", ret); 315 return ret; 316 } 317 318 ec_cdev->state = state; 319 320 return 0; 321 } 322 323 static const struct thermal_cooling_device_ops qcom_ec_thermal_ops = { 324 .get_max_state = qcom_ec_fan_get_max_state, 325 .get_cur_state = qcom_ec_fan_get_cur_state, 326 .set_cur_state = qcom_ec_fan_set_cur_state, 327 }; 328 329 static int qcom_ec_resume(struct device *dev) 330 { 331 struct i2c_client *client = to_i2c_client(dev); 332 333 return i2c_smbus_write_byte_data(client, EC_MODERN_STANDBY_CMD, 334 EC_MODERN_STANDBY_EXIT); 335 } 336 337 static int qcom_ec_suspend(struct device *dev) 338 { 339 struct i2c_client *client = to_i2c_client(dev); 340 341 return i2c_smbus_write_byte_data(client, EC_MODERN_STANDBY_CMD, 342 EC_MODERN_STANDBY_ENTER); 343 } 344 345 static int qcom_ec_probe(struct i2c_client *client) 346 { 347 struct device *dev = &client->dev; 348 struct qcom_ec *ec; 349 unsigned int i; 350 int ret; 351 352 ec = devm_kzalloc(dev, sizeof(*ec), GFP_KERNEL); 353 if (!ec) 354 return -ENOMEM; 355 356 ec->client = client; 357 358 ret = devm_request_threaded_irq(dev, client->irq, NULL, qcom_ec_irq, 359 IRQF_ONESHOT, "qcom_ec", ec); 360 if (ret < 0) 361 return ret; 362 363 i2c_set_clientdata(client, ec); 364 365 ret = qcom_ec_read_fw_version(dev); 366 if (ret < 0) 367 return dev_err_probe(dev, ret, "Failed to read EC firmware version\n"); 368 369 ret = qcom_ec_sci_evt_control(dev, true); 370 if (ret < 0) 371 return dev_err_probe(dev, ret, "Failed to enable SCI events\n"); 372 373 ret = qcom_ec_thermal_capabilities(dev); 374 if (ret < 0) 375 return dev_err_probe(dev, ret, "Failed to read thermal capabilities\n"); 376 377 if (ec->thermal_cap.fan_cnt == 0) { 378 dev_warn(dev, FW_BUG "Failed to get fan count, firmware update required\n"); 379 return 0; 380 } 381 382 ec->ec_cdev = devm_kcalloc(dev, ec->thermal_cap.fan_cnt, sizeof(*ec->ec_cdev), GFP_KERNEL); 383 if (!ec->ec_cdev) 384 return -ENOMEM; 385 386 for (i = 0; i < ec->thermal_cap.fan_cnt; i++) { 387 struct qcom_ec_cooling_dev *ec_cdev = &ec->ec_cdev[i]; 388 char name[EC_FAN_NAME_SIZE]; 389 390 scnprintf(name, sizeof(name), "qcom_ec_fan_%u", i); 391 ec_cdev->fan_id = i + 1; 392 ec_cdev->parent_dev = dev; 393 394 ec_cdev->cdev = devm_thermal_of_cooling_device_register(dev, NULL, name, ec_cdev, 395 &qcom_ec_thermal_ops); 396 if (IS_ERR(ec_cdev->cdev)) { 397 return dev_err_probe(dev, PTR_ERR(ec_cdev->cdev), 398 "Failed to register fan%d cooling device\n", i); 399 } 400 } 401 402 return 0; 403 } 404 405 static void qcom_ec_remove(struct i2c_client *client) 406 { 407 struct qcom_ec *ec = i2c_get_clientdata(client); 408 struct device *dev = &client->dev; 409 int ret; 410 411 ret = qcom_ec_sci_evt_control(dev, false); 412 if (ret < 0) 413 dev_err(dev, "Failed to disable SCI events: %d\n", ret); 414 415 for (int i = 0; i < ec->thermal_cap.fan_cnt; i++) { 416 struct qcom_ec_cooling_dev *ec_cdev = &ec->ec_cdev[i]; 417 418 qcom_ec_fan_debug_mode_off(ec_cdev); 419 } 420 } 421 422 static const struct of_device_id qcom_ec_of_match[] = { 423 { .compatible = "qcom,hamoa-crd-ec" }, 424 {} 425 }; 426 MODULE_DEVICE_TABLE(of, qcom_ec_of_match); 427 428 static const struct i2c_device_id qcom_ec_i2c_id_table[] = { 429 { "qcom-hamoa-ec", }, 430 {} 431 }; 432 MODULE_DEVICE_TABLE(i2c, qcom_ec_i2c_id_table); 433 434 static DEFINE_SIMPLE_DEV_PM_OPS(qcom_ec_pm_ops, 435 qcom_ec_suspend, 436 qcom_ec_resume); 437 438 static struct i2c_driver qcom_ec_i2c_driver = { 439 .driver = { 440 .name = "qcom-hamoa-ec", 441 .of_match_table = qcom_ec_of_match, 442 .pm = &qcom_ec_pm_ops, 443 }, 444 .probe = qcom_ec_probe, 445 .remove = qcom_ec_remove, 446 .id_table = qcom_ec_i2c_id_table, 447 }; 448 module_i2c_driver(qcom_ec_i2c_driver); 449 450 MODULE_DESCRIPTION("QCOM Hamoa Embedded Controller"); 451 MODULE_LICENSE("GPL"); 452