aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-10-15 00:56:23 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-15 00:56:23 -0400
commit50fa86172bec2769979b5eb0cd1a244391ae4bb0 (patch)
tree5fd4949b031e1362af8b226d6372da2604de13ff /drivers/mfd
parent6b0490816671b2f4126a99998c9bf3c8c0472de2 (diff)
parent7881c64716f3a7d60b325ed0ad4d15f49b474a43 (diff)
Merge tag 'for-v3.18' of git://git.infradead.org/battery-2.6
Pull power supply and reset updates from Sebastian Reichel: - Initial support for the following chips * max77836 (charger) * max14577 (charger) * bq27742 (battery gauge) * ltc2952 (poweroff) * stih416 (restart) * syscon-reboot (restart) * gpio-restart (restart) - cleanup of power supply core - misc fixes in power supply and reset drivers * tag 'for-v3.18' of git://git.infradead.org/battery-2.6: (48 commits) power: ab8500_fg: Fix build warning Documentation: charger: max14577: Update the date of introducing ABI power: reset: corrections for simple syscon reboot driver Documentation: power: reset: Add documentation for generic SYSCON reboot driver power: reset: Add generic SYSCON register mapped reset bq27x00_battery: Fix flag reading for bq27742 power: reset: use restart_notifier mechanism for msm-poweroff power: Add simple gpio-restart driver power: reset: st: Provide DT bindings for ST's Power Reset driver power: reset: Add restart functionality for STiH41x platforms power: charger-manager: Fix NULL pointer exception with missing cm-fuel-gauge power: max14577: Fix circular config SYSFS dependency power: gpio-charger: do not use gpio value directly power: max8925: Use of_get_child_by_name power: max8925: Fix NULL ptr dereference on memory allocation failure bq27x00_battery: Add support to bq27742 Documentation: charger: max14577: Document exported sysfs entry devicetree: mfd: max14577: Add device tree bindings document power: max17040: Add ID for MAX77836 Fuel Gauge block charger: max14577: Configure battery-dependent settings from DTS and sysfs ... Conflicts: drivers/power/reset/Kconfig drivers/power/reset/Makefile
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/max14577.c100
1 files changed, 99 insertions, 1 deletions
diff --git a/drivers/mfd/max14577.c b/drivers/mfd/max14577.c
index 4a5e885383f8..b8af263be594 100644
--- a/drivers/mfd/max14577.c
+++ b/drivers/mfd/max14577.c
@@ -26,6 +26,87 @@
26#include <linux/mfd/max14577.h> 26#include <linux/mfd/max14577.h>
27#include <linux/mfd/max14577-private.h> 27#include <linux/mfd/max14577-private.h>
28 28
29/*
30 * Table of valid charger currents for different Maxim chipsets.
31 * It is placed here because it is used by both charger and regulator driver.
32 */
33const struct maxim_charger_current maxim_charger_currents[] = {
34 [MAXIM_DEVICE_TYPE_UNKNOWN] = { 0, 0, 0, 0 },
35 [MAXIM_DEVICE_TYPE_MAX14577] = {
36 .min = MAX14577_CHARGER_CURRENT_LIMIT_MIN,
37 .high_start = MAX14577_CHARGER_CURRENT_LIMIT_HIGH_START,
38 .high_step = MAX14577_CHARGER_CURRENT_LIMIT_HIGH_STEP,
39 .max = MAX14577_CHARGER_CURRENT_LIMIT_MAX,
40 },
41 [MAXIM_DEVICE_TYPE_MAX77836] = {
42 .min = MAX77836_CHARGER_CURRENT_LIMIT_MIN,
43 .high_start = MAX77836_CHARGER_CURRENT_LIMIT_HIGH_START,
44 .high_step = MAX77836_CHARGER_CURRENT_LIMIT_HIGH_STEP,
45 .max = MAX77836_CHARGER_CURRENT_LIMIT_MAX,
46 },
47};
48EXPORT_SYMBOL_GPL(maxim_charger_currents);
49
50/*
51 * maxim_charger_calc_reg_current - Calculate register value for current
52 * @limits: constraints for charger, matching the MBCICHWRC register
53 * @min_ua: minimal requested current, micro Amps
54 * @max_ua: maximum requested current, micro Amps
55 * @dst: destination to store calculated register value
56 *
57 * Calculates the value of MBCICHWRC (Fast Battery Charge Current) register
58 * for given current and stores it under pointed 'dst'. The stored value
59 * combines low bit (MBCICHWRCL) and high bits (MBCICHWRCH). It is also
60 * properly shifted.
61 *
62 * The calculated register value matches the current which:
63 * - is always between <limits.min, limits.max>;
64 * - is always less or equal to max_ua;
65 * - is the highest possible value;
66 * - may be lower than min_ua.
67 *
68 * On success returns 0. On error returns -EINVAL (requested min/max current
69 * is outside of given charger limits) and 'dst' is not set.
70 */
71int maxim_charger_calc_reg_current(const struct maxim_charger_current *limits,
72 unsigned int min_ua, unsigned int max_ua, u8 *dst)
73{
74 unsigned int current_bits = 0xf;
75
76 if (min_ua > max_ua)
77 return -EINVAL;
78
79 if (min_ua > limits->max || max_ua < limits->min)
80 return -EINVAL;
81
82 if (max_ua < limits->high_start) {
83 /*
84 * Less than high_start, so set the minimal current
85 * (turn Low Bit off, 0 as high bits).
86 */
87 *dst = 0x0;
88 return 0;
89 }
90
91 /* max_ua is in range: <high_start, infinite>, cut it to limits.max */
92 max_ua = min(limits->max, max_ua);
93 max_ua -= limits->high_start;
94 /*
95 * There is no risk of overflow 'max_ua' here because:
96 * - max_ua >= limits.high_start
97 * - BUILD_BUG checks that 'limits' are: max >= high_start + high_step
98 */
99 current_bits = max_ua / limits->high_step;
100
101 /* Turn Low Bit on (use range <limits.high_start, limits.max>) ... */
102 *dst = 0x1 << CHGCTRL4_MBCICHWRCL_SHIFT;
103 /* and set proper High Bits */
104 *dst |= current_bits << CHGCTRL4_MBCICHWRCH_SHIFT;
105
106 return 0;
107}
108EXPORT_SYMBOL_GPL(maxim_charger_calc_reg_current);
109
29static const struct mfd_cell max14577_devs[] = { 110static const struct mfd_cell max14577_devs[] = {
30 { 111 {
31 .name = "max14577-muic", 112 .name = "max14577-muic",
@@ -35,7 +116,10 @@ static const struct mfd_cell max14577_devs[] = {
35 .name = "max14577-regulator", 116 .name = "max14577-regulator",
36 .of_compatible = "maxim,max14577-regulator", 117 .of_compatible = "maxim,max14577-regulator",
37 }, 118 },
38 { .name = "max14577-charger", }, 119 {
120 .name = "max14577-charger",
121 .of_compatible = "maxim,max14577-charger",
122 },
39}; 123};
40 124
41static const struct mfd_cell max77836_devs[] = { 125static const struct mfd_cell max77836_devs[] = {
@@ -463,6 +547,20 @@ static int __init max14577_i2c_init(void)
463 BUILD_BUG_ON(ARRAY_SIZE(max14577_i2c_id) != MAXIM_DEVICE_TYPE_NUM); 547 BUILD_BUG_ON(ARRAY_SIZE(max14577_i2c_id) != MAXIM_DEVICE_TYPE_NUM);
464 BUILD_BUG_ON(ARRAY_SIZE(max14577_dt_match) != MAXIM_DEVICE_TYPE_NUM); 548 BUILD_BUG_ON(ARRAY_SIZE(max14577_dt_match) != MAXIM_DEVICE_TYPE_NUM);
465 549
550 /* Valid charger current values must be provided for each chipset */
551 BUILD_BUG_ON(ARRAY_SIZE(maxim_charger_currents) != MAXIM_DEVICE_TYPE_NUM);
552
553 /* Check for valid values for charger */
554 BUILD_BUG_ON(MAX14577_CHARGER_CURRENT_LIMIT_HIGH_START +
555 MAX14577_CHARGER_CURRENT_LIMIT_HIGH_STEP * 0xf !=
556 MAX14577_CHARGER_CURRENT_LIMIT_MAX);
557 BUILD_BUG_ON(MAX14577_CHARGER_CURRENT_LIMIT_HIGH_STEP == 0);
558
559 BUILD_BUG_ON(MAX77836_CHARGER_CURRENT_LIMIT_HIGH_START +
560 MAX77836_CHARGER_CURRENT_LIMIT_HIGH_STEP * 0xf !=
561 MAX77836_CHARGER_CURRENT_LIMIT_MAX);
562 BUILD_BUG_ON(MAX77836_CHARGER_CURRENT_LIMIT_HIGH_STEP == 0);
563
466 return i2c_add_driver(&max14577_i2c_driver); 564 return i2c_add_driver(&max14577_i2c_driver);
467} 565}
468subsys_initcall(max14577_i2c_init); 566subsys_initcall(max14577_i2c_init);