| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright 2015-16 Golden Delicious Computers |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Author: Nikolaus Schaller <hns@goldelico.com> |
|---|
| 5 | 6 | * |
|---|
| 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 | | - * |
|---|
| 10 | 7 | * LED driver for the IS31FL319{0,1,3,6,9} to drive 1, 3, 6 or 9 light |
|---|
| 11 | 8 | * effect LEDs. |
|---|
| 12 | | - * |
|---|
| 13 | 9 | */ |
|---|
| 14 | 10 | |
|---|
| 15 | 11 | #include <linux/err.h> |
|---|
| .. | .. |
|---|
| 20 | 16 | #include <linux/of_device.h> |
|---|
| 21 | 17 | #include <linux/regmap.h> |
|---|
| 22 | 18 | #include <linux/slab.h> |
|---|
| 19 | +#include <linux/delay.h> |
|---|
| 20 | +#include <linux/gpio/consumer.h> |
|---|
| 23 | 21 | |
|---|
| 24 | 22 | /* register numbers */ |
|---|
| 25 | 23 | #define IS31FL319X_SHUTDOWN 0x00 |
|---|
| .. | .. |
|---|
| 65 | 63 | struct is31fl319x_chip { |
|---|
| 66 | 64 | const struct is31fl319x_chipdef *cdef; |
|---|
| 67 | 65 | struct i2c_client *client; |
|---|
| 66 | + struct gpio_desc *shutdown_gpio; |
|---|
| 68 | 67 | struct regmap *regmap; |
|---|
| 69 | 68 | struct mutex lock; |
|---|
| 70 | 69 | u32 audio_gain_db; |
|---|
| .. | .. |
|---|
| 203 | 202 | static int is31fl319x_parse_dt(struct device *dev, |
|---|
| 204 | 203 | struct is31fl319x_chip *is31) |
|---|
| 205 | 204 | { |
|---|
| 206 | | - struct device_node *np = dev->of_node, *child; |
|---|
| 207 | | - const struct of_device_id *of_dev_id; |
|---|
| 205 | + struct device_node *np = dev_of_node(dev), *child; |
|---|
| 208 | 206 | int count; |
|---|
| 209 | 207 | int ret; |
|---|
| 210 | 208 | |
|---|
| 211 | 209 | if (!np) |
|---|
| 212 | 210 | return -ENODEV; |
|---|
| 213 | 211 | |
|---|
| 214 | | - of_dev_id = of_match_device(of_is31fl319x_match, dev); |
|---|
| 215 | | - if (!of_dev_id) { |
|---|
| 216 | | - dev_err(dev, "Failed to match device with supported chips\n"); |
|---|
| 217 | | - return -EINVAL; |
|---|
| 212 | + is31->shutdown_gpio = devm_gpiod_get_optional(dev, |
|---|
| 213 | + "shutdown", |
|---|
| 214 | + GPIOD_OUT_HIGH); |
|---|
| 215 | + if (IS_ERR(is31->shutdown_gpio)) { |
|---|
| 216 | + ret = PTR_ERR(is31->shutdown_gpio); |
|---|
| 217 | + dev_err(dev, "Failed to get shutdown gpio: %d\n", ret); |
|---|
| 218 | + return ret; |
|---|
| 218 | 219 | } |
|---|
| 219 | 220 | |
|---|
| 220 | | - is31->cdef = of_dev_id->data; |
|---|
| 221 | + is31->cdef = device_get_match_data(dev); |
|---|
| 221 | 222 | |
|---|
| 222 | | - count = of_get_child_count(np); |
|---|
| 223 | + count = of_get_available_child_count(np); |
|---|
| 223 | 224 | |
|---|
| 224 | | - dev_dbg(dev, "probe %s with %d leds defined in DT\n", |
|---|
| 225 | | - of_dev_id->compatible, count); |
|---|
| 225 | + dev_dbg(dev, "probing with %d leds defined in DT\n", count); |
|---|
| 226 | 226 | |
|---|
| 227 | 227 | if (!count || count > is31->cdef->num_leds) { |
|---|
| 228 | 228 | dev_err(dev, "Number of leds defined must be between 1 and %u\n", |
|---|
| .. | .. |
|---|
| 230 | 230 | return -ENODEV; |
|---|
| 231 | 231 | } |
|---|
| 232 | 232 | |
|---|
| 233 | | - for_each_child_of_node(np, child) { |
|---|
| 233 | + for_each_available_child_of_node(np, child) { |
|---|
| 234 | 234 | struct is31fl319x_led *led; |
|---|
| 235 | 235 | u32 reg; |
|---|
| 236 | 236 | |
|---|
| .. | .. |
|---|
| 337 | 337 | { |
|---|
| 338 | 338 | struct is31fl319x_chip *is31; |
|---|
| 339 | 339 | struct device *dev = &client->dev; |
|---|
| 340 | | - struct i2c_adapter *adapter = to_i2c_adapter(dev->parent); |
|---|
| 341 | 340 | int err; |
|---|
| 342 | 341 | int i = 0; |
|---|
| 343 | 342 | u32 aggregated_led_microamp = IS31FL319X_CURRENT_MAX; |
|---|
| 344 | 343 | |
|---|
| 345 | | - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) |
|---|
| 344 | + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) |
|---|
| 346 | 345 | return -EIO; |
|---|
| 347 | 346 | |
|---|
| 348 | 347 | is31 = devm_kzalloc(&client->dev, sizeof(*is31), GFP_KERNEL); |
|---|
| .. | .. |
|---|
| 355 | 354 | if (err) |
|---|
| 356 | 355 | goto free_mutex; |
|---|
| 357 | 356 | |
|---|
| 357 | + if (is31->shutdown_gpio) { |
|---|
| 358 | + gpiod_direction_output(is31->shutdown_gpio, 0); |
|---|
| 359 | + mdelay(5); |
|---|
| 360 | + gpiod_direction_output(is31->shutdown_gpio, 1); |
|---|
| 361 | + } |
|---|
| 362 | + |
|---|
| 358 | 363 | is31->client = client; |
|---|
| 359 | 364 | is31->regmap = devm_regmap_init_i2c(client, ®map_config); |
|---|
| 360 | 365 | if (IS_ERR(is31->regmap)) { |
|---|