1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * SMBus driver for ACPI SMBus CMI 4 * 5 * Copyright (C) 2009 Crane Cai <crane.cai@amd.com> 6 */ 7 8 #include <linux/module.h> 9 #include <linux/platform_device.h> 10 #include <linux/slab.h> 11 #include <linux/kernel.h> 12 #include <linux/stddef.h> 13 #include <linux/i2c.h> 14 #include <linux/acpi.h> 15 16 /* SMBUS HID definition as supported by Microsoft Windows */ 17 #define ACPI_SMBUS_MS_HID "SMB0001" 18 19 struct smbus_methods_t { 20 char *mt_info; 21 char *mt_sbr; 22 char *mt_sbw; 23 }; 24 25 struct acpi_smbus_cmi { 26 acpi_handle handle; 27 struct i2c_adapter adapter; 28 u8 cap_info:1; 29 u8 cap_read:1; 30 u8 cap_write:1; 31 const struct smbus_methods_t *methods; 32 }; 33 34 static const struct smbus_methods_t smbus_methods = { 35 .mt_info = "_SBI", 36 .mt_sbr = "_SBR", 37 .mt_sbw = "_SBW", 38 }; 39 40 /* Some IBM BIOSes omit the leading underscore */ 41 static const struct smbus_methods_t ibm_smbus_methods = { 42 .mt_info = "SBI_", 43 .mt_sbr = "SBR_", 44 .mt_sbw = "SBW_", 45 }; 46 47 static const struct acpi_device_id acpi_smbus_cmi_ids[] = { 48 {"SMBUS01", (kernel_ulong_t)&smbus_methods}, 49 {ACPI_SMBUS_IBM_HID, (kernel_ulong_t)&ibm_smbus_methods}, 50 {ACPI_SMBUS_MS_HID, (kernel_ulong_t)&smbus_methods}, 51 {"", 0} 52 }; 53 MODULE_DEVICE_TABLE(acpi, acpi_smbus_cmi_ids); 54 55 #define ACPI_SMBUS_STATUS_OK 0x00 56 #define ACPI_SMBUS_STATUS_FAIL 0x07 57 #define ACPI_SMBUS_STATUS_DNAK 0x10 58 #define ACPI_SMBUS_STATUS_DERR 0x11 59 #define ACPI_SMBUS_STATUS_CMD_DENY 0x12 60 #define ACPI_SMBUS_STATUS_UNKNOWN 0x13 61 #define ACPI_SMBUS_STATUS_ACC_DENY 0x17 62 #define ACPI_SMBUS_STATUS_TIMEOUT 0x18 63 #define ACPI_SMBUS_STATUS_NOTSUP 0x19 64 #define ACPI_SMBUS_STATUS_BUSY 0x1a 65 #define ACPI_SMBUS_STATUS_PEC 0x1f 66 67 #define ACPI_SMBUS_PRTCL_WRITE 0x00 68 #define ACPI_SMBUS_PRTCL_READ 0x01 69 #define ACPI_SMBUS_PRTCL_QUICK 0x02 70 #define ACPI_SMBUS_PRTCL_BYTE 0x04 71 #define ACPI_SMBUS_PRTCL_BYTE_DATA 0x06 72 #define ACPI_SMBUS_PRTCL_WORD_DATA 0x08 73 #define ACPI_SMBUS_PRTCL_BLOCK_DATA 0x0a 74 75 76 static int 77 acpi_smbus_cmi_access(struct i2c_adapter *adap, u16 addr, unsigned short flags, 78 char read_write, u8 command, int size, 79 union i2c_smbus_data *data) 80 { 81 int result = 0; 82 struct acpi_smbus_cmi *smbus_cmi = adap->algo_data; 83 unsigned char protocol; 84 acpi_status status = 0; 85 struct acpi_object_list input; 86 union acpi_object mt_params[5]; 87 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 88 union acpi_object *obj; 89 union acpi_object *pkg; 90 char *method; 91 int len = 0; 92 93 dev_dbg(&adap->dev, "access size: %d %s\n", size, 94 (read_write) ? "READ" : "WRITE"); 95 switch (size) { 96 case I2C_SMBUS_QUICK: 97 protocol = ACPI_SMBUS_PRTCL_QUICK; 98 command = 0; 99 if (read_write == I2C_SMBUS_WRITE) { 100 mt_params[3].type = ACPI_TYPE_INTEGER; 101 mt_params[3].integer.value = 0; 102 mt_params[4].type = ACPI_TYPE_INTEGER; 103 mt_params[4].integer.value = 0; 104 } 105 break; 106 107 case I2C_SMBUS_BYTE: 108 protocol = ACPI_SMBUS_PRTCL_BYTE; 109 if (read_write == I2C_SMBUS_WRITE) { 110 mt_params[3].type = ACPI_TYPE_INTEGER; 111 mt_params[3].integer.value = 0; 112 mt_params[4].type = ACPI_TYPE_INTEGER; 113 mt_params[4].integer.value = 0; 114 } else { 115 command = 0; 116 } 117 break; 118 119 case I2C_SMBUS_BYTE_DATA: 120 protocol = ACPI_SMBUS_PRTCL_BYTE_DATA; 121 if (read_write == I2C_SMBUS_WRITE) { 122 mt_params[3].type = ACPI_TYPE_INTEGER; 123 mt_params[3].integer.value = 1; 124 mt_params[4].type = ACPI_TYPE_INTEGER; 125 mt_params[4].integer.value = data->byte; 126 } 127 break; 128 129 case I2C_SMBUS_WORD_DATA: 130 protocol = ACPI_SMBUS_PRTCL_WORD_DATA; 131 if (read_write == I2C_SMBUS_WRITE) { 132 mt_params[3].type = ACPI_TYPE_INTEGER; 133 mt_params[3].integer.value = 2; 134 mt_params[4].type = ACPI_TYPE_INTEGER; 135 mt_params[4].integer.value = data->word; 136 } 137 break; 138 139 case I2C_SMBUS_BLOCK_DATA: 140 protocol = ACPI_SMBUS_PRTCL_BLOCK_DATA; 141 if (read_write == I2C_SMBUS_WRITE) { 142 len = data->block[0]; 143 if (len == 0 || len > I2C_SMBUS_BLOCK_MAX) 144 return -EINVAL; 145 mt_params[3].type = ACPI_TYPE_INTEGER; 146 mt_params[3].integer.value = len; 147 mt_params[4].type = ACPI_TYPE_BUFFER; 148 mt_params[4].buffer.length = len; 149 mt_params[4].buffer.pointer = data->block + 1; 150 } 151 break; 152 153 default: 154 dev_warn(&adap->dev, "Unsupported transaction %d\n", size); 155 return -EOPNOTSUPP; 156 } 157 158 if (read_write == I2C_SMBUS_READ) { 159 protocol |= ACPI_SMBUS_PRTCL_READ; 160 method = smbus_cmi->methods->mt_sbr; 161 input.count = 3; 162 } else { 163 protocol |= ACPI_SMBUS_PRTCL_WRITE; 164 method = smbus_cmi->methods->mt_sbw; 165 input.count = 5; 166 } 167 168 input.pointer = mt_params; 169 mt_params[0].type = ACPI_TYPE_INTEGER; 170 mt_params[0].integer.value = protocol; 171 mt_params[1].type = ACPI_TYPE_INTEGER; 172 mt_params[1].integer.value = addr; 173 mt_params[2].type = ACPI_TYPE_INTEGER; 174 mt_params[2].integer.value = command; 175 176 status = acpi_evaluate_object(smbus_cmi->handle, method, &input, 177 &buffer); 178 if (ACPI_FAILURE(status)) { 179 acpi_handle_err(smbus_cmi->handle, 180 "Failed to evaluate %s: %i\n", method, status); 181 return -EIO; 182 } 183 184 pkg = buffer.pointer; 185 if (pkg && pkg->type == ACPI_TYPE_PACKAGE) 186 obj = pkg->package.elements; 187 else { 188 acpi_handle_err(smbus_cmi->handle, "Invalid argument type\n"); 189 result = -EIO; 190 goto out; 191 } 192 if (obj == NULL || obj->type != ACPI_TYPE_INTEGER) { 193 acpi_handle_err(smbus_cmi->handle, "Invalid argument type\n"); 194 result = -EIO; 195 goto out; 196 } 197 198 result = obj->integer.value; 199 acpi_handle_debug(smbus_cmi->handle, "%s return status: %i\n", method, 200 result); 201 202 switch (result) { 203 case ACPI_SMBUS_STATUS_OK: 204 result = 0; 205 break; 206 case ACPI_SMBUS_STATUS_BUSY: 207 result = -EBUSY; 208 goto out; 209 case ACPI_SMBUS_STATUS_TIMEOUT: 210 result = -ETIMEDOUT; 211 goto out; 212 case ACPI_SMBUS_STATUS_DNAK: 213 result = -ENXIO; 214 goto out; 215 default: 216 result = -EIO; 217 goto out; 218 } 219 220 if (read_write == I2C_SMBUS_WRITE || size == I2C_SMBUS_QUICK) 221 goto out; 222 223 obj = pkg->package.elements + 1; 224 if (obj->type != ACPI_TYPE_INTEGER) { 225 acpi_handle_err(smbus_cmi->handle, "Invalid argument type\n"); 226 result = -EIO; 227 goto out; 228 } 229 230 len = obj->integer.value; 231 obj = pkg->package.elements + 2; 232 switch (size) { 233 case I2C_SMBUS_BYTE: 234 case I2C_SMBUS_BYTE_DATA: 235 case I2C_SMBUS_WORD_DATA: 236 if (obj->type != ACPI_TYPE_INTEGER) { 237 acpi_handle_err(smbus_cmi->handle, 238 "Invalid argument type\n"); 239 result = -EIO; 240 goto out; 241 } 242 if (len == 2) 243 data->word = obj->integer.value; 244 else 245 data->byte = obj->integer.value; 246 break; 247 case I2C_SMBUS_BLOCK_DATA: 248 if (obj->type != ACPI_TYPE_BUFFER) { 249 acpi_handle_err(smbus_cmi->handle, 250 "Invalid argument type\n"); 251 result = -EIO; 252 goto out; 253 } 254 if (len == 0 || len > I2C_SMBUS_BLOCK_MAX) 255 return -EPROTO; 256 data->block[0] = len; 257 memcpy(data->block + 1, obj->buffer.pointer, len); 258 break; 259 } 260 261 out: 262 kfree(buffer.pointer); 263 dev_dbg(&adap->dev, "Transaction status: %i\n", result); 264 return result; 265 } 266 267 static u32 acpi_smbus_cmi_func(struct i2c_adapter *adapter) 268 { 269 struct acpi_smbus_cmi *smbus_cmi = adapter->algo_data; 270 u32 ret; 271 272 ret = smbus_cmi->cap_read | smbus_cmi->cap_write ? 273 I2C_FUNC_SMBUS_QUICK : 0; 274 275 ret |= smbus_cmi->cap_read ? 276 (I2C_FUNC_SMBUS_READ_BYTE | 277 I2C_FUNC_SMBUS_READ_BYTE_DATA | 278 I2C_FUNC_SMBUS_READ_WORD_DATA | 279 I2C_FUNC_SMBUS_READ_BLOCK_DATA) : 0; 280 281 ret |= smbus_cmi->cap_write ? 282 (I2C_FUNC_SMBUS_WRITE_BYTE | 283 I2C_FUNC_SMBUS_WRITE_BYTE_DATA | 284 I2C_FUNC_SMBUS_WRITE_WORD_DATA | 285 I2C_FUNC_SMBUS_WRITE_BLOCK_DATA) : 0; 286 287 return ret; 288 } 289 290 static const struct i2c_algorithm acpi_smbus_cmi_algorithm = { 291 .smbus_xfer = acpi_smbus_cmi_access, 292 .functionality = acpi_smbus_cmi_func, 293 }; 294 295 296 static int acpi_smbus_cmi_add_cap(struct acpi_smbus_cmi *smbus_cmi, 297 const char *name) 298 { 299 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 300 struct acpi_handle *handle = smbus_cmi->handle; 301 union acpi_object *obj; 302 acpi_status status; 303 304 if (!strcmp(name, smbus_cmi->methods->mt_info)) { 305 status = acpi_evaluate_object(smbus_cmi->handle, 306 smbus_cmi->methods->mt_info, 307 NULL, &buffer); 308 if (ACPI_FAILURE(status)) { 309 acpi_handle_err(handle, "Failed to evaluate %s: %i\n", 310 smbus_cmi->methods->mt_info, status); 311 return -EIO; 312 } 313 314 obj = buffer.pointer; 315 if (obj && obj->type == ACPI_TYPE_PACKAGE) 316 obj = obj->package.elements; 317 else { 318 acpi_handle_err(handle, "Invalid argument type\n"); 319 kfree(buffer.pointer); 320 return -EIO; 321 } 322 323 if (obj->type != ACPI_TYPE_INTEGER) { 324 acpi_handle_err(handle, "Invalid argument type\n"); 325 kfree(buffer.pointer); 326 return -EIO; 327 } else 328 acpi_handle_debug(handle, "SMBus CMI Version %x\n", 329 (int)obj->integer.value); 330 331 kfree(buffer.pointer); 332 smbus_cmi->cap_info = 1; 333 } else if (!strcmp(name, smbus_cmi->methods->mt_sbr)) 334 smbus_cmi->cap_read = 1; 335 else if (!strcmp(name, smbus_cmi->methods->mt_sbw)) 336 smbus_cmi->cap_write = 1; 337 else 338 acpi_handle_debug(handle, "Unsupported CMI method: %s\n", name); 339 340 return 0; 341 } 342 343 static acpi_status acpi_smbus_cmi_query_methods(acpi_handle handle, u32 level, 344 void *context, void **return_value) 345 { 346 char node_name[5]; 347 struct acpi_buffer buffer = { sizeof(node_name), node_name }; 348 struct acpi_smbus_cmi *smbus_cmi = context; 349 acpi_status status; 350 351 status = acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer); 352 353 if (ACPI_SUCCESS(status)) 354 acpi_smbus_cmi_add_cap(smbus_cmi, node_name); 355 356 return AE_OK; 357 } 358 359 static int smbus_cmi_probe(struct platform_device *device) 360 { 361 struct device *dev = &device->dev; 362 struct acpi_smbus_cmi *smbus_cmi; 363 int ret; 364 365 smbus_cmi = kzalloc(sizeof(struct acpi_smbus_cmi), GFP_KERNEL); 366 if (!smbus_cmi) 367 return -ENOMEM; 368 369 smbus_cmi->handle = ACPI_HANDLE(dev); 370 smbus_cmi->methods = device_get_match_data(dev); 371 372 platform_set_drvdata(device, smbus_cmi); 373 374 smbus_cmi->cap_info = 0; 375 smbus_cmi->cap_read = 0; 376 smbus_cmi->cap_write = 0; 377 378 acpi_walk_namespace(ACPI_TYPE_METHOD, smbus_cmi->handle, 1, 379 acpi_smbus_cmi_query_methods, NULL, smbus_cmi, NULL); 380 381 if (smbus_cmi->cap_info == 0) { 382 ret = -ENODEV; 383 goto err; 384 } 385 386 snprintf(smbus_cmi->adapter.name, sizeof(smbus_cmi->adapter.name), 387 "SMBus CMI adapter %s", dev_name(dev)); 388 smbus_cmi->adapter.owner = THIS_MODULE; 389 smbus_cmi->adapter.algo = &acpi_smbus_cmi_algorithm; 390 smbus_cmi->adapter.algo_data = smbus_cmi; 391 smbus_cmi->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD; 392 smbus_cmi->adapter.dev.parent = &device->dev; 393 394 ret = i2c_add_adapter(&smbus_cmi->adapter); 395 if (ret) { 396 dev_err(&device->dev, "Couldn't register adapter!\n"); 397 goto err; 398 } 399 400 return 0; 401 402 err: 403 kfree(smbus_cmi); 404 return ret; 405 } 406 407 static void smbus_cmi_remove(struct platform_device *device) 408 { 409 struct acpi_smbus_cmi *smbus_cmi = platform_get_drvdata(device); 410 411 i2c_del_adapter(&smbus_cmi->adapter); 412 kfree(smbus_cmi); 413 } 414 415 static struct platform_driver smbus_cmi_driver = { 416 .probe = smbus_cmi_probe, 417 .remove_new = smbus_cmi_remove, 418 .driver = { 419 .name = "smbus_cmi", 420 .acpi_match_table = acpi_smbus_cmi_ids, 421 }, 422 }; 423 module_platform_driver(smbus_cmi_driver); 424 425 MODULE_LICENSE("GPL"); 426 MODULE_AUTHOR("Crane Cai <crane.cai@amd.com>"); 427 MODULE_DESCRIPTION("ACPI SMBus CMI driver"); 428