diff options
Diffstat (limited to 'drivers/mfd')
-rw-r--r-- | drivers/mfd/wm8350-core.c | 29 | ||||
-rw-r--r-- | drivers/mfd/wm8350-i2c.c | 5 | ||||
-rw-r--r-- | drivers/mfd/wm8350-regmap.c | 56 |
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 | */ |
296 | int wm8350_reg_lock(struct wm8350 *wm8350) | 293 | int 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(®_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(®_lock_mutex); | ||
308 | |||
307 | return ret; | 309 | return ret; |
308 | } | 310 | } |
309 | EXPORT_SYMBOL_GPL(wm8350_reg_lock); | 311 | EXPORT_SYMBOL_GPL(wm8350_reg_lock); |
@@ -319,15 +321,20 @@ EXPORT_SYMBOL_GPL(wm8350_reg_lock); | |||
319 | */ | 321 | */ |
320 | int wm8350_reg_unlock(struct wm8350 *wm8350) | 322 | int 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(®_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(®_lock_mutex); | ||
337 | |||
331 | return ret; | 338 | return ret; |
332 | } | 339 | } |
333 | EXPORT_SYMBOL_GPL(wm8350_reg_unlock); | 340 | EXPORT_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 | ||
26 | static const struct regmap_config wm8350_regmap = { | ||
27 | .reg_bits = 8, | ||
28 | .val_bits = 16, | ||
29 | }; | ||
30 | |||
31 | static int wm8350_i2c_probe(struct i2c_client *i2c, | 26 | static 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 | |||
3437 | static bool wm8350_readable(struct device *dev, unsigned int reg) | ||
3438 | { | ||
3439 | return wm8350_reg_io_map[reg].readable; | ||
3440 | } | ||
3441 | |||
3442 | static 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 | |||
3457 | static bool wm8350_volatile(struct device *dev, unsigned int reg) | ||
3458 | { | ||
3459 | return wm8350_reg_io_map[reg].vol; | ||
3460 | } | ||
3461 | |||
3462 | static 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 | |||
3480 | const 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 | }; | ||