aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2011-06-17 08:02:27 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2011-08-22 07:25:15 -0400
commitd6c645fc00777a6f8a7df1f580065ec30c71be7b (patch)
tree0dba18686fbfac44b7123b2a29b5b8e75b761346 /drivers/mfd
parent5570c2f709bdc455a2e8907919c1214ca8a21859 (diff)
mfd: Convert WM8994 to use new register map API
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Acked-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/Kconfig1
-rw-r--r--drivers/mfd/wm8994-core.c178
2 files changed, 34 insertions, 145 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index cfae5c594d24..a67adcbd0fa1 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -490,6 +490,7 @@ config MFD_WM8350_I2C
490config MFD_WM8994 490config MFD_WM8994
491 bool "Support Wolfson Microelectronics WM8994" 491 bool "Support Wolfson Microelectronics WM8994"
492 select MFD_CORE 492 select MFD_CORE
493 select REGMAP_I2C
493 depends on I2C=y && GENERIC_HARDIRQS 494 depends on I2C=y && GENERIC_HARDIRQS
494 help 495 help
495 The WM8994 is a highly integrated hi-fi CODEC designed for 496 The WM8994 is a highly integrated hi-fi CODEC designed for
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
index 96479c9b1728..bfde4e8ec638 100644
--- a/drivers/mfd/wm8994-core.c
+++ b/drivers/mfd/wm8994-core.c
@@ -16,9 +16,11 @@
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/i2c.h> 18#include <linux/i2c.h>
19#include <linux/err.h>
19#include <linux/delay.h> 20#include <linux/delay.h>
20#include <linux/mfd/core.h> 21#include <linux/mfd/core.h>
21#include <linux/pm_runtime.h> 22#include <linux/pm_runtime.h>
23#include <linux/regmap.h>
22#include <linux/regulator/consumer.h> 24#include <linux/regulator/consumer.h>
23#include <linux/regulator/machine.h> 25#include <linux/regulator/machine.h>
24 26
@@ -29,22 +31,7 @@
29static int wm8994_read(struct wm8994 *wm8994, unsigned short reg, 31static int wm8994_read(struct wm8994 *wm8994, unsigned short reg,
30 int bytes, void *dest) 32 int bytes, void *dest)
31{ 33{
32 int ret, i; 34 return regmap_raw_read(wm8994->regmap, reg, dest, bytes);
33 u16 *buf = dest;
34
35 BUG_ON(bytes % 2);
36 BUG_ON(bytes <= 0);
37
38 ret = wm8994->read_dev(wm8994, reg, bytes, dest);
39 if (ret < 0)
40 return ret;
41
42 for (i = 0; i < bytes / 2; i++) {
43 dev_vdbg(wm8994->dev, "Read %04x from R%d(0x%x)\n",
44 be16_to_cpu(buf[i]), reg + i, reg + i);
45 }
46
47 return 0;
48} 35}
49 36
50/** 37/**
@@ -55,19 +42,15 @@ static int wm8994_read(struct wm8994 *wm8994, unsigned short reg,
55 */ 42 */
56int wm8994_reg_read(struct wm8994 *wm8994, unsigned short reg) 43int wm8994_reg_read(struct wm8994 *wm8994, unsigned short reg)
57{ 44{
58 unsigned short val; 45 unsigned int val;
59 int ret; 46 int ret;
60 47
61 mutex_lock(&wm8994->io_lock); 48 ret = regmap_read(wm8994->regmap, reg, &val);
62
63 ret = wm8994_read(wm8994, reg, 2, &val);
64
65 mutex_unlock(&wm8994->io_lock);
66 49
67 if (ret < 0) 50 if (ret < 0)
68 return ret; 51 return ret;
69 else 52 else
70 return be16_to_cpu(val); 53 return val;
71} 54}
72EXPORT_SYMBOL_GPL(wm8994_reg_read); 55EXPORT_SYMBOL_GPL(wm8994_reg_read);
73 56
@@ -82,33 +65,13 @@ EXPORT_SYMBOL_GPL(wm8994_reg_read);
82int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg, 65int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg,
83 int count, u16 *buf) 66 int count, u16 *buf)
84{ 67{
85 int ret; 68 return regmap_bulk_read(wm8994->regmap, reg, buf, count);
86
87 mutex_lock(&wm8994->io_lock);
88
89 ret = wm8994_read(wm8994, reg, count * 2, buf);
90
91 mutex_unlock(&wm8994->io_lock);
92
93 return ret;
94} 69}
95EXPORT_SYMBOL_GPL(wm8994_bulk_read);
96 70
97static int wm8994_write(struct wm8994 *wm8994, unsigned short reg, 71static int wm8994_write(struct wm8994 *wm8994, unsigned short reg,
98 int bytes, const void *src) 72 int bytes, const void *src)
99{ 73{
100 const u16 *buf = src; 74 return regmap_raw_write(wm8994->regmap, reg, src, bytes);
101 int i;
102
103 BUG_ON(bytes % 2);
104 BUG_ON(bytes <= 0);
105
106 for (i = 0; i < bytes / 2; i++) {
107 dev_vdbg(wm8994->dev, "Write %04x to R%d(0x%x)\n",
108 be16_to_cpu(buf[i]), reg + i, reg + i);
109 }
110
111 return wm8994->write_dev(wm8994, reg, bytes, src);
112} 75}
113 76
114/** 77/**
@@ -121,17 +84,7 @@ static int wm8994_write(struct wm8994 *wm8994, unsigned short reg,
121int wm8994_reg_write(struct wm8994 *wm8994, unsigned short reg, 84int wm8994_reg_write(struct wm8994 *wm8994, unsigned short reg,
122 unsigned short val) 85 unsigned short val)
123{ 86{
124 int ret; 87 return regmap_write(wm8994->regmap, reg, val);
125
126 val = cpu_to_be16(val);
127
128 mutex_lock(&wm8994->io_lock);
129
130 ret = wm8994_write(wm8994, reg, 2, &val);
131
132 mutex_unlock(&wm8994->io_lock);
133
134 return ret;
135} 88}
136EXPORT_SYMBOL_GPL(wm8994_reg_write); 89EXPORT_SYMBOL_GPL(wm8994_reg_write);
137 90
@@ -146,15 +99,7 @@ EXPORT_SYMBOL_GPL(wm8994_reg_write);
146int wm8994_bulk_write(struct wm8994 *wm8994, unsigned short reg, 99int wm8994_bulk_write(struct wm8994 *wm8994, unsigned short reg,
147 int count, const u16 *buf) 100 int count, const u16 *buf)
148{ 101{
149 int ret; 102 return regmap_raw_write(wm8994->regmap, reg, buf, count * sizeof(u16));
150
151 mutex_lock(&wm8994->io_lock);
152
153 ret = wm8994_write(wm8994, reg, count * 2, buf);
154
155 mutex_unlock(&wm8994->io_lock);
156
157 return ret;
158} 103}
159EXPORT_SYMBOL_GPL(wm8994_bulk_write); 104EXPORT_SYMBOL_GPL(wm8994_bulk_write);
160 105
@@ -169,28 +114,7 @@ EXPORT_SYMBOL_GPL(wm8994_bulk_write);
169int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg, 114int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg,
170 unsigned short mask, unsigned short val) 115 unsigned short mask, unsigned short val)
171{ 116{
172 int ret; 117 return regmap_update_bits(wm8994->regmap, reg, mask, val);
173 u16 r;
174
175 mutex_lock(&wm8994->io_lock);
176
177 ret = wm8994_read(wm8994, reg, 2, &r);
178 if (ret < 0)
179 goto out;
180
181 r = be16_to_cpu(r);
182
183 r &= ~mask;
184 r |= val;
185
186 r = cpu_to_be16(r);
187
188 ret = wm8994_write(wm8994, reg, 2, &r);
189
190out:
191 mutex_unlock(&wm8994->io_lock);
192
193 return ret;
194} 118}
195EXPORT_SYMBOL_GPL(wm8994_set_bits); 119EXPORT_SYMBOL_GPL(wm8994_set_bits);
196 120
@@ -378,6 +302,11 @@ static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo)
378} 302}
379#endif 303#endif
380 304
305static struct regmap_config wm8994_regmap_config = {
306 .reg_bits = 16,
307 .val_bits = 16,
308};
309
381/* 310/*
382 * Instantiate the generic non-control parts of the device. 311 * Instantiate the generic non-control parts of the device.
383 */ 312 */
@@ -387,7 +316,6 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
387 const char *devname; 316 const char *devname;
388 int ret, i; 317 int ret, i;
389 318
390 mutex_init(&wm8994->io_lock);
391 dev_set_drvdata(wm8994->dev, wm8994); 319 dev_set_drvdata(wm8994->dev, wm8994);
392 320
393 /* Add the on-chip regulators first for bootstrapping */ 321 /* Add the on-chip regulators first for bootstrapping */
@@ -397,7 +325,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
397 NULL, 0); 325 NULL, 0);
398 if (ret != 0) { 326 if (ret != 0) {
399 dev_err(wm8994->dev, "Failed to add children: %d\n", ret); 327 dev_err(wm8994->dev, "Failed to add children: %d\n", ret);
400 goto err; 328 goto err_regmap;
401 } 329 }
402 330
403 switch (wm8994->type) { 331 switch (wm8994->type) {
@@ -409,7 +337,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
409 break; 337 break;
410 default: 338 default:
411 BUG(); 339 BUG();
412 goto err; 340 goto err_regmap;
413 } 341 }
414 342
415 wm8994->supplies = kzalloc(sizeof(struct regulator_bulk_data) * 343 wm8994->supplies = kzalloc(sizeof(struct regulator_bulk_data) *
@@ -417,7 +345,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
417 GFP_KERNEL); 345 GFP_KERNEL);
418 if (!wm8994->supplies) { 346 if (!wm8994->supplies) {
419 ret = -ENOMEM; 347 ret = -ENOMEM;
420 goto err; 348 goto err_regmap;
421 } 349 }
422 350
423 switch (wm8994->type) { 351 switch (wm8994->type) {
@@ -431,7 +359,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
431 break; 359 break;
432 default: 360 default:
433 BUG(); 361 BUG();
434 goto err; 362 goto err_regmap;
435 } 363 }
436 364
437 ret = regulator_bulk_get(wm8994->dev, wm8994->num_supplies, 365 ret = regulator_bulk_get(wm8994->dev, wm8994->num_supplies,
@@ -554,7 +482,8 @@ err_get:
554 regulator_bulk_free(wm8994->num_supplies, wm8994->supplies); 482 regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
555err_supplies: 483err_supplies:
556 kfree(wm8994->supplies); 484 kfree(wm8994->supplies);
557err: 485err_regmap:
486 regmap_exit(wm8994->regmap);
558 mfd_remove_devices(wm8994->dev); 487 mfd_remove_devices(wm8994->dev);
559 kfree(wm8994); 488 kfree(wm8994);
560 return ret; 489 return ret;
@@ -569,62 +498,15 @@ static void wm8994_device_exit(struct wm8994 *wm8994)
569 wm8994->supplies); 498 wm8994->supplies);
570 regulator_bulk_free(wm8994->num_supplies, wm8994->supplies); 499 regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
571 kfree(wm8994->supplies); 500 kfree(wm8994->supplies);
501 regmap_exit(wm8994->regmap);
572 kfree(wm8994); 502 kfree(wm8994);
573} 503}
574 504
575static int wm8994_i2c_read_device(struct wm8994 *wm8994, unsigned short reg,
576 int bytes, void *dest)
577{
578 struct i2c_client *i2c = wm8994->control_data;
579 int ret;
580 u16 r = cpu_to_be16(reg);
581
582 ret = i2c_master_send(i2c, (unsigned char *)&r, 2);
583 if (ret < 0)
584 return ret;
585 if (ret != 2)
586 return -EIO;
587
588 ret = i2c_master_recv(i2c, dest, bytes);
589 if (ret < 0)
590 return ret;
591 if (ret != bytes)
592 return -EIO;
593 return 0;
594}
595
596static int wm8994_i2c_write_device(struct wm8994 *wm8994, unsigned short reg,
597 int bytes, const void *src)
598{
599 struct i2c_client *i2c = wm8994->control_data;
600 struct i2c_msg xfer[2];
601 int ret;
602
603 reg = cpu_to_be16(reg);
604
605 xfer[0].addr = i2c->addr;
606 xfer[0].flags = 0;
607 xfer[0].len = 2;
608 xfer[0].buf = (char *)&reg;
609
610 xfer[1].addr = i2c->addr;
611 xfer[1].flags = I2C_M_NOSTART;
612 xfer[1].len = bytes;
613 xfer[1].buf = (char *)src;
614
615 ret = i2c_transfer(i2c->adapter, xfer, 2);
616 if (ret < 0)
617 return ret;
618 if (ret != 2)
619 return -EIO;
620
621 return 0;
622}
623
624static int wm8994_i2c_probe(struct i2c_client *i2c, 505static int wm8994_i2c_probe(struct i2c_client *i2c,
625 const struct i2c_device_id *id) 506 const struct i2c_device_id *id)
626{ 507{
627 struct wm8994 *wm8994; 508 struct wm8994 *wm8994;
509 int ret;
628 510
629 wm8994 = kzalloc(sizeof(struct wm8994), GFP_KERNEL); 511 wm8994 = kzalloc(sizeof(struct wm8994), GFP_KERNEL);
630 if (wm8994 == NULL) 512 if (wm8994 == NULL)
@@ -632,12 +514,18 @@ static int wm8994_i2c_probe(struct i2c_client *i2c,
632 514
633 i2c_set_clientdata(i2c, wm8994); 515 i2c_set_clientdata(i2c, wm8994);
634 wm8994->dev = &i2c->dev; 516 wm8994->dev = &i2c->dev;
635 wm8994->control_data = i2c;
636 wm8994->read_dev = wm8994_i2c_read_device;
637 wm8994->write_dev = wm8994_i2c_write_device;
638 wm8994->irq = i2c->irq; 517 wm8994->irq = i2c->irq;
639 wm8994->type = id->driver_data; 518 wm8994->type = id->driver_data;
640 519
520 wm8994->regmap = regmap_init_i2c(i2c, &wm8994_regmap_config);
521 if (IS_ERR(wm8994->regmap)) {
522 ret = PTR_ERR(wm8994->regmap);
523 dev_err(wm8994->dev, "Failed to allocate register map: %d\n",
524 ret);
525 kfree(wm8994);
526 return ret;
527 }
528
641 return wm8994_device_init(wm8994, i2c->irq); 529 return wm8994_device_init(wm8994, i2c->irq);
642} 530}
643 531