.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright 2007-2008 Extreme Engineering Solutions, Inc. |
---|
3 | 4 | * |
---|
4 | 5 | * Author: Nate Case <ncase@xes-inc.com> |
---|
5 | | - * |
---|
6 | | - * This file is subject to the terms and conditions of version 2 of |
---|
7 | | - * the GNU General Public License. See the file COPYING in the main |
---|
8 | | - * directory of this archive for more details. |
---|
9 | 6 | * |
---|
10 | 7 | * LED driver for various PCA955x I2C LED drivers |
---|
11 | 8 | * |
---|
.. | .. |
---|
40 | 37 | * bits the chip supports. |
---|
41 | 38 | */ |
---|
42 | 39 | |
---|
43 | | -#include <linux/acpi.h> |
---|
44 | 40 | #include <linux/ctype.h> |
---|
45 | 41 | #include <linux/delay.h> |
---|
46 | 42 | #include <linux/err.h> |
---|
47 | | -#include <linux/gpio.h> |
---|
| 43 | +#include <linux/gpio/driver.h> |
---|
48 | 44 | #include <linux/i2c.h> |
---|
49 | 45 | #include <linux/leds.h> |
---|
50 | 46 | #include <linux/module.h> |
---|
51 | | -#include <linux/of_device.h> |
---|
52 | 47 | #include <linux/of.h> |
---|
| 48 | +#include <linux/property.h> |
---|
53 | 49 | #include <linux/slab.h> |
---|
54 | 50 | #include <linux/string.h> |
---|
55 | 51 | |
---|
.. | .. |
---|
69 | 65 | pca9550, |
---|
70 | 66 | pca9551, |
---|
71 | 67 | pca9552, |
---|
| 68 | + ibm_pca9552, |
---|
72 | 69 | pca9553, |
---|
73 | 70 | }; |
---|
74 | 71 | |
---|
.. | .. |
---|
94 | 91 | .slv_addr = /* 1100xxx */ 0x60, |
---|
95 | 92 | .slv_addr_shift = 3, |
---|
96 | 93 | }, |
---|
| 94 | + [ibm_pca9552] = { |
---|
| 95 | + .bits = 16, |
---|
| 96 | + .slv_addr = /* 0110xxx */ 0x30, |
---|
| 97 | + .slv_addr_shift = 3, |
---|
| 98 | + }, |
---|
97 | 99 | [pca9553] = { |
---|
98 | 100 | .bits = 4, |
---|
99 | 101 | .slv_addr = /* 110001x */ 0x62, |
---|
.. | .. |
---|
105 | 107 | { "pca9550", pca9550 }, |
---|
106 | 108 | { "pca9551", pca9551 }, |
---|
107 | 109 | { "pca9552", pca9552 }, |
---|
| 110 | + { "ibm-pca9552", ibm_pca9552 }, |
---|
108 | 111 | { "pca9553", pca9553 }, |
---|
109 | 112 | { } |
---|
110 | 113 | }; |
---|
111 | 114 | MODULE_DEVICE_TABLE(i2c, pca955x_id); |
---|
112 | | - |
---|
113 | | -static const struct acpi_device_id pca955x_acpi_ids[] = { |
---|
114 | | - { "PCA9550", pca9550 }, |
---|
115 | | - { "PCA9551", pca9551 }, |
---|
116 | | - { "PCA9552", pca9552 }, |
---|
117 | | - { "PCA9553", pca9553 }, |
---|
118 | | - { } |
---|
119 | | -}; |
---|
120 | | -MODULE_DEVICE_TABLE(acpi, pca955x_acpi_ids); |
---|
121 | 115 | |
---|
122 | 116 | struct pca955x { |
---|
123 | 117 | struct mutex lock; |
---|
.. | .. |
---|
373 | 367 | } |
---|
374 | 368 | #endif /* CONFIG_LEDS_PCA955X_GPIO */ |
---|
375 | 369 | |
---|
376 | | -#if IS_ENABLED(CONFIG_OF) |
---|
377 | 370 | static struct pca955x_platform_data * |
---|
378 | | -pca955x_pdata_of_init(struct i2c_client *client, struct pca955x_chipdef *chip) |
---|
| 371 | +pca955x_get_pdata(struct i2c_client *client, struct pca955x_chipdef *chip) |
---|
379 | 372 | { |
---|
380 | | - struct device_node *np = client->dev.of_node; |
---|
381 | | - struct device_node *child; |
---|
382 | 373 | struct pca955x_platform_data *pdata; |
---|
| 374 | + struct fwnode_handle *child; |
---|
383 | 375 | int count; |
---|
384 | 376 | |
---|
385 | | - count = of_get_child_count(np); |
---|
| 377 | + count = device_get_child_node_count(&client->dev); |
---|
386 | 378 | if (!count || count > chip->bits) |
---|
387 | 379 | return ERR_PTR(-ENODEV); |
---|
388 | 380 | |
---|
.. | .. |
---|
396 | 388 | if (!pdata->leds) |
---|
397 | 389 | return ERR_PTR(-ENOMEM); |
---|
398 | 390 | |
---|
399 | | - for_each_child_of_node(np, child) { |
---|
| 391 | + device_for_each_child_node(&client->dev, child) { |
---|
400 | 392 | const char *name; |
---|
401 | 393 | u32 reg; |
---|
402 | 394 | int res; |
---|
403 | 395 | |
---|
404 | | - res = of_property_read_u32(child, "reg", ®); |
---|
| 396 | + res = fwnode_property_read_u32(child, "reg", ®); |
---|
405 | 397 | if ((res != 0) || (reg >= chip->bits)) |
---|
406 | 398 | continue; |
---|
407 | 399 | |
---|
408 | | - if (of_property_read_string(child, "label", &name)) |
---|
409 | | - name = child->name; |
---|
| 400 | + res = fwnode_property_read_string(child, "label", &name); |
---|
| 401 | + if ((res != 0) && is_of_node(child)) |
---|
| 402 | + name = to_of_node(child)->name; |
---|
410 | 403 | |
---|
411 | 404 | snprintf(pdata->leds[reg].name, sizeof(pdata->leds[reg].name), |
---|
412 | 405 | "%s", name); |
---|
413 | 406 | |
---|
414 | 407 | pdata->leds[reg].type = PCA955X_TYPE_LED; |
---|
415 | | - of_property_read_u32(child, "type", &pdata->leds[reg].type); |
---|
416 | | - of_property_read_string(child, "linux,default-trigger", |
---|
| 408 | + fwnode_property_read_u32(child, "type", &pdata->leds[reg].type); |
---|
| 409 | + fwnode_property_read_string(child, "linux,default-trigger", |
---|
417 | 410 | &pdata->leds[reg].default_trigger); |
---|
418 | 411 | } |
---|
419 | 412 | |
---|
.. | .. |
---|
426 | 419 | { .compatible = "nxp,pca9550", .data = (void *)pca9550 }, |
---|
427 | 420 | { .compatible = "nxp,pca9551", .data = (void *)pca9551 }, |
---|
428 | 421 | { .compatible = "nxp,pca9552", .data = (void *)pca9552 }, |
---|
| 422 | + { .compatible = "ibm,pca9552", .data = (void *)ibm_pca9552 }, |
---|
429 | 423 | { .compatible = "nxp,pca9553", .data = (void *)pca9553 }, |
---|
430 | 424 | {}, |
---|
431 | 425 | }; |
---|
432 | | - |
---|
433 | 426 | MODULE_DEVICE_TABLE(of, of_pca955x_match); |
---|
434 | | -#else |
---|
435 | | -static struct pca955x_platform_data * |
---|
436 | | -pca955x_pdata_of_init(struct i2c_client *client, struct pca955x_chipdef *chip) |
---|
437 | | -{ |
---|
438 | | - return ERR_PTR(-ENODEV); |
---|
439 | | -} |
---|
440 | | -#endif |
---|
441 | 427 | |
---|
442 | 428 | static int pca955x_probe(struct i2c_client *client, |
---|
443 | 429 | const struct i2c_device_id *id) |
---|
.. | .. |
---|
450 | 436 | struct pca955x_platform_data *pdata; |
---|
451 | 437 | int ngpios = 0; |
---|
452 | 438 | |
---|
453 | | - if (id) { |
---|
454 | | - chip = &pca955x_chipdefs[id->driver_data]; |
---|
455 | | - } else { |
---|
456 | | - const struct acpi_device_id *acpi_id; |
---|
457 | | - |
---|
458 | | - acpi_id = acpi_match_device(pca955x_acpi_ids, &client->dev); |
---|
459 | | - if (!acpi_id) |
---|
460 | | - return -ENODEV; |
---|
461 | | - chip = &pca955x_chipdefs[acpi_id->driver_data]; |
---|
462 | | - } |
---|
463 | | - adapter = to_i2c_adapter(client->dev.parent); |
---|
| 439 | + chip = &pca955x_chipdefs[id->driver_data]; |
---|
| 440 | + adapter = client->adapter; |
---|
464 | 441 | pdata = dev_get_platdata(&client->dev); |
---|
465 | 442 | if (!pdata) { |
---|
466 | | - pdata = pca955x_pdata_of_init(client, chip); |
---|
| 443 | + pdata = pca955x_get_pdata(client, chip); |
---|
467 | 444 | if (IS_ERR(pdata)) |
---|
468 | 445 | return PTR_ERR(pdata); |
---|
469 | 446 | } |
---|
.. | .. |
---|
602 | 579 | static struct i2c_driver pca955x_driver = { |
---|
603 | 580 | .driver = { |
---|
604 | 581 | .name = "leds-pca955x", |
---|
605 | | - .acpi_match_table = ACPI_PTR(pca955x_acpi_ids), |
---|
606 | | - .of_match_table = of_match_ptr(of_pca955x_match), |
---|
| 582 | + .of_match_table = of_pca955x_match, |
---|
607 | 583 | }, |
---|
608 | 584 | .probe = pca955x_probe, |
---|
609 | 585 | .id_table = pca955x_id, |
---|