diff options
author | Laxman Dewangan <ldewangan@nvidia.com> | 2012-07-18 02:20:46 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2012-07-24 18:36:53 -0400 |
commit | 1176b5be67692e910c8d4b055902c314e7249e36 (patch) | |
tree | 211de06acf919e30eb5684918aa9222b23898190 /drivers/mfd/tps6586x.c | |
parent | b6719412dc28458f3c142a27bf3e0d2ab3ce0573 (diff) |
mfd: Use regmap for tps6586x register access.
Using regmap apis for accessing the device registers.
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Reviewed-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd/tps6586x.c')
-rw-r--r-- | drivers/mfd/tps6586x.c | 157 |
1 files changed, 46 insertions, 111 deletions
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c index c103ea903614..6f59594c6c11 100644 --- a/drivers/mfd/tps6586x.c +++ b/drivers/mfd/tps6586x.c | |||
@@ -21,8 +21,10 @@ | |||
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/mutex.h> | 22 | #include <linux/mutex.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/err.h> | ||
24 | #include <linux/gpio.h> | 25 | #include <linux/gpio.h> |
25 | #include <linux/i2c.h> | 26 | #include <linux/i2c.h> |
27 | #include <linux/regmap.h> | ||
26 | #include <linux/regulator/of_regulator.h> | 28 | #include <linux/regulator/of_regulator.h> |
27 | 29 | ||
28 | #include <linux/mfd/core.h> | 30 | #include <linux/mfd/core.h> |
@@ -48,6 +50,9 @@ | |||
48 | /* device id */ | 50 | /* device id */ |
49 | #define TPS6586X_VERSIONCRC 0xcd | 51 | #define TPS6586X_VERSIONCRC 0xcd |
50 | 52 | ||
53 | /* Maximum register */ | ||
54 | #define TPS6586X_MAX_REGISTER (TPS6586X_VERSIONCRC + 1) | ||
55 | |||
51 | struct tps6586x_irq_data { | 56 | struct tps6586x_irq_data { |
52 | u8 mask_reg; | 57 | u8 mask_reg; |
53 | u8 mask_mask; | 58 | u8 mask_mask; |
@@ -90,9 +95,9 @@ static const struct tps6586x_irq_data tps6586x_irqs[] = { | |||
90 | }; | 95 | }; |
91 | 96 | ||
92 | struct tps6586x { | 97 | struct tps6586x { |
93 | struct mutex lock; | ||
94 | struct device *dev; | 98 | struct device *dev; |
95 | struct i2c_client *client; | 99 | struct i2c_client *client; |
100 | struct regmap *regmap; | ||
96 | 101 | ||
97 | struct gpio_chip gpio; | 102 | struct gpio_chip gpio; |
98 | struct irq_chip irq_chip; | 103 | struct irq_chip irq_chip; |
@@ -103,152 +108,69 @@ struct tps6586x { | |||
103 | u8 mask_reg[5]; | 108 | u8 mask_reg[5]; |
104 | }; | 109 | }; |
105 | 110 | ||
106 | static inline int __tps6586x_read(struct i2c_client *client, | 111 | static inline struct tps6586x *dev_to_tps6586x(struct device *dev) |
107 | int reg, uint8_t *val) | ||
108 | { | 112 | { |
109 | int ret; | 113 | return i2c_get_clientdata(to_i2c_client(dev)); |
110 | |||
111 | ret = i2c_smbus_read_byte_data(client, reg); | ||
112 | if (ret < 0) { | ||
113 | dev_err(&client->dev, "failed reading at 0x%02x\n", reg); | ||
114 | return ret; | ||
115 | } | ||
116 | |||
117 | *val = (uint8_t)ret; | ||
118 | |||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | static inline int __tps6586x_reads(struct i2c_client *client, int reg, | ||
123 | int len, uint8_t *val) | ||
124 | { | ||
125 | int ret; | ||
126 | |||
127 | ret = i2c_smbus_read_i2c_block_data(client, reg, len, val); | ||
128 | if (ret < 0) { | ||
129 | dev_err(&client->dev, "failed reading from 0x%02x\n", reg); | ||
130 | return ret; | ||
131 | } | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static inline int __tps6586x_write(struct i2c_client *client, | ||
137 | int reg, uint8_t val) | ||
138 | { | ||
139 | int ret; | ||
140 | |||
141 | ret = i2c_smbus_write_byte_data(client, reg, val); | ||
142 | if (ret < 0) { | ||
143 | dev_err(&client->dev, "failed writing 0x%02x to 0x%02x\n", | ||
144 | val, reg); | ||
145 | return ret; | ||
146 | } | ||
147 | |||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | static inline int __tps6586x_writes(struct i2c_client *client, int reg, | ||
152 | int len, uint8_t *val) | ||
153 | { | ||
154 | int ret, i; | ||
155 | |||
156 | for (i = 0; i < len; i++) { | ||
157 | ret = __tps6586x_write(client, reg + i, *(val + i)); | ||
158 | if (ret < 0) | ||
159 | return ret; | ||
160 | } | ||
161 | |||
162 | return 0; | ||
163 | } | 114 | } |
164 | 115 | ||
165 | int tps6586x_write(struct device *dev, int reg, uint8_t val) | 116 | int tps6586x_write(struct device *dev, int reg, uint8_t val) |
166 | { | 117 | { |
167 | return __tps6586x_write(to_i2c_client(dev), reg, val); | 118 | struct tps6586x *tps6586x = dev_to_tps6586x(dev); |
119 | |||
120 | return regmap_write(tps6586x->regmap, reg, val); | ||
168 | } | 121 | } |
169 | EXPORT_SYMBOL_GPL(tps6586x_write); | 122 | EXPORT_SYMBOL_GPL(tps6586x_write); |
170 | 123 | ||
171 | int tps6586x_writes(struct device *dev, int reg, int len, uint8_t *val) | 124 | int tps6586x_writes(struct device *dev, int reg, int len, uint8_t *val) |
172 | { | 125 | { |
173 | return __tps6586x_writes(to_i2c_client(dev), reg, len, val); | 126 | struct tps6586x *tps6586x = dev_to_tps6586x(dev); |
127 | |||
128 | return regmap_bulk_write(tps6586x->regmap, reg, val, len); | ||
174 | } | 129 | } |
175 | EXPORT_SYMBOL_GPL(tps6586x_writes); | 130 | EXPORT_SYMBOL_GPL(tps6586x_writes); |
176 | 131 | ||
177 | int tps6586x_read(struct device *dev, int reg, uint8_t *val) | 132 | int tps6586x_read(struct device *dev, int reg, uint8_t *val) |
178 | { | 133 | { |
179 | return __tps6586x_read(to_i2c_client(dev), reg, val); | 134 | struct tps6586x *tps6586x = dev_to_tps6586x(dev); |
135 | unsigned int rval; | ||
136 | int ret; | ||
137 | |||
138 | ret = regmap_read(tps6586x->regmap, reg, &rval); | ||
139 | if (!ret) | ||
140 | *val = rval; | ||
141 | return ret; | ||
180 | } | 142 | } |
181 | EXPORT_SYMBOL_GPL(tps6586x_read); | 143 | EXPORT_SYMBOL_GPL(tps6586x_read); |
182 | 144 | ||
183 | int tps6586x_reads(struct device *dev, int reg, int len, uint8_t *val) | 145 | int tps6586x_reads(struct device *dev, int reg, int len, uint8_t *val) |
184 | { | 146 | { |
185 | return __tps6586x_reads(to_i2c_client(dev), reg, len, val); | 147 | struct tps6586x *tps6586x = dev_to_tps6586x(dev); |
148 | |||
149 | return regmap_bulk_read(tps6586x->regmap, reg, val, len); | ||
186 | } | 150 | } |
187 | EXPORT_SYMBOL_GPL(tps6586x_reads); | 151 | EXPORT_SYMBOL_GPL(tps6586x_reads); |
188 | 152 | ||
189 | int tps6586x_set_bits(struct device *dev, int reg, uint8_t bit_mask) | 153 | int tps6586x_set_bits(struct device *dev, int reg, uint8_t bit_mask) |
190 | { | 154 | { |
191 | struct tps6586x *tps6586x = dev_get_drvdata(dev); | 155 | struct tps6586x *tps6586x = dev_to_tps6586x(dev); |
192 | uint8_t reg_val; | ||
193 | int ret = 0; | ||
194 | |||
195 | mutex_lock(&tps6586x->lock); | ||
196 | |||
197 | ret = __tps6586x_read(to_i2c_client(dev), reg, ®_val); | ||
198 | if (ret) | ||
199 | goto out; | ||
200 | 156 | ||
201 | if ((reg_val & bit_mask) != bit_mask) { | 157 | return regmap_update_bits(tps6586x->regmap, reg, bit_mask, bit_mask); |
202 | reg_val |= bit_mask; | ||
203 | ret = __tps6586x_write(to_i2c_client(dev), reg, reg_val); | ||
204 | } | ||
205 | out: | ||
206 | mutex_unlock(&tps6586x->lock); | ||
207 | return ret; | ||
208 | } | 158 | } |
209 | EXPORT_SYMBOL_GPL(tps6586x_set_bits); | 159 | EXPORT_SYMBOL_GPL(tps6586x_set_bits); |
210 | 160 | ||
211 | int tps6586x_clr_bits(struct device *dev, int reg, uint8_t bit_mask) | 161 | int tps6586x_clr_bits(struct device *dev, int reg, uint8_t bit_mask) |
212 | { | 162 | { |
213 | struct tps6586x *tps6586x = dev_get_drvdata(dev); | 163 | struct tps6586x *tps6586x = dev_to_tps6586x(dev); |
214 | uint8_t reg_val; | ||
215 | int ret = 0; | ||
216 | 164 | ||
217 | mutex_lock(&tps6586x->lock); | 165 | return regmap_update_bits(tps6586x->regmap, reg, bit_mask, 0); |
218 | |||
219 | ret = __tps6586x_read(to_i2c_client(dev), reg, ®_val); | ||
220 | if (ret) | ||
221 | goto out; | ||
222 | |||
223 | if (reg_val & bit_mask) { | ||
224 | reg_val &= ~bit_mask; | ||
225 | ret = __tps6586x_write(to_i2c_client(dev), reg, reg_val); | ||
226 | } | ||
227 | out: | ||
228 | mutex_unlock(&tps6586x->lock); | ||
229 | return ret; | ||
230 | } | 166 | } |
231 | EXPORT_SYMBOL_GPL(tps6586x_clr_bits); | 167 | EXPORT_SYMBOL_GPL(tps6586x_clr_bits); |
232 | 168 | ||
233 | int tps6586x_update(struct device *dev, int reg, uint8_t val, uint8_t mask) | 169 | int tps6586x_update(struct device *dev, int reg, uint8_t val, uint8_t mask) |
234 | { | 170 | { |
235 | struct tps6586x *tps6586x = dev_get_drvdata(dev); | 171 | struct tps6586x *tps6586x = dev_to_tps6586x(dev); |
236 | uint8_t reg_val; | ||
237 | int ret = 0; | ||
238 | |||
239 | mutex_lock(&tps6586x->lock); | ||
240 | |||
241 | ret = __tps6586x_read(tps6586x->client, reg, ®_val); | ||
242 | if (ret) | ||
243 | goto out; | ||
244 | 172 | ||
245 | if ((reg_val & mask) != val) { | 173 | return regmap_update_bits(tps6586x->regmap, reg, mask, val); |
246 | reg_val = (reg_val & ~mask) | val; | ||
247 | ret = __tps6586x_write(tps6586x->client, reg, reg_val); | ||
248 | } | ||
249 | out: | ||
250 | mutex_unlock(&tps6586x->lock); | ||
251 | return ret; | ||
252 | } | 174 | } |
253 | EXPORT_SYMBOL_GPL(tps6586x_update); | 175 | EXPORT_SYMBOL_GPL(tps6586x_update); |
254 | 176 | ||
@@ -258,7 +180,7 @@ static int tps6586x_gpio_get(struct gpio_chip *gc, unsigned offset) | |||
258 | uint8_t val; | 180 | uint8_t val; |
259 | int ret; | 181 | int ret; |
260 | 182 | ||
261 | ret = __tps6586x_read(tps6586x->client, TPS6586X_GPIOSET2, &val); | 183 | ret = tps6586x_read(tps6586x->dev, TPS6586X_GPIOSET2, &val); |
262 | if (ret) | 184 | if (ret) |
263 | return ret; | 185 | return ret; |
264 | 186 | ||
@@ -556,6 +478,12 @@ static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *clien | |||
556 | } | 478 | } |
557 | #endif | 479 | #endif |
558 | 480 | ||
481 | static const struct regmap_config tps6586x_regmap_config = { | ||
482 | .reg_bits = 8, | ||
483 | .val_bits = 8, | ||
484 | .max_register = TPS6586X_MAX_REGISTER - 1, | ||
485 | }; | ||
486 | |||
559 | static int __devinit tps6586x_i2c_probe(struct i2c_client *client, | 487 | static int __devinit tps6586x_i2c_probe(struct i2c_client *client, |
560 | const struct i2c_device_id *id) | 488 | const struct i2c_device_id *id) |
561 | { | 489 | { |
@@ -589,7 +517,14 @@ static int __devinit tps6586x_i2c_probe(struct i2c_client *client, | |||
589 | tps6586x->dev = &client->dev; | 517 | tps6586x->dev = &client->dev; |
590 | i2c_set_clientdata(client, tps6586x); | 518 | i2c_set_clientdata(client, tps6586x); |
591 | 519 | ||
592 | mutex_init(&tps6586x->lock); | 520 | tps6586x->regmap = devm_regmap_init_i2c(client, |
521 | &tps6586x_regmap_config); | ||
522 | if (IS_ERR(tps6586x->regmap)) { | ||
523 | ret = PTR_ERR(tps6586x->regmap); | ||
524 | dev_err(&client->dev, "regmap init failed: %d\n", ret); | ||
525 | return ret; | ||
526 | } | ||
527 | |||
593 | 528 | ||
594 | if (client->irq) { | 529 | if (client->irq) { |
595 | ret = tps6586x_irq_init(tps6586x, client->irq, | 530 | ret = tps6586x_irq_init(tps6586x, client->irq, |