1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Serial multi-instantiate driver, pseudo driver to instantiate multiple 4 * client devices from a single fwnode. 5 * 6 * Copyright 2018 Hans de Goede <hdegoede@redhat.com> 7 */ 8 9 #include <linux/acpi.h> 10 #include <linux/bits.h> 11 #include <linux/i2c.h> 12 #include <linux/interrupt.h> 13 #include <linux/kernel.h> 14 #include <linux/module.h> 15 #include <linux/platform_device.h> 16 #include <linux/property.h> 17 #include <linux/spi/spi.h> 18 #include <linux/types.h> 19 20 #define IRQ_RESOURCE_TYPE GENMASK(1, 0) 21 #define IRQ_RESOURCE_NONE 0 22 #define IRQ_RESOURCE_GPIO 1 23 #define IRQ_RESOURCE_APIC 2 24 #define IRQ_RESOURCE_AUTO 3 25 #define IRQ_RESOURCE_OPT BIT(2) 26 27 enum smi_bus_type { 28 SMI_I2C, 29 SMI_SPI, 30 SMI_AUTO_DETECT, 31 }; 32 33 struct smi_instance { 34 const char *type; 35 unsigned int flags; 36 int irq_idx; 37 }; 38 39 struct smi_node { 40 enum smi_bus_type bus_type; 41 struct smi_instance instances[]; 42 }; 43 44 struct smi { 45 int i2c_num; 46 int spi_num; 47 struct i2c_client **i2c_devs; 48 struct spi_device **spi_devs; 49 }; 50 51 static int smi_get_irq(struct platform_device *pdev, struct acpi_device *adev, 52 const struct smi_instance *inst) 53 { 54 int ret; 55 56 switch (inst->flags & IRQ_RESOURCE_TYPE) { 57 case IRQ_RESOURCE_AUTO: 58 ret = acpi_dev_gpio_irq_get(adev, inst->irq_idx); 59 if (ret > 0) { 60 dev_dbg(&pdev->dev, "Using gpio irq\n"); 61 break; 62 } 63 ret = platform_get_irq(pdev, inst->irq_idx); 64 if (ret > 0) { 65 dev_dbg(&pdev->dev, "Using platform irq\n"); 66 break; 67 } 68 if (inst->flags & IRQ_RESOURCE_OPT) { 69 dev_dbg(&pdev->dev, "No irq\n"); 70 return 0; 71 } 72 break; 73 case IRQ_RESOURCE_GPIO: 74 ret = acpi_dev_gpio_irq_get(adev, inst->irq_idx); 75 break; 76 case IRQ_RESOURCE_APIC: 77 ret = platform_get_irq(pdev, inst->irq_idx); 78 break; 79 default: 80 return 0; 81 } 82 if (ret < 0) 83 return dev_err_probe(&pdev->dev, ret, "Error requesting irq at index %d\n", 84 inst->irq_idx); 85 86 return ret; 87 } 88 89 static void smi_devs_unregister(struct smi *smi) 90 { 91 #if IS_REACHABLE(CONFIG_I2C) 92 while (smi->i2c_num--) 93 i2c_unregister_device(smi->i2c_devs[smi->i2c_num]); 94 #endif 95 96 if (IS_REACHABLE(CONFIG_SPI)) { 97 while (smi->spi_num--) 98 spi_unregister_device(smi->spi_devs[smi->spi_num]); 99 } 100 } 101 102 /** 103 * smi_spi_probe - Instantiate multiple SPI devices from inst array 104 * @pdev: Platform device 105 * @smi: Internal struct for Serial multi instantiate driver 106 * @inst_array: Array of instances to probe 107 * 108 * Returns the number of SPI devices instantiate, Zero if none is found or a negative error code. 109 */ 110 static int smi_spi_probe(struct platform_device *pdev, struct smi *smi, 111 const struct smi_instance *inst_array) 112 { 113 struct device *dev = &pdev->dev; 114 struct acpi_device *adev = ACPI_COMPANION(dev); 115 struct spi_controller *ctlr; 116 struct spi_device *spi_dev; 117 char name[50]; 118 int i, ret, count; 119 120 ret = acpi_spi_count_resources(adev); 121 if (ret < 0) 122 return ret; 123 if (!ret) 124 return -ENOENT; 125 126 count = ret; 127 128 smi->spi_devs = devm_kcalloc(dev, count, sizeof(*smi->spi_devs), GFP_KERNEL); 129 if (!smi->spi_devs) 130 return -ENOMEM; 131 132 for (i = 0; i < count && inst_array[i].type; i++) { 133 134 spi_dev = acpi_spi_device_alloc(NULL, adev, i); 135 if (IS_ERR(spi_dev)) { 136 ret = dev_err_probe(dev, PTR_ERR(spi_dev), "failed to allocate SPI device %s from ACPI\n", 137 dev_name(&adev->dev)); 138 goto error; 139 } 140 141 ctlr = spi_dev->controller; 142 143 strscpy(spi_dev->modalias, inst_array[i].type); 144 145 ret = smi_get_irq(pdev, adev, &inst_array[i]); 146 if (ret < 0) { 147 spi_dev_put(spi_dev); 148 goto error; 149 } 150 spi_dev->irq = ret; 151 152 snprintf(name, sizeof(name), "%s-%s-%s.%d", dev_name(&ctlr->dev), dev_name(dev), 153 inst_array[i].type, i); 154 spi_dev->dev.init_name = name; 155 156 ret = spi_add_device(spi_dev); 157 if (ret) { 158 dev_err_probe(&ctlr->dev, ret, "failed to add SPI device %s from ACPI\n", 159 dev_name(&adev->dev)); 160 spi_dev_put(spi_dev); 161 goto error; 162 } 163 164 dev_dbg(dev, "SPI device %s using chip select %u", name, 165 spi_get_chipselect(spi_dev, 0)); 166 167 smi->spi_devs[i] = spi_dev; 168 smi->spi_num++; 169 } 170 171 if (smi->spi_num < count) { 172 dev_dbg(dev, "Error finding driver, idx %d\n", i); 173 ret = -ENODEV; 174 goto error; 175 } 176 177 dev_info(dev, "Instantiated %d SPI devices.\n", smi->spi_num); 178 179 return 0; 180 error: 181 smi_devs_unregister(smi); 182 183 return ret; 184 } 185 186 /** 187 * smi_i2c_probe - Instantiate multiple I2C devices from inst array 188 * @pdev: Platform device 189 * @smi: Internal struct for Serial multi instantiate driver 190 * @inst_array: Array of instances to probe 191 * 192 * Returns the number of I2C devices instantiate, Zero if none is found or a negative error code. 193 */ 194 static int smi_i2c_probe(struct platform_device *pdev, struct smi *smi, 195 const struct smi_instance *inst_array) 196 { 197 struct i2c_board_info board_info = {}; 198 struct device *dev = &pdev->dev; 199 struct acpi_device *adev = ACPI_COMPANION(dev); 200 char name[32]; 201 int i, ret, count; 202 203 ret = i2c_acpi_client_count(adev); 204 if (ret < 0) 205 return ret; 206 if (!ret) 207 return -ENOENT; 208 209 count = ret; 210 211 smi->i2c_devs = devm_kcalloc(dev, count, sizeof(*smi->i2c_devs), GFP_KERNEL); 212 if (!smi->i2c_devs) 213 return -ENOMEM; 214 215 for (i = 0; i < count && inst_array[i].type; i++) { 216 memset(&board_info, 0, sizeof(board_info)); 217 strscpy(board_info.type, inst_array[i].type); 218 snprintf(name, sizeof(name), "%s-%s.%d", dev_name(dev), inst_array[i].type, i); 219 board_info.dev_name = name; 220 221 ret = smi_get_irq(pdev, adev, &inst_array[i]); 222 if (ret < 0) 223 goto error; 224 board_info.irq = ret; 225 226 smi->i2c_devs[i] = i2c_acpi_new_device(dev, i, &board_info); 227 if (IS_ERR(smi->i2c_devs[i])) { 228 ret = dev_err_probe(dev, PTR_ERR(smi->i2c_devs[i]), 229 "Error creating i2c-client, idx %d\n", i); 230 goto error; 231 } 232 smi->i2c_num++; 233 } 234 if (smi->i2c_num < count) { 235 dev_dbg(dev, "Error finding driver, idx %d\n", i); 236 ret = -ENODEV; 237 goto error; 238 } 239 240 dev_info(dev, "Instantiated %d I2C devices.\n", smi->i2c_num); 241 242 return 0; 243 error: 244 smi_devs_unregister(smi); 245 246 return ret; 247 } 248 249 static int smi_probe(struct platform_device *pdev) 250 { 251 struct device *dev = &pdev->dev; 252 const struct smi_node *node; 253 struct smi *smi; 254 int ret; 255 256 node = device_get_match_data(dev); 257 if (!node) { 258 dev_dbg(dev, "Error ACPI match data is missing\n"); 259 return -ENODEV; 260 } 261 262 smi = devm_kzalloc(dev, sizeof(*smi), GFP_KERNEL); 263 if (!smi) 264 return -ENOMEM; 265 266 platform_set_drvdata(pdev, smi); 267 268 switch (node->bus_type) { 269 case SMI_I2C: 270 if (IS_REACHABLE(CONFIG_I2C)) 271 return smi_i2c_probe(pdev, smi, node->instances); 272 273 return -ENODEV; 274 case SMI_SPI: 275 if (IS_REACHABLE(CONFIG_SPI)) 276 return smi_spi_probe(pdev, smi, node->instances); 277 278 return -ENODEV; 279 case SMI_AUTO_DETECT: 280 /* 281 * For backwards-compatibility with the existing nodes I2C 282 * is checked first and if such entries are found ONLY I2C 283 * devices are created. Since some existing nodes that were 284 * already handled by this driver could also contain unrelated 285 * SpiSerialBus nodes that were previously ignored, and this 286 * preserves that behavior. 287 */ 288 if (IS_REACHABLE(CONFIG_I2C)) { 289 ret = smi_i2c_probe(pdev, smi, node->instances); 290 if (ret != -ENOENT) 291 return ret; 292 } 293 294 if (IS_REACHABLE(CONFIG_SPI)) 295 return smi_spi_probe(pdev, smi, node->instances); 296 297 return -ENODEV; 298 default: 299 return -EINVAL; 300 } 301 } 302 303 static void smi_remove(struct platform_device *pdev) 304 { 305 struct smi *smi = platform_get_drvdata(pdev); 306 307 smi_devs_unregister(smi); 308 } 309 310 static const struct smi_node bsg1160_data = { 311 .instances = { 312 { "bmc150_accel", IRQ_RESOURCE_GPIO, 0 }, 313 { "bmc150_magn" }, 314 { "bmg160" }, 315 {} 316 }, 317 .bus_type = SMI_I2C, 318 }; 319 320 static const struct smi_node bsg2150_data = { 321 .instances = { 322 { "bmc150_accel", IRQ_RESOURCE_GPIO, 0 }, 323 { "bmc150_magn" }, 324 /* The resources describe a 3th client, but it is not really there. */ 325 { "bsg2150_dummy_dev" }, 326 {} 327 }, 328 .bus_type = SMI_I2C, 329 }; 330 331 static const struct smi_node int3515_data = { 332 .instances = { 333 { "tps6598x", IRQ_RESOURCE_APIC, 0 }, 334 { "tps6598x", IRQ_RESOURCE_APIC, 1 }, 335 { "tps6598x", IRQ_RESOURCE_APIC, 2 }, 336 { "tps6598x", IRQ_RESOURCE_APIC, 3 }, 337 {} 338 }, 339 .bus_type = SMI_I2C, 340 }; 341 342 static const struct smi_node cs35l41_hda = { 343 .instances = { 344 { "cs35l41-hda", IRQ_RESOURCE_AUTO, 0 }, 345 { "cs35l41-hda", IRQ_RESOURCE_AUTO, 0 }, 346 { "cs35l41-hda", IRQ_RESOURCE_AUTO, 0 }, 347 { "cs35l41-hda", IRQ_RESOURCE_AUTO, 0 }, 348 {} 349 }, 350 .bus_type = SMI_AUTO_DETECT, 351 }; 352 353 static const struct smi_node cs35l54_hda = { 354 .instances = { 355 { "cs35l54-hda", IRQ_RESOURCE_AUTO, 0 }, 356 { "cs35l54-hda", IRQ_RESOURCE_AUTO, 0 }, 357 { "cs35l54-hda", IRQ_RESOURCE_AUTO, 0 }, 358 { "cs35l54-hda", IRQ_RESOURCE_AUTO, 0 }, 359 /* a 5th entry is an alias address, not a real device */ 360 { "cs35l54-hda_dummy_dev" }, 361 {} 362 }, 363 .bus_type = SMI_AUTO_DETECT, 364 }; 365 366 static const struct smi_node cs35l56_hda = { 367 .instances = { 368 { "cs35l56-hda", IRQ_RESOURCE_AUTO, 0 }, 369 { "cs35l56-hda", IRQ_RESOURCE_AUTO, 0 }, 370 { "cs35l56-hda", IRQ_RESOURCE_AUTO, 0 }, 371 { "cs35l56-hda", IRQ_RESOURCE_AUTO, 0 }, 372 /* a 5th entry is an alias address, not a real device */ 373 { "cs35l56-hda_dummy_dev" }, 374 {} 375 }, 376 .bus_type = SMI_AUTO_DETECT, 377 }; 378 379 static const struct smi_node cs35l57_hda = { 380 .instances = { 381 { "cs35l57-hda", IRQ_RESOURCE_AUTO, 0 }, 382 { "cs35l57-hda", IRQ_RESOURCE_AUTO, 0 }, 383 { "cs35l57-hda", IRQ_RESOURCE_AUTO, 0 }, 384 { "cs35l57-hda", IRQ_RESOURCE_AUTO, 0 }, 385 /* a 5th entry is an alias address, not a real device */ 386 { "cs35l57-hda_dummy_dev" }, 387 {} 388 }, 389 .bus_type = SMI_AUTO_DETECT, 390 }; 391 392 static const struct smi_node tas2781_hda = { 393 .instances = { 394 { "tas2781-hda", IRQ_RESOURCE_AUTO | IRQ_RESOURCE_OPT, 0 }, 395 { "tas2781-hda", IRQ_RESOURCE_AUTO | IRQ_RESOURCE_OPT, 0 }, 396 { "tas2781-hda", IRQ_RESOURCE_AUTO | IRQ_RESOURCE_OPT, 0 }, 397 { "tas2781-hda", IRQ_RESOURCE_AUTO | IRQ_RESOURCE_OPT, 0 }, 398 {} 399 }, 400 .bus_type = SMI_AUTO_DETECT, 401 }; 402 403 /* 404 * Note new device-ids must also be added to ignore_serial_bus_ids in 405 * drivers/acpi/scan.c: acpi_device_enumeration_by_parent(). 406 */ 407 static const struct acpi_device_id smi_acpi_ids[] = { 408 { "BSG1160", (unsigned long)&bsg1160_data }, 409 { "BSG2150", (unsigned long)&bsg2150_data }, 410 { "CSC3551", (unsigned long)&cs35l41_hda }, 411 { "CSC3554", (unsigned long)&cs35l54_hda }, 412 { "CSC3556", (unsigned long)&cs35l56_hda }, 413 { "CSC3557", (unsigned long)&cs35l57_hda }, 414 { "INT3515", (unsigned long)&int3515_data }, 415 { "TXNW2781", (unsigned long)&tas2781_hda }, 416 /* Non-conforming _HID for Cirrus Logic already released */ 417 { "CLSA0100", (unsigned long)&cs35l41_hda }, 418 { "CLSA0101", (unsigned long)&cs35l41_hda }, 419 { } 420 }; 421 MODULE_DEVICE_TABLE(acpi, smi_acpi_ids); 422 423 static struct platform_driver smi_driver = { 424 .driver = { 425 .name = "Serial bus multi instantiate pseudo device driver", 426 .acpi_match_table = smi_acpi_ids, 427 }, 428 .probe = smi_probe, 429 .remove = smi_remove, 430 }; 431 module_platform_driver(smi_driver); 432 433 MODULE_DESCRIPTION("Serial multi instantiate pseudo device driver"); 434 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); 435 MODULE_LICENSE("GPL"); 436