1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * rmi-i2c.c - Side band RMI over I2C support for AMD out 4 * of band management 5 * 6 * Copyright (C) 2024 Advanced Micro Devices, Inc. 7 */ 8 9 #include <linux/delay.h> 10 #include <linux/err.h> 11 #include <linux/i2c.h> 12 #include <linux/i3c/device.h> 13 #include <linux/i3c/master.h> 14 #include <linux/init.h> 15 #include <linux/module.h> 16 #include <linux/mutex.h> 17 #include <linux/of.h> 18 #include <linux/regmap.h> 19 #include "rmi-core.h" 20 21 #define REV_TWO_BYTE_ADDR 0x21 22 23 static int sbrmi_enable_alert(struct sbrmi_data *data) 24 { 25 int ctrl, ret; 26 27 /* 28 * Enable the SB-RMI Software alert status 29 * by writing 0 to bit 4 of Control register(0x1) 30 */ 31 ret = regmap_read(data->regmap, SBRMI_CTRL, &ctrl); 32 if (ret < 0) 33 return ret; 34 35 if (ctrl & 0x10) { 36 ctrl &= ~0x10; 37 return regmap_write(data->regmap, SBRMI_CTRL, ctrl); 38 } 39 40 return 0; 41 } 42 43 static int sbrmi_get_max_pwr_limit(struct sbrmi_data *data) 44 { 45 struct apml_mbox_msg msg = { 0 }; 46 int ret; 47 48 msg.cmd = SBRMI_READ_PKG_MAX_PWR_LIMIT; 49 ret = rmi_mailbox_xfer(data, &msg); 50 if (ret < 0) 51 return ret; 52 data->pwr_limit_max = msg.mb_in_out; 53 54 return ret; 55 } 56 57 static int sbrmi_common_probe(struct device *dev, struct regmap *regmap, uint8_t address) 58 { 59 struct sbrmi_data *data; 60 int ret; 61 62 data = devm_kzalloc(dev, sizeof(struct sbrmi_data), GFP_KERNEL); 63 if (!data) 64 return -ENOMEM; 65 66 data->regmap = regmap; 67 mutex_init(&data->lock); 68 69 /* Enable alert for SB-RMI sequence */ 70 ret = sbrmi_enable_alert(data); 71 if (ret < 0) 72 return ret; 73 74 /* Cache maximum power limit */ 75 ret = sbrmi_get_max_pwr_limit(data); 76 if (ret < 0) 77 return ret; 78 79 data->dev_static_addr = address; 80 81 dev_set_drvdata(dev, data); 82 83 ret = create_hwmon_sensor_device(dev, data); 84 if (ret < 0) 85 return ret; 86 return create_misc_rmi_device(data, dev); 87 } 88 89 static struct regmap_config sbrmi_regmap_config = { 90 .reg_bits = 8, 91 .val_bits = 8, 92 }; 93 94 static struct regmap_config sbrmi_regmap_config_ext = { 95 .reg_bits = 16, 96 .val_bits = 8, 97 .reg_format_endian = REGMAP_ENDIAN_LITTLE, 98 }; 99 100 static int sbrmi_i2c_probe(struct i2c_client *client) 101 { 102 struct device *dev = &client->dev; 103 struct regmap *regmap; 104 int rev, ret; 105 106 regmap = devm_regmap_init_i2c(client, &sbrmi_regmap_config); 107 if (IS_ERR(regmap)) 108 return PTR_ERR(regmap); 109 110 ret = regmap_read(regmap, SBRMI_REV, &rev); 111 if (ret) 112 return ret; 113 114 /* 115 * For Turin and newer platforms, revision is 0x21 or later. This is 116 * to identify the two byte register address size. However, one 117 * byte transaction can be successful. 118 * Verify if revision is 0x21 or later, if yes, switch to 2 byte 119 * address size. 120 * Continuously using 1 byte address for revision 0x21 or later can lead 121 * to bus corruption. 122 */ 123 if (rev >= REV_TWO_BYTE_ADDR) { 124 regmap = devm_regmap_init_i2c(client, &sbrmi_regmap_config_ext); 125 if (IS_ERR(regmap)) 126 return PTR_ERR(regmap); 127 } 128 return sbrmi_common_probe(dev, regmap, client->addr); 129 } 130 131 static void sbrmi_i2c_remove(struct i2c_client *client) 132 { 133 struct sbrmi_data *data = dev_get_drvdata(&client->dev); 134 135 misc_deregister(&data->sbrmi_misc_dev); 136 /* Assign fops and parent of misc dev to NULL */ 137 data->sbrmi_misc_dev.fops = NULL; 138 data->sbrmi_misc_dev.parent = NULL; 139 dev_info(&client->dev, "Removed sbrmi-i2c driver\n"); 140 return; 141 } 142 143 static const struct i2c_device_id sbrmi_id[] = { 144 {"sbrmi-i2c"}, 145 {} 146 }; 147 MODULE_DEVICE_TABLE(i2c, sbrmi_id); 148 149 static const struct of_device_id __maybe_unused sbrmi_of_match[] = { 150 { 151 .compatible = "amd,sbrmi", 152 }, 153 { }, 154 }; 155 MODULE_DEVICE_TABLE(of, sbrmi_of_match); 156 157 static struct i2c_driver sbrmi_driver = { 158 .driver = { 159 .name = "sbrmi-i2c", 160 .of_match_table = of_match_ptr(sbrmi_of_match), 161 }, 162 .probe = sbrmi_i2c_probe, 163 .remove = sbrmi_i2c_remove, 164 .id_table = sbrmi_id, 165 }; 166 167 static int sbrmi_i3c_probe(struct i3c_device *i3cdev) 168 { 169 struct device *dev = i3cdev_to_dev(i3cdev); 170 struct regmap *regmap; 171 int rev, ret; 172 173 /* 174 * AMD OOB devices are distinguished by their Instance ID. 175 * For SBRMI, the Instance ID is 1. Since the device ID match 176 * does not account for the Instance ID, the following check 177 * ensures that only the SBRMI device is probed, excluding 178 * other OOB devices. 179 */ 180 if (I3C_PID_INSTANCE_ID(i3cdev->desc->info.pid) != 1) 181 return -ENXIO; 182 183 regmap = devm_regmap_init_i3c(i3cdev, &sbrmi_regmap_config); 184 if (IS_ERR(regmap)) 185 return PTR_ERR(regmap); 186 187 ret = regmap_read(regmap, SBRMI_REV, &rev); 188 if (ret) 189 return ret; 190 191 /* 192 * For Turin and newer platforms, revision is 0x21 or later. This is 193 * to identify the two byte register address size. However, one 194 * byte transaction can be successful. 195 * Verify if revision is 0x21 or later, if yes, switch to 2 byte 196 * address size. 197 * Continuously using 1 byte address for revision 0x21 or later can lead 198 * to bus corruption. 199 */ 200 if (rev >= REV_TWO_BYTE_ADDR) { 201 regmap = devm_regmap_init_i3c(i3cdev, &sbrmi_regmap_config_ext); 202 if (IS_ERR(regmap)) 203 return PTR_ERR(regmap); 204 } 205 206 /* 207 * AMD APML I3C devices support static address. 208 * If static address is defined, dynamic address is same as static address. 209 * In case static address is not defined, I3C master controller defined 210 * dynamic address is used. 211 */ 212 return sbrmi_common_probe(dev, regmap, i3cdev->desc->info.dyn_addr); 213 } 214 215 static void sbrmi_i3c_remove(struct i3c_device *i3cdev) 216 { 217 struct sbrmi_data *data = dev_get_drvdata(&i3cdev->dev); 218 219 misc_deregister(&data->sbrmi_misc_dev); 220 } 221 222 static const struct i3c_device_id sbrmi_i3c_id[] = { 223 /* PID for AMD SBRMI device */ 224 I3C_DEVICE_EXTRA_INFO(0x112, 0x0, 0x2, NULL), 225 I3C_DEVICE_EXTRA_INFO(0x0, 0x0, 0x118, NULL), /* Socket:0, Venice */ 226 I3C_DEVICE_EXTRA_INFO(0x0, 0x100, 0x118, NULL), /* Socket:1, Venice */ 227 I3C_DEVICE_EXTRA_INFO(0x112, 0x0, 0x119, NULL), /* Socket:0, Venice */ 228 I3C_DEVICE_EXTRA_INFO(0x112, 0x100, 0x119, NULL), /* Socket:1, Venice */ 229 {} 230 }; 231 MODULE_DEVICE_TABLE(i3c, sbrmi_i3c_id); 232 233 static struct i3c_driver sbrmi_i3c_driver = { 234 .driver = { 235 .name = "sbrmi-i3c", 236 }, 237 .probe = sbrmi_i3c_probe, 238 .remove = sbrmi_i3c_remove, 239 .id_table = sbrmi_i3c_id, 240 }; 241 242 module_i3c_i2c_driver(sbrmi_i3c_driver, &sbrmi_driver); 243 244 MODULE_AUTHOR("Akshay Gupta <akshay.gupta@amd.com>"); 245 MODULE_AUTHOR("Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>"); 246 MODULE_DESCRIPTION("Hwmon driver for AMD SB-RMI emulated sensor"); 247 MODULE_LICENSE("GPL"); 248