aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2012-05-07 05:03:21 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2012-05-07 05:32:08 -0400
commitb7b142d9fc056e98e6fdef82dca3e87067517340 (patch)
treeb7ec58d3c576080cdf94435f9d227bf6496b8150
parentce7e4e11221dd7fbe82c8ad28d1875b0dfa20de4 (diff)
mfd: Convert wm8350 physical I/O to regmap API
The driver still uses a custom cache implementation but the underlying physical I/O is now done using the regmap API, saving some code and avoiding allocating enormous scratch arrays on the stack. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r--drivers/mfd/wm8350-core.c31
-rw-r--r--drivers/mfd/wm8350-i2c.c53
-rw-r--r--include/linux/mfd/wm8350/core.h9
3 files changed, 27 insertions, 66 deletions
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c
index dd1caaac55e4..8a9b11ca076a 100644
--- a/drivers/mfd/wm8350-core.c
+++ b/drivers/mfd/wm8350-core.c
@@ -20,6 +20,7 @@
20#include <linux/device.h> 20#include <linux/device.h>
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23#include <linux/regmap.h>
23#include <linux/workqueue.h> 24#include <linux/workqueue.h>
24 25
25#include <linux/mfd/wm8350/core.h> 26#include <linux/mfd/wm8350/core.h>
@@ -74,7 +75,7 @@ static int wm8350_phys_read(struct wm8350 *wm8350, u8 reg, int num_regs,
74 int bytes = num_regs * 2; 75 int bytes = num_regs * 2;
75 76
76 dev_dbg(wm8350->dev, "volatile read\n"); 77 dev_dbg(wm8350->dev, "volatile read\n");
77 ret = wm8350->read_dev(wm8350, reg, bytes, (char *)dest); 78 ret = regmap_raw_read(wm8350->regmap, reg, dest, bytes);
78 79
79 for (i = reg; i < reg + num_regs; i++) { 80 for (i = reg; i < reg + num_regs; i++) {
80 /* Cache is CPU endian */ 81 /* Cache is CPU endian */
@@ -96,9 +97,6 @@ static int wm8350_read(struct wm8350 *wm8350, u8 reg, int num_regs, u16 *dest)
96 int ret = 0; 97 int ret = 0;
97 int bytes = num_regs * 2; 98 int bytes = num_regs * 2;
98 99
99 if (wm8350->read_dev == NULL)
100 return -ENODEV;
101
102 if ((reg + num_regs - 1) > WM8350_MAX_REGISTER) { 100 if ((reg + num_regs - 1) > WM8350_MAX_REGISTER) {
103 dev_err(wm8350->dev, "invalid reg %x\n", 101 dev_err(wm8350->dev, "invalid reg %x\n",
104 reg + num_regs - 1); 102 reg + num_regs - 1);
@@ -149,9 +147,6 @@ static int wm8350_write(struct wm8350 *wm8350, u8 reg, int num_regs, u16 *src)
149 int end = reg + num_regs; 147 int end = reg + num_regs;
150 int bytes = num_regs * 2; 148 int bytes = num_regs * 2;
151 149
152 if (wm8350->write_dev == NULL)
153 return -ENODEV;
154
155 if ((reg + num_regs - 1) > WM8350_MAX_REGISTER) { 150 if ((reg + num_regs - 1) > WM8350_MAX_REGISTER) {
156 dev_err(wm8350->dev, "invalid reg %x\n", 151 dev_err(wm8350->dev, "invalid reg %x\n",
157 reg + num_regs - 1); 152 reg + num_regs - 1);
@@ -182,7 +177,7 @@ static int wm8350_write(struct wm8350 *wm8350, u8 reg, int num_regs, u16 *src)
182 } 177 }
183 178
184 /* Actually write it out */ 179 /* Actually write it out */
185 return wm8350->write_dev(wm8350, reg, bytes, (char *)src); 180 return regmap_raw_write(wm8350->regmap, reg, src, bytes);
186} 181}
187 182
188/* 183/*
@@ -515,9 +510,8 @@ static int wm8350_create_cache(struct wm8350 *wm8350, int type, int mode)
515 * a PMIC so the device many not be in a virgin state and we 510 * a PMIC so the device many not be in a virgin state and we
516 * can't rely on the silicon values. 511 * can't rely on the silicon values.
517 */ 512 */
518 ret = wm8350->read_dev(wm8350, 0, 513 ret = regmap_raw_read(wm8350->regmap, 0, wm8350->reg_cache,
519 sizeof(u16) * (WM8350_MAX_REGISTER + 1), 514 sizeof(u16) * (WM8350_MAX_REGISTER + 1));
520 wm8350->reg_cache);
521 if (ret < 0) { 515 if (ret < 0) {
522 dev_err(wm8350->dev, 516 dev_err(wm8350->dev,
523 "failed to read initial cache values\n"); 517 "failed to read initial cache values\n");
@@ -570,35 +564,30 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq,
570 struct wm8350_platform_data *pdata) 564 struct wm8350_platform_data *pdata)
571{ 565{
572 int ret; 566 int ret;
573 u16 id1, id2, mask_rev; 567 unsigned int id1, id2, mask_rev;
574 u16 cust_id, mode, chip_rev; 568 unsigned int cust_id, mode, chip_rev;
575 569
576 dev_set_drvdata(wm8350->dev, wm8350); 570 dev_set_drvdata(wm8350->dev, wm8350);
577 571
578 /* get WM8350 revision and config mode */ 572 /* get WM8350 revision and config mode */
579 ret = wm8350->read_dev(wm8350, WM8350_RESET_ID, sizeof(id1), &id1); 573 ret = regmap_read(wm8350->regmap, WM8350_RESET_ID, &id1);
580 if (ret != 0) { 574 if (ret != 0) {
581 dev_err(wm8350->dev, "Failed to read ID: %d\n", ret); 575 dev_err(wm8350->dev, "Failed to read ID: %d\n", ret);
582 goto err; 576 goto err;
583 } 577 }
584 578
585 ret = wm8350->read_dev(wm8350, WM8350_ID, sizeof(id2), &id2); 579 ret = regmap_read(wm8350->regmap, WM8350_ID, &id2);
586 if (ret != 0) { 580 if (ret != 0) {
587 dev_err(wm8350->dev, "Failed to read ID: %d\n", ret); 581 dev_err(wm8350->dev, "Failed to read ID: %d\n", ret);
588 goto err; 582 goto err;
589 } 583 }
590 584
591 ret = wm8350->read_dev(wm8350, WM8350_REVISION, sizeof(mask_rev), 585 ret = regmap_read(wm8350->regmap, WM8350_REVISION, &mask_rev);
592 &mask_rev);
593 if (ret != 0) { 586 if (ret != 0) {
594 dev_err(wm8350->dev, "Failed to read revision: %d\n", ret); 587 dev_err(wm8350->dev, "Failed to read revision: %d\n", ret);
595 goto err; 588 goto err;
596 } 589 }
597 590
598 id1 = be16_to_cpu(id1);
599 id2 = be16_to_cpu(id2);
600 mask_rev = be16_to_cpu(mask_rev);
601
602 if (id1 != 0x6143) { 591 if (id1 != 0x6143) {
603 dev_err(wm8350->dev, 592 dev_err(wm8350->dev,
604 "Device with ID %x is not a WM8350\n", id1); 593 "Device with ID %x is not a WM8350\n", id1);
diff --git a/drivers/mfd/wm8350-i2c.c b/drivers/mfd/wm8350-i2c.c
index d955faaf27c4..271589f8e8e3 100644
--- a/drivers/mfd/wm8350-i2c.c
+++ b/drivers/mfd/wm8350-i2c.c
@@ -15,47 +15,18 @@
15 15
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/moduleparam.h> 17#include <linux/moduleparam.h>
18#include <linux/err.h>
18#include <linux/init.h> 19#include <linux/init.h>
19#include <linux/i2c.h> 20#include <linux/i2c.h>
20#include <linux/platform_device.h> 21#include <linux/platform_device.h>
21#include <linux/mfd/wm8350/core.h> 22#include <linux/mfd/wm8350/core.h>
23#include <linux/regmap.h>
22#include <linux/slab.h> 24#include <linux/slab.h>
23 25
24static int wm8350_i2c_read_device(struct wm8350 *wm8350, char reg, 26static const struct regmap_config wm8350_regmap = {
25 int bytes, void *dest) 27 .reg_bits = 8,
26{ 28 .val_bits = 16,
27 int ret; 29};
28
29 ret = i2c_master_send(wm8350->i2c_client, &reg, 1);
30 if (ret < 0)
31 return ret;
32 ret = i2c_master_recv(wm8350->i2c_client, dest, bytes);
33 if (ret < 0)
34 return ret;
35 if (ret != bytes)
36 return -EIO;
37 return 0;
38}
39
40static int wm8350_i2c_write_device(struct wm8350 *wm8350, char reg,
41 int bytes, void *src)
42{
43 /* we add 1 byte for device register */
44 u8 msg[(WM8350_MAX_REGISTER << 1) + 1];
45 int ret;
46
47 if (bytes > ((WM8350_MAX_REGISTER << 1) + 1))
48 return -EINVAL;
49
50 msg[0] = reg;
51 memcpy(&msg[1], src, bytes);
52 ret = i2c_master_send(wm8350->i2c_client, msg, bytes + 1);
53 if (ret < 0)
54 return ret;
55 if (ret != bytes + 1)
56 return -EIO;
57 return 0;
58}
59 30
60static int wm8350_i2c_probe(struct i2c_client *i2c, 31static int wm8350_i2c_probe(struct i2c_client *i2c,
61 const struct i2c_device_id *id) 32 const struct i2c_device_id *id)
@@ -67,11 +38,16 @@ static int wm8350_i2c_probe(struct i2c_client *i2c,
67 if (wm8350 == NULL) 38 if (wm8350 == NULL)
68 return -ENOMEM; 39 return -ENOMEM;
69 40
41 wm8350->regmap = devm_regmap_init_i2c(i2c, &wm8350_regmap);
42 if (IS_ERR(wm8350->regmap)) {
43 ret = PTR_ERR(wm8350->regmap);
44 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
45 ret);
46 return ret;
47 }
48
70 i2c_set_clientdata(i2c, wm8350); 49 i2c_set_clientdata(i2c, wm8350);
71 wm8350->dev = &i2c->dev; 50 wm8350->dev = &i2c->dev;
72 wm8350->i2c_client = i2c;
73 wm8350->read_dev = wm8350_i2c_read_device;
74 wm8350->write_dev = wm8350_i2c_write_device;
75 51
76 ret = wm8350_device_init(wm8350, i2c->irq, i2c->dev.platform_data); 52 ret = wm8350_device_init(wm8350, i2c->irq, i2c->dev.platform_data);
77 if (ret < 0) 53 if (ret < 0)
@@ -80,6 +56,7 @@ static int wm8350_i2c_probe(struct i2c_client *i2c,
80 return ret; 56 return ret;
81 57
82err: 58err:
59 regmap_exit(wm8350->regmap);
83 return ret; 60 return ret;
84} 61}
85 62
diff --git a/include/linux/mfd/wm8350/core.h b/include/linux/mfd/wm8350/core.h
index 98fcc977e82b..9192b6404a73 100644
--- a/include/linux/mfd/wm8350/core.h
+++ b/include/linux/mfd/wm8350/core.h
@@ -602,6 +602,7 @@ extern const u16 wm8352_mode2_defaults[];
602extern const u16 wm8352_mode3_defaults[]; 602extern const u16 wm8352_mode3_defaults[];
603 603
604struct wm8350; 604struct wm8350;
605struct regmap;
605 606
606struct wm8350_hwmon { 607struct wm8350_hwmon {
607 struct platform_device *pdev; 608 struct platform_device *pdev;
@@ -612,13 +613,7 @@ struct wm8350 {
612 struct device *dev; 613 struct device *dev;
613 614
614 /* device IO */ 615 /* device IO */
615 union { 616 struct regmap *regmap;
616 struct i2c_client *i2c_client;
617 struct spi_device *spi_device;
618 };
619 int (*read_dev)(struct wm8350 *wm8350, char reg, int size, void *dest);
620 int (*write_dev)(struct wm8350 *wm8350, char reg, int size,
621 void *src);
622 u16 *reg_cache; 617 u16 *reg_cache;
623 618
624 struct mutex auxadc_mutex; 619 struct mutex auxadc_mutex;