| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * pca9532.c - 16-bit Led dimmer |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2011 Jan Weitzel |
|---|
| 5 | 6 | * Copyright (C) 2008 Riku Voipio |
|---|
| 6 | 7 | * |
|---|
| 7 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 8 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 9 | | - * the Free Software Foundation; version 2 of the License. |
|---|
| 10 | | - * |
|---|
| 11 | 8 | * Datasheet: http://www.nxp.com/documents/data_sheet/PCA9532.pdf |
|---|
| 12 | | - * |
|---|
| 13 | 9 | */ |
|---|
| 14 | 10 | |
|---|
| 15 | 11 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 20 | 16 | #include <linux/mutex.h> |
|---|
| 21 | 17 | #include <linux/workqueue.h> |
|---|
| 22 | 18 | #include <linux/leds-pca9532.h> |
|---|
| 23 | | -#include <linux/gpio.h> |
|---|
| 19 | +#include <linux/gpio/driver.h> |
|---|
| 24 | 20 | #include <linux/of.h> |
|---|
| 25 | 21 | #include <linux/of_device.h> |
|---|
| 26 | 22 | |
|---|
| .. | .. |
|---|
| 31 | 27 | #define PCA9532_REG_PWM(m, i) (PCA9532_REG_OFFSET(m) + 0x2 + (i) * 2) |
|---|
| 32 | 28 | #define LED_REG(m, led) (PCA9532_REG_OFFSET(m) + 0x5 + (led >> 2)) |
|---|
| 33 | 29 | #define LED_NUM(led) (led & 0x3) |
|---|
| 30 | +#define LED_SHIFT(led) (LED_NUM(led) * 2) |
|---|
| 31 | +#define LED_MASK(led) (0x3 << LED_SHIFT(led)) |
|---|
| 34 | 32 | |
|---|
| 35 | 33 | #define ldev_to_led(c) container_of(c, struct pca9532_led, ldev) |
|---|
| 36 | 34 | |
|---|
| .. | .. |
|---|
| 166 | 164 | mutex_lock(&data->update_lock); |
|---|
| 167 | 165 | reg = i2c_smbus_read_byte_data(client, LED_REG(maxleds, led->id)); |
|---|
| 168 | 166 | /* zero led bits */ |
|---|
| 169 | | - reg = reg & ~(0x3<<LED_NUM(led->id)*2); |
|---|
| 167 | + reg = reg & ~LED_MASK(led->id); |
|---|
| 170 | 168 | /* set the new value */ |
|---|
| 171 | | - reg = reg | (led->state << LED_NUM(led->id)*2); |
|---|
| 169 | + reg = reg | (led->state << LED_SHIFT(led->id)); |
|---|
| 172 | 170 | i2c_smbus_write_byte_data(client, LED_REG(maxleds, led->id), reg); |
|---|
| 173 | 171 | mutex_unlock(&data->update_lock); |
|---|
| 174 | 172 | } |
|---|
| .. | .. |
|---|
| 264 | 262 | |
|---|
| 265 | 263 | mutex_lock(&data->update_lock); |
|---|
| 266 | 264 | reg = i2c_smbus_read_byte_data(client, LED_REG(maxleds, led->id)); |
|---|
| 267 | | - ret = reg >> LED_NUM(led->id)/2; |
|---|
| 265 | + ret = (reg & LED_MASK(led->id)) >> LED_SHIFT(led->id); |
|---|
| 268 | 266 | mutex_unlock(&data->update_lock); |
|---|
| 269 | 267 | return ret; |
|---|
| 270 | 268 | } |
|---|
| .. | .. |
|---|
| 471 | 469 | { |
|---|
| 472 | 470 | struct pca9532_platform_data *pdata; |
|---|
| 473 | 471 | struct device_node *child; |
|---|
| 474 | | - const struct of_device_id *match; |
|---|
| 475 | 472 | int devid, maxleds; |
|---|
| 476 | 473 | int i = 0; |
|---|
| 477 | 474 | const char *state; |
|---|
| 478 | 475 | |
|---|
| 479 | | - match = of_match_device(of_pca9532_leds_match, dev); |
|---|
| 480 | | - if (!match) |
|---|
| 481 | | - return ERR_PTR(-ENODEV); |
|---|
| 482 | | - |
|---|
| 483 | | - devid = (int)(uintptr_t)match->data; |
|---|
| 476 | + devid = (int)(uintptr_t)of_device_get_match_data(dev); |
|---|
| 484 | 477 | maxleds = pca9532_chip_info_tbl[devid].num_leds; |
|---|
| 485 | 478 | |
|---|
| 486 | 479 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); |
|---|
| 487 | 480 | if (!pdata) |
|---|
| 488 | 481 | return ERR_PTR(-ENOMEM); |
|---|
| 489 | 482 | |
|---|
| 490 | | - for_each_child_of_node(np, child) { |
|---|
| 483 | + of_property_read_u8_array(np, "nxp,pwm", &pdata->pwm[0], |
|---|
| 484 | + ARRAY_SIZE(pdata->pwm)); |
|---|
| 485 | + of_property_read_u8_array(np, "nxp,psc", &pdata->psc[0], |
|---|
| 486 | + ARRAY_SIZE(pdata->psc)); |
|---|
| 487 | + |
|---|
| 488 | + for_each_available_child_of_node(np, child) { |
|---|
| 491 | 489 | if (of_property_read_string(child, "label", |
|---|
| 492 | 490 | &pdata->leds[i].name)) |
|---|
| 493 | 491 | pdata->leds[i].name = child->name; |
|---|
| .. | .. |
|---|
| 513 | 511 | const struct i2c_device_id *id) |
|---|
| 514 | 512 | { |
|---|
| 515 | 513 | int devid; |
|---|
| 516 | | - const struct of_device_id *of_id; |
|---|
| 517 | 514 | struct pca9532_data *data = i2c_get_clientdata(client); |
|---|
| 518 | 515 | struct pca9532_platform_data *pca9532_pdata = |
|---|
| 519 | 516 | dev_get_platdata(&client->dev); |
|---|
| 520 | | - struct device_node *np = client->dev.of_node; |
|---|
| 517 | + struct device_node *np = dev_of_node(&client->dev); |
|---|
| 521 | 518 | |
|---|
| 522 | 519 | if (!pca9532_pdata) { |
|---|
| 523 | 520 | if (np) { |
|---|
| .. | .. |
|---|
| 529 | 526 | dev_err(&client->dev, "no platform data\n"); |
|---|
| 530 | 527 | return -EINVAL; |
|---|
| 531 | 528 | } |
|---|
| 532 | | - of_id = of_match_device(of_pca9532_leds_match, |
|---|
| 533 | | - &client->dev); |
|---|
| 534 | | - if (unlikely(!of_id)) |
|---|
| 535 | | - return -EINVAL; |
|---|
| 536 | | - devid = (int)(uintptr_t) of_id->data; |
|---|
| 529 | + devid = (int)(uintptr_t)of_device_get_match_data(&client->dev); |
|---|
| 537 | 530 | } else { |
|---|
| 538 | 531 | devid = id->driver_data; |
|---|
| 539 | 532 | } |
|---|
| .. | .. |
|---|
| 559 | 552 | static int pca9532_remove(struct i2c_client *client) |
|---|
| 560 | 553 | { |
|---|
| 561 | 554 | struct pca9532_data *data = i2c_get_clientdata(client); |
|---|
| 562 | | - int err; |
|---|
| 563 | 555 | |
|---|
| 564 | | - err = pca9532_destroy_devices(data, data->chip_info->num_leds); |
|---|
| 565 | | - if (err) |
|---|
| 566 | | - return err; |
|---|
| 567 | | - |
|---|
| 568 | | - return 0; |
|---|
| 556 | + return pca9532_destroy_devices(data, data->chip_info->num_leds); |
|---|
| 569 | 557 | } |
|---|
| 570 | 558 | |
|---|
| 571 | 559 | module_i2c_driver(pca9532_driver); |
|---|