aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2011-08-08 04:04:40 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2011-10-24 08:09:08 -0400
commit6e3ad118041f56db752a5eb2b557517d14592af7 (patch)
treea19fb9c05cd0fdf46824b367844d689fe6030f5b
parentd036c96e703c176250503194f4fcd8b96e606b52 (diff)
mfd: Convert pcf50633 to use new register map API
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Tested-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r--drivers/mfd/Kconfig1
-rw-r--r--drivers/mfd/pcf50633-core.c114
-rw-r--r--include/linux/mfd/pcf50633/core.h3
3 files changed, 38 insertions, 80 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 21574bdf485f..13f0040413c4 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -500,6 +500,7 @@ config MFD_WM8994
500config MFD_PCF50633 500config MFD_PCF50633
501 tristate "Support for NXP PCF50633" 501 tristate "Support for NXP PCF50633"
502 depends on I2C 502 depends on I2C
503 select REGMAP_I2C
503 help 504 help
504 Say yes here if you have NXP PCF50633 chip on your board. 505 Say yes here if you have NXP PCF50633 chip on your board.
505 This core driver provides register access and IRQ handling 506 This core driver provides register access and IRQ handling
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c
index 57868416c760..ff1a7e741ecd 100644
--- a/drivers/mfd/pcf50633-core.c
+++ b/drivers/mfd/pcf50633-core.c
@@ -23,45 +23,22 @@
23#include <linux/i2c.h> 23#include <linux/i2c.h>
24#include <linux/pm.h> 24#include <linux/pm.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/regmap.h>
27#include <linux/err.h>
26 28
27#include <linux/mfd/pcf50633/core.h> 29#include <linux/mfd/pcf50633/core.h>
28 30
29static int __pcf50633_read(struct pcf50633 *pcf, u8 reg, int num, u8 *data)
30{
31 int ret;
32
33 ret = i2c_smbus_read_i2c_block_data(pcf->i2c_client, reg,
34 num, data);
35 if (ret < 0)
36 dev_err(pcf->dev, "Error reading %d regs at %d\n", num, reg);
37
38 return ret;
39}
40
41static int __pcf50633_write(struct pcf50633 *pcf, u8 reg, int num, u8 *data)
42{
43 int ret;
44
45 ret = i2c_smbus_write_i2c_block_data(pcf->i2c_client, reg,
46 num, data);
47 if (ret < 0)
48 dev_err(pcf->dev, "Error writing %d regs at %d\n", num, reg);
49
50 return ret;
51
52}
53
54/* Read a block of up to 32 regs */ 31/* Read a block of up to 32 regs */
55int pcf50633_read_block(struct pcf50633 *pcf, u8 reg, 32int pcf50633_read_block(struct pcf50633 *pcf, u8 reg,
56 int nr_regs, u8 *data) 33 int nr_regs, u8 *data)
57{ 34{
58 int ret; 35 int ret;
59 36
60 mutex_lock(&pcf->lock); 37 ret = regmap_raw_read(pcf->regmap, reg, data, nr_regs);
61 ret = __pcf50633_read(pcf, reg, nr_regs, data); 38 if (ret != 0)
62 mutex_unlock(&pcf->lock); 39 return ret;
63 40
64 return ret; 41 return nr_regs;
65} 42}
66EXPORT_SYMBOL_GPL(pcf50633_read_block); 43EXPORT_SYMBOL_GPL(pcf50633_read_block);
67 44
@@ -71,21 +48,22 @@ int pcf50633_write_block(struct pcf50633 *pcf , u8 reg,
71{ 48{
72 int ret; 49 int ret;
73 50
74 mutex_lock(&pcf->lock); 51 ret = regmap_raw_write(pcf->regmap, reg, data, nr_regs);
75 ret = __pcf50633_write(pcf, reg, nr_regs, data); 52 if (ret != 0)
76 mutex_unlock(&pcf->lock); 53 return ret;
77 54
78 return ret; 55 return nr_regs;
79} 56}
80EXPORT_SYMBOL_GPL(pcf50633_write_block); 57EXPORT_SYMBOL_GPL(pcf50633_write_block);
81 58
82u8 pcf50633_reg_read(struct pcf50633 *pcf, u8 reg) 59u8 pcf50633_reg_read(struct pcf50633 *pcf, u8 reg)
83{ 60{
84 u8 val; 61 unsigned int val;
62 int ret;
85 63
86 mutex_lock(&pcf->lock); 64 ret = regmap_read(pcf->regmap, reg, &val);
87 __pcf50633_read(pcf, reg, 1, &val); 65 if (ret < 0)
88 mutex_unlock(&pcf->lock); 66 return -1;
89 67
90 return val; 68 return val;
91} 69}
@@ -93,56 +71,19 @@ EXPORT_SYMBOL_GPL(pcf50633_reg_read);
93 71
94int pcf50633_reg_write(struct pcf50633 *pcf, u8 reg, u8 val) 72int pcf50633_reg_write(struct pcf50633 *pcf, u8 reg, u8 val)
95{ 73{
96 int ret; 74 return regmap_write(pcf->regmap, reg, val);
97
98 mutex_lock(&pcf->lock);
99 ret = __pcf50633_write(pcf, reg, 1, &val);
100 mutex_unlock(&pcf->lock);
101
102 return ret;
103} 75}
104EXPORT_SYMBOL_GPL(pcf50633_reg_write); 76EXPORT_SYMBOL_GPL(pcf50633_reg_write);
105 77
106int pcf50633_reg_set_bit_mask(struct pcf50633 *pcf, u8 reg, u8 mask, u8 val) 78int pcf50633_reg_set_bit_mask(struct pcf50633 *pcf, u8 reg, u8 mask, u8 val)
107{ 79{
108 int ret; 80 return regmap_update_bits(pcf->regmap, reg, mask, val);
109 u8 tmp;
110
111 val &= mask;
112
113 mutex_lock(&pcf->lock);
114 ret = __pcf50633_read(pcf, reg, 1, &tmp);
115 if (ret < 0)
116 goto out;
117
118 tmp &= ~mask;
119 tmp |= val;
120 ret = __pcf50633_write(pcf, reg, 1, &tmp);
121
122out:
123 mutex_unlock(&pcf->lock);
124
125 return ret;
126} 81}
127EXPORT_SYMBOL_GPL(pcf50633_reg_set_bit_mask); 82EXPORT_SYMBOL_GPL(pcf50633_reg_set_bit_mask);
128 83
129int pcf50633_reg_clear_bits(struct pcf50633 *pcf, u8 reg, u8 val) 84int pcf50633_reg_clear_bits(struct pcf50633 *pcf, u8 reg, u8 val)
130{ 85{
131 int ret; 86 return regmap_update_bits(pcf->regmap, reg, val, 0);
132 u8 tmp;
133
134 mutex_lock(&pcf->lock);
135 ret = __pcf50633_read(pcf, reg, 1, &tmp);
136 if (ret < 0)
137 goto out;
138
139 tmp &= ~val;
140 ret = __pcf50633_write(pcf, reg, 1, &tmp);
141
142out:
143 mutex_unlock(&pcf->lock);
144
145 return ret;
146} 87}
147EXPORT_SYMBOL_GPL(pcf50633_reg_clear_bits); 88EXPORT_SYMBOL_GPL(pcf50633_reg_clear_bits);
148 89
@@ -251,6 +192,11 @@ static int pcf50633_resume(struct device *dev)
251 192
252static SIMPLE_DEV_PM_OPS(pcf50633_pm, pcf50633_suspend, pcf50633_resume); 193static SIMPLE_DEV_PM_OPS(pcf50633_pm, pcf50633_suspend, pcf50633_resume);
253 194
195static struct regmap_config pcf50633_regmap_config = {
196 .reg_bits = 8,
197 .val_bits = 8,
198};
199
254static int __devinit pcf50633_probe(struct i2c_client *client, 200static int __devinit pcf50633_probe(struct i2c_client *client,
255 const struct i2c_device_id *ids) 201 const struct i2c_device_id *ids)
256{ 202{
@@ -272,16 +218,23 @@ static int __devinit pcf50633_probe(struct i2c_client *client,
272 218
273 mutex_init(&pcf->lock); 219 mutex_init(&pcf->lock);
274 220
221 pcf->regmap = regmap_init_i2c(client, &pcf50633_regmap_config);
222 if (IS_ERR(pcf->regmap)) {
223 ret = PTR_ERR(pcf->regmap);
224 dev_err(pcf->dev, "Failed to allocate register map: %d\n",
225 ret);
226 goto err_free;
227 }
228
275 i2c_set_clientdata(client, pcf); 229 i2c_set_clientdata(client, pcf);
276 pcf->dev = &client->dev; 230 pcf->dev = &client->dev;
277 pcf->i2c_client = client;
278 231
279 version = pcf50633_reg_read(pcf, 0); 232 version = pcf50633_reg_read(pcf, 0);
280 variant = pcf50633_reg_read(pcf, 1); 233 variant = pcf50633_reg_read(pcf, 1);
281 if (version < 0 || variant < 0) { 234 if (version < 0 || variant < 0) {
282 dev_err(pcf->dev, "Unable to probe pcf50633\n"); 235 dev_err(pcf->dev, "Unable to probe pcf50633\n");
283 ret = -ENODEV; 236 ret = -ENODEV;
284 goto err_free; 237 goto err_regmap;
285 } 238 }
286 239
287 dev_info(pcf->dev, "Probed device version %d variant %d\n", 240 dev_info(pcf->dev, "Probed device version %d variant %d\n",
@@ -328,6 +281,8 @@ static int __devinit pcf50633_probe(struct i2c_client *client,
328 281
329 return 0; 282 return 0;
330 283
284err_regmap:
285 regmap_exit(pcf->regmap);
331err_free: 286err_free:
332 kfree(pcf); 287 kfree(pcf);
333 288
@@ -351,6 +306,7 @@ static int __devexit pcf50633_remove(struct i2c_client *client)
351 for (i = 0; i < PCF50633_NUM_REGULATORS; i++) 306 for (i = 0; i < PCF50633_NUM_REGULATORS; i++)
352 platform_device_unregister(pcf->regulator_pdev[i]); 307 platform_device_unregister(pcf->regulator_pdev[i]);
353 308
309 regmap_exit(pcf->regmap);
354 kfree(pcf); 310 kfree(pcf);
355 311
356 return 0; 312 return 0;
diff --git a/include/linux/mfd/pcf50633/core.h b/include/linux/mfd/pcf50633/core.h
index 50d4a047118d..a80840752b4c 100644
--- a/include/linux/mfd/pcf50633/core.h
+++ b/include/linux/mfd/pcf50633/core.h
@@ -21,6 +21,7 @@
21#include <linux/mfd/pcf50633/backlight.h> 21#include <linux/mfd/pcf50633/backlight.h>
22 22
23struct pcf50633; 23struct pcf50633;
24struct regmap;
24 25
25#define PCF50633_NUM_REGULATORS 11 26#define PCF50633_NUM_REGULATORS 11
26 27
@@ -134,7 +135,7 @@ enum {
134 135
135struct pcf50633 { 136struct pcf50633 {
136 struct device *dev; 137 struct device *dev;
137 struct i2c_client *i2c_client; 138 struct regmap *regmap;
138 139
139 struct pcf50633_platform_data *pdata; 140 struct pcf50633_platform_data *pdata;
140 int irq; 141 int irq;