aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/pcf50633-core.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-11-03 12:40:51 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-11-03 12:40:51 -0400
commita0a4194c943bc64dd7b6e26cccb036cb26b81363 (patch)
tree4282f0dd573344d10f69616eb05868b5cd563cc1 /drivers/mfd/pcf50633-core.c
parentcf0223503e6198292cdcc864e01eeb5fe7490752 (diff)
parentb958f7a7cbdfbf59ba61de7ebb9c59b0ee3a7967 (diff)
Merge branch 'for-next' of git://git.infradead.org/users/sameo/mfd-2.6
* 'for-next' of git://git.infradead.org/users/sameo/mfd-2.6: (80 commits) mfd: Fix missing abx500 header file updates mfd: Add missing <linux/io.h> include to intel_msic x86, mrst: add platform support for MSIC MFD driver mfd: Expose TurnOnStatus in ab8500 sysfs mfd: Remove support for early drop ab8500 chip mfd: Add support for ab8500 v3.3 mfd: Add ab8500 interrupt disable hook mfd: Convert db8500-prcmu panic() into pr_crit() mfd: Refactor db8500-prcmu request_clock() function mfd: Rename db8500-prcmu init function mfd: Fix db5500-prcmu defines mfd: db8500-prcmu voltage domain consumers additions mfd: db8500-prcmu reset code retrieval mfd: db8500-prcmu tweak for modem wakeup mfd: Add db8500-pcmu watchdog accessor functions for watchdog mfd: hwacc power state db8500-prcmu accessor mfd: Add db8500-prcmu accessors for PLL and SGA clock mfd: Move to the new db500 PRCMU API mfd: Create a common interface for dbx500 PRCMU drivers mfd: Initialize DB8500 PRCMU regs ... Fix up trivial conflicts in arch/arm/mach-imx/mach-mx31moboard.c arch/arm/mach-omap2/board-omap3beagle.c arch/arm/mach-u300/include/mach/irqs.h drivers/mfd/wm831x-spi.c
Diffstat (limited to 'drivers/mfd/pcf50633-core.c')
-rw-r--r--drivers/mfd/pcf50633-core.c114
1 files changed, 35 insertions, 79 deletions
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;