| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Core driver for TPS61050/61052 boost converters, used for while LED |
|---|
| 3 | 4 | * driving, audio power amplification, white LED flash, and generic |
|---|
| .. | .. |
|---|
| 9 | 10 | * Written on behalf of Linaro for ST-Ericsson |
|---|
| 10 | 11 | * |
|---|
| 11 | 12 | * Author: Linus Walleij <linus.walleij@linaro.org> |
|---|
| 12 | | - * |
|---|
| 13 | | - * License terms: GNU General Public License (GPL) version 2 |
|---|
| 14 | 13 | */ |
|---|
| 15 | 14 | |
|---|
| 16 | 15 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 92 | 91 | PLATFORM_DEVID_AUTO, cell, 1, NULL, 0, NULL); |
|---|
| 93 | 92 | } |
|---|
| 94 | 93 | |
|---|
| 94 | +static struct tps6105x_platform_data *tps6105x_parse_dt(struct device *dev) |
|---|
| 95 | +{ |
|---|
| 96 | + struct device_node *np = dev->of_node; |
|---|
| 97 | + struct tps6105x_platform_data *pdata; |
|---|
| 98 | + struct device_node *child; |
|---|
| 99 | + |
|---|
| 100 | + if (!np) |
|---|
| 101 | + return ERR_PTR(-EINVAL); |
|---|
| 102 | + if (of_get_available_child_count(np) > 1) { |
|---|
| 103 | + dev_err(dev, "cannot support multiple operational modes"); |
|---|
| 104 | + return ERR_PTR(-EINVAL); |
|---|
| 105 | + } |
|---|
| 106 | + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); |
|---|
| 107 | + if (!pdata) |
|---|
| 108 | + return ERR_PTR(-ENOMEM); |
|---|
| 109 | + pdata->mode = TPS6105X_MODE_SHUTDOWN; |
|---|
| 110 | + for_each_available_child_of_node(np, child) { |
|---|
| 111 | + if (child->name && !of_node_cmp(child->name, "regulator")) |
|---|
| 112 | + pdata->mode = TPS6105X_MODE_VOLTAGE; |
|---|
| 113 | + else if (child->name && !of_node_cmp(child->name, "led")) |
|---|
| 114 | + pdata->mode = TPS6105X_MODE_TORCH; |
|---|
| 115 | + } |
|---|
| 116 | + |
|---|
| 117 | + return pdata; |
|---|
| 118 | +} |
|---|
| 119 | + |
|---|
| 95 | 120 | static int tps6105x_probe(struct i2c_client *client, |
|---|
| 96 | 121 | const struct i2c_device_id *id) |
|---|
| 97 | 122 | { |
|---|
| .. | .. |
|---|
| 100 | 125 | int ret; |
|---|
| 101 | 126 | |
|---|
| 102 | 127 | pdata = dev_get_platdata(&client->dev); |
|---|
| 103 | | - if (!pdata) { |
|---|
| 104 | | - dev_err(&client->dev, "missing platform data\n"); |
|---|
| 105 | | - return -ENODEV; |
|---|
| 128 | + if (!pdata) |
|---|
| 129 | + pdata = tps6105x_parse_dt(&client->dev); |
|---|
| 130 | + if (IS_ERR(pdata)) { |
|---|
| 131 | + dev_err(&client->dev, "No platform data or DT found"); |
|---|
| 132 | + return PTR_ERR(pdata); |
|---|
| 106 | 133 | } |
|---|
| 107 | 134 | |
|---|
| 108 | 135 | tps6105x = devm_kmalloc(&client->dev, sizeof(*tps6105x), GFP_KERNEL); |
|---|