diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-05-07 05:03:21 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2012-05-07 05:32:08 -0400 |
commit | b7b142d9fc056e98e6fdef82dca3e87067517340 (patch) | |
tree | b7ec58d3c576080cdf94435f9d227bf6496b8150 | |
parent | ce7e4e11221dd7fbe82c8ad28d1875b0dfa20de4 (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.c | 31 | ||||
-rw-r--r-- | drivers/mfd/wm8350-i2c.c | 53 | ||||
-rw-r--r-- | include/linux/mfd/wm8350/core.h | 9 |
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 | ||
24 | static int wm8350_i2c_read_device(struct wm8350 *wm8350, char reg, | 26 | static 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, ®, 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 | |||
40 | static 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 | ||
60 | static int wm8350_i2c_probe(struct i2c_client *i2c, | 31 | static 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 | ||
82 | err: | 58 | err: |
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[]; | |||
602 | extern const u16 wm8352_mode3_defaults[]; | 602 | extern const u16 wm8352_mode3_defaults[]; |
603 | 603 | ||
604 | struct wm8350; | 604 | struct wm8350; |
605 | struct regmap; | ||
605 | 606 | ||
606 | struct wm8350_hwmon { | 607 | struct 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; |