aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2012-06-03 08:37:22 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2012-07-08 18:16:10 -0400
commit52b461b86a9f6c7a86bdcb858e1bbef089fbe6a0 (patch)
tree9c839b3ce945fb75249d0be0cbde503b44334351 /drivers/mfd
parentb0ab907d325f99054eb2700a8f8c50776ebfeaf9 (diff)
mfd: Add regmap cache support for wm8350
Use the most simple possible transformation on the existing code so keep the table sitting around, further patches in this series will delete the existing cache code - the main purpose of this patch is to ensure that we always have a cache for bisection. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/wm8350-core.c29
-rw-r--r--drivers/mfd/wm8350-i2c.c5
-rw-r--r--drivers/mfd/wm8350-regmap.c56
3 files changed, 74 insertions, 16 deletions
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c
index 8a9b11ca076a..fadcbbe9e2ba 100644
--- a/drivers/mfd/wm8350-core.c
+++ b/drivers/mfd/wm8350-core.c
@@ -32,9 +32,6 @@
32#include <linux/mfd/wm8350/supply.h> 32#include <linux/mfd/wm8350/supply.h>
33#include <linux/mfd/wm8350/wdt.h> 33#include <linux/mfd/wm8350/wdt.h>
34 34
35#define WM8350_UNLOCK_KEY 0x0013
36#define WM8350_LOCK_KEY 0x0000
37
38#define WM8350_CLOCK_CONTROL_1 0x28 35#define WM8350_CLOCK_CONTROL_1 0x28
39#define WM8350_AIF_TEST 0x74 36#define WM8350_AIF_TEST 0x74
40 37
@@ -295,15 +292,20 @@ EXPORT_SYMBOL_GPL(wm8350_block_write);
295 */ 292 */
296int wm8350_reg_lock(struct wm8350 *wm8350) 293int wm8350_reg_lock(struct wm8350 *wm8350)
297{ 294{
298 u16 key = WM8350_LOCK_KEY;
299 int ret; 295 int ret;
300 296
297 mutex_lock(&reg_lock_mutex);
298
301 ldbg(__func__); 299 ldbg(__func__);
302 mutex_lock(&io_mutex); 300
303 ret = wm8350_write(wm8350, WM8350_SECURITY, 1, &key); 301 ret = wm8350_reg_write(wm8350, WM8350_SECURITY, WM8350_LOCK_KEY);
304 if (ret) 302 if (ret)
305 dev_err(wm8350->dev, "lock failed\n"); 303 dev_err(wm8350->dev, "lock failed\n");
306 mutex_unlock(&io_mutex); 304
305 wm8350->unlocked = false;
306
307 mutex_unlock(&reg_lock_mutex);
308
307 return ret; 309 return ret;
308} 310}
309EXPORT_SYMBOL_GPL(wm8350_reg_lock); 311EXPORT_SYMBOL_GPL(wm8350_reg_lock);
@@ -319,15 +321,20 @@ EXPORT_SYMBOL_GPL(wm8350_reg_lock);
319 */ 321 */
320int wm8350_reg_unlock(struct wm8350 *wm8350) 322int wm8350_reg_unlock(struct wm8350 *wm8350)
321{ 323{
322 u16 key = WM8350_UNLOCK_KEY;
323 int ret; 324 int ret;
324 325
326 mutex_lock(&reg_lock_mutex);
327
325 ldbg(__func__); 328 ldbg(__func__);
326 mutex_lock(&io_mutex); 329
327 ret = wm8350_write(wm8350, WM8350_SECURITY, 1, &key); 330 ret = wm8350_reg_write(wm8350, WM8350_SECURITY, WM8350_UNLOCK_KEY);
328 if (ret) 331 if (ret)
329 dev_err(wm8350->dev, "unlock failed\n"); 332 dev_err(wm8350->dev, "unlock failed\n");
330 mutex_unlock(&io_mutex); 333
334 wm8350->unlocked = true;
335
336 mutex_unlock(&reg_lock_mutex);
337
331 return ret; 338 return ret;
332} 339}
333EXPORT_SYMBOL_GPL(wm8350_reg_unlock); 340EXPORT_SYMBOL_GPL(wm8350_reg_unlock);
diff --git a/drivers/mfd/wm8350-i2c.c b/drivers/mfd/wm8350-i2c.c
index a68aceb4e48c..2e57101c8d3d 100644
--- a/drivers/mfd/wm8350-i2c.c
+++ b/drivers/mfd/wm8350-i2c.c
@@ -23,11 +23,6 @@
23#include <linux/regmap.h> 23#include <linux/regmap.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25 25
26static const struct regmap_config wm8350_regmap = {
27 .reg_bits = 8,
28 .val_bits = 16,
29};
30
31static int wm8350_i2c_probe(struct i2c_client *i2c, 26static int wm8350_i2c_probe(struct i2c_client *i2c,
32 const struct i2c_device_id *id) 27 const struct i2c_device_id *id)
33{ 28{
diff --git a/drivers/mfd/wm8350-regmap.c b/drivers/mfd/wm8350-regmap.c
index e965139e5cd5..7974cadaa422 100644
--- a/drivers/mfd/wm8350-regmap.c
+++ b/drivers/mfd/wm8350-regmap.c
@@ -3433,3 +3433,59 @@ const struct wm8350_reg_access wm8350_reg_io_map[] = {
3433 { 0x0000, 0x0000, 0x0000 }, /* R254 */ 3433 { 0x0000, 0x0000, 0x0000 }, /* R254 */
3434 { 0x0000, 0x0000, 0x0000 }, /* R255 */ 3434 { 0x0000, 0x0000, 0x0000 }, /* R255 */
3435}; 3435};
3436
3437static bool wm8350_readable(struct device *dev, unsigned int reg)
3438{
3439 return wm8350_reg_io_map[reg].readable;
3440}
3441
3442static bool wm8350_writeable(struct device *dev, unsigned int reg)
3443{
3444 struct wm8350 *wm8350 = dev_get_drvdata(dev);
3445
3446 if (!wm8350->unlocked) {
3447 if ((reg >= WM8350_GPIO_FUNCTION_SELECT_1 &&
3448 reg <= WM8350_GPIO_FUNCTION_SELECT_4) ||
3449 (reg >= WM8350_BATTERY_CHARGER_CONTROL_1 &&
3450 reg <= WM8350_BATTERY_CHARGER_CONTROL_3))
3451 return false;
3452 }
3453
3454 return wm8350_reg_io_map[reg].writable;
3455}
3456
3457static bool wm8350_volatile(struct device *dev, unsigned int reg)
3458{
3459 return wm8350_reg_io_map[reg].vol;
3460}
3461
3462static bool wm8350_precious(struct device *dev, unsigned int reg)
3463{
3464 switch (reg) {
3465 case WM8350_SYSTEM_INTERRUPTS:
3466 case WM8350_INT_STATUS_1:
3467 case WM8350_INT_STATUS_2:
3468 case WM8350_POWER_UP_INT_STATUS:
3469 case WM8350_UNDER_VOLTAGE_INT_STATUS:
3470 case WM8350_OVER_CURRENT_INT_STATUS:
3471 case WM8350_GPIO_INT_STATUS:
3472 case WM8350_COMPARATOR_INT_STATUS:
3473 return true;
3474
3475 default:
3476 return false;
3477 }
3478}
3479
3480const struct regmap_config wm8350_regmap = {
3481 .reg_bits = 8,
3482 .val_bits = 16,
3483
3484 .cache_type = REGCACHE_RBTREE,
3485
3486 .max_register = WM8350_MAX_REGISTER,
3487 .readable_reg = wm8350_readable,
3488 .writeable_reg = wm8350_writeable,
3489 .volatile_reg = wm8350_volatile,
3490 .precious_reg = wm8350_precious,
3491};