Skip to content

Commit 3c32a43

Browse files
committed
regulator: Add device tree support to AD5398
Merge series from Isaac Scott <[email protected]>: The AD5398 is a DAC that can be used to control current flow in circuits in a wide variety of applications such as motor control, or in my case, LED control. I found when working with the current driver that it did not work for my use case. It transpired that it only had support for platform_data, and didn't appear to be correctly implemented according to the datasheet, which can be found here: https://www.analog.com/media/en/technical-documentation/data-sheets/ad5398.pdf One example of this is the "soft power-down" bit being referred to in the driver as simply "enable", which gives the impression that the setting that bit will allow current through the regulator, which it does not. This series allows the regulator to be given its constraints via the device tree, and makes the function of the enable register much more obvious.
2 parents f5aab04 + 5a6a461 commit 3c32a43

File tree

1 file changed

+18
-12
lines changed

1 file changed

+18
-12
lines changed

drivers/regulator/ad5398.c

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414
#include <linux/platform_device.h>
1515
#include <linux/regulator/driver.h>
1616
#include <linux/regulator/machine.h>
17+
#include <linux/regulator/of_regulator.h>
1718

18-
#define AD5398_CURRENT_EN_MASK 0x8000
19+
#define AD5398_SW_POWER_DOWN BIT(16)
1920

2021
struct ad5398_chip_info {
2122
struct i2c_client *client;
@@ -113,7 +114,7 @@ static int ad5398_set_current_limit(struct regulator_dev *rdev, int min_uA, int
113114

114115
/* prepare register data */
115116
selector = (selector << chip->current_offset) & chip->current_mask;
116-
data = (unsigned short)selector | (data & AD5398_CURRENT_EN_MASK);
117+
data = (unsigned short)selector | (data & AD5398_SW_POWER_DOWN);
117118

118119
/* write the new current value back as well as enable bit */
119120
ret = ad5398_write_reg(client, data);
@@ -132,10 +133,10 @@ static int ad5398_is_enabled(struct regulator_dev *rdev)
132133
if (ret < 0)
133134
return ret;
134135

135-
if (data & AD5398_CURRENT_EN_MASK)
136-
return 1;
137-
else
136+
if (data & AD5398_SW_POWER_DOWN)
138137
return 0;
138+
else
139+
return 1;
139140
}
140141

141142
static int ad5398_enable(struct regulator_dev *rdev)
@@ -149,10 +150,10 @@ static int ad5398_enable(struct regulator_dev *rdev)
149150
if (ret < 0)
150151
return ret;
151152

152-
if (data & AD5398_CURRENT_EN_MASK)
153+
if (!(data & AD5398_SW_POWER_DOWN))
153154
return 0;
154155

155-
data |= AD5398_CURRENT_EN_MASK;
156+
data &= ~AD5398_SW_POWER_DOWN;
156157

157158
ret = ad5398_write_reg(client, data);
158159

@@ -170,10 +171,10 @@ static int ad5398_disable(struct regulator_dev *rdev)
170171
if (ret < 0)
171172
return ret;
172173

173-
if (!(data & AD5398_CURRENT_EN_MASK))
174+
if (data & AD5398_SW_POWER_DOWN)
174175
return 0;
175176

176-
data &= ~AD5398_CURRENT_EN_MASK;
177+
data |= AD5398_SW_POWER_DOWN;
177178

178179
ret = ad5398_write_reg(client, data);
179180

@@ -221,15 +222,20 @@ static int ad5398_probe(struct i2c_client *client)
221222
const struct ad5398_current_data_format *df =
222223
(struct ad5398_current_data_format *)id->driver_data;
223224

224-
if (!init_data)
225-
return -EINVAL;
226-
227225
chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
228226
if (!chip)
229227
return -ENOMEM;
230228

231229
config.dev = &client->dev;
230+
if (client->dev.of_node)
231+
init_data = of_get_regulator_init_data(&client->dev,
232+
client->dev.of_node,
233+
&ad5398_reg);
234+
if (!init_data)
235+
return -EINVAL;
236+
232237
config.init_data = init_data;
238+
config.of_node = client->dev.of_node;
233239
config.driver_data = chip;
234240

235241
chip->client = client;

0 commit comments

Comments
 (0)