diff options
author | Hans de Goede <hdegoede@redhat.com> | 2017-04-14 14:32:49 -0400 |
---|---|---|
committer | Sebastian Reichel <sre@kernel.org> | 2017-05-01 06:37:25 -0400 |
commit | 917362135b8a5c0680acf08807e9fc6179eb6c79 (patch) | |
tree | bb20f3213be8e5e6aad36ab8ab333b7c1f1d85b8 | |
parent | 2814913c3136b41084a896c90062bd9b87672dff (diff) |
power: supply: max17042_battery: Add default platform_data fallback data
Some x86 machines use a max17047 fuel-gauge and x86 might be missing
platform_data if not provided by SFI.
This commit adds default platform_data as fallback option so that the
driver can work on boards where no platform_data is provided.
Since not all boards have a thermistor hooked up, set temp_min to 0 and
change the health checks from temp <= temp_min to temp < temp_min to
not trigger on such boards (where temp reads 0).
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
-rw-r--r-- | drivers/power/supply/max17042_battery.c | 60 | ||||
-rw-r--r-- | include/linux/power/max17042_battery.h | 6 |
2 files changed, 58 insertions, 8 deletions
diff --git a/drivers/power/supply/max17042_battery.c b/drivers/power/supply/max17042_battery.c index a51b2965cd5c..f0ff6e880ff2 100644 --- a/drivers/power/supply/max17042_battery.c +++ b/drivers/power/supply/max17042_battery.c | |||
@@ -150,12 +150,12 @@ static int max17042_get_battery_health(struct max17042_chip *chip, int *health) | |||
150 | if (ret < 0) | 150 | if (ret < 0) |
151 | goto health_error; | 151 | goto health_error; |
152 | 152 | ||
153 | if (temp <= chip->pdata->temp_min) { | 153 | if (temp < chip->pdata->temp_min) { |
154 | *health = POWER_SUPPLY_HEALTH_COLD; | 154 | *health = POWER_SUPPLY_HEALTH_COLD; |
155 | goto out; | 155 | goto out; |
156 | } | 156 | } |
157 | 157 | ||
158 | if (temp >= chip->pdata->temp_max) { | 158 | if (temp > chip->pdata->temp_max) { |
159 | *health = POWER_SUPPLY_HEALTH_OVERHEAT; | 159 | *health = POWER_SUPPLY_HEALTH_OVERHEAT; |
160 | goto out; | 160 | goto out; |
161 | } | 161 | } |
@@ -772,8 +772,9 @@ static void max17042_init_worker(struct work_struct *work) | |||
772 | 772 | ||
773 | #ifdef CONFIG_OF | 773 | #ifdef CONFIG_OF |
774 | static struct max17042_platform_data * | 774 | static struct max17042_platform_data * |
775 | max17042_get_pdata(struct device *dev) | 775 | max17042_get_pdata(struct max17042_chip *chip) |
776 | { | 776 | { |
777 | struct device *dev = &chip->client->dev; | ||
777 | struct device_node *np = dev->of_node; | 778 | struct device_node *np = dev->of_node; |
778 | u32 prop; | 779 | u32 prop; |
779 | struct max17042_platform_data *pdata; | 780 | struct max17042_platform_data *pdata; |
@@ -806,10 +807,55 @@ max17042_get_pdata(struct device *dev) | |||
806 | return pdata; | 807 | return pdata; |
807 | } | 808 | } |
808 | #else | 809 | #else |
810 | static struct max17042_reg_data max17047_default_pdata_init_regs[] = { | ||
811 | /* | ||
812 | * Some firmwares do not set FullSOCThr, Enable End-of-Charge Detection | ||
813 | * when the voltage FG reports 95%, as recommended in the datasheet. | ||
814 | */ | ||
815 | { MAX17047_FullSOCThr, MAX17042_BATTERY_FULL << 8 }, | ||
816 | }; | ||
817 | |||
809 | static struct max17042_platform_data * | 818 | static struct max17042_platform_data * |
810 | max17042_get_pdata(struct device *dev) | 819 | max17042_get_pdata(struct max17042_chip *chip) |
811 | { | 820 | { |
812 | return dev->platform_data; | 821 | struct device *dev = &chip->client->dev; |
822 | struct max17042_platform_data *pdata; | ||
823 | int ret, misc_cfg; | ||
824 | |||
825 | if (dev->platform_data) | ||
826 | return dev->platform_data; | ||
827 | |||
828 | /* | ||
829 | * The MAX17047 gets used on x86 where we might not have pdata, assume | ||
830 | * the firmware will already have initialized the fuel-gauge and provide | ||
831 | * default values for the non init bits to make things work. | ||
832 | */ | ||
833 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | ||
834 | if (!pdata) | ||
835 | return pdata; | ||
836 | |||
837 | if (chip->chip_type != MAXIM_DEVICE_TYPE_MAX17042) { | ||
838 | pdata->init_data = max17047_default_pdata_init_regs; | ||
839 | pdata->num_init_data = | ||
840 | ARRAY_SIZE(max17047_default_pdata_init_regs); | ||
841 | } | ||
842 | |||
843 | ret = regmap_read(chip->regmap, MAX17042_MiscCFG, &misc_cfg); | ||
844 | if (ret < 0) | ||
845 | return NULL; | ||
846 | |||
847 | /* If bits 0-1 are set to 3 then only Voltage readings are used */ | ||
848 | if ((misc_cfg & 0x3) == 0x3) | ||
849 | pdata->enable_current_sense = false; | ||
850 | else | ||
851 | pdata->enable_current_sense = true; | ||
852 | |||
853 | pdata->vmin = MAX17042_DEFAULT_VMIN; | ||
854 | pdata->vmax = MAX17042_DEFAULT_VMAX; | ||
855 | pdata->temp_min = MAX17042_DEFAULT_TEMP_MIN; | ||
856 | pdata->temp_max = MAX17042_DEFAULT_TEMP_MAX; | ||
857 | |||
858 | return pdata; | ||
813 | } | 859 | } |
814 | #endif | 860 | #endif |
815 | 861 | ||
@@ -858,20 +904,20 @@ static int max17042_probe(struct i2c_client *client, | |||
858 | return -ENOMEM; | 904 | return -ENOMEM; |
859 | 905 | ||
860 | chip->client = client; | 906 | chip->client = client; |
907 | chip->chip_type = id->driver_data; | ||
861 | chip->regmap = devm_regmap_init_i2c(client, &max17042_regmap_config); | 908 | chip->regmap = devm_regmap_init_i2c(client, &max17042_regmap_config); |
862 | if (IS_ERR(chip->regmap)) { | 909 | if (IS_ERR(chip->regmap)) { |
863 | dev_err(&client->dev, "Failed to initialize regmap\n"); | 910 | dev_err(&client->dev, "Failed to initialize regmap\n"); |
864 | return -EINVAL; | 911 | return -EINVAL; |
865 | } | 912 | } |
866 | 913 | ||
867 | chip->pdata = max17042_get_pdata(&client->dev); | 914 | chip->pdata = max17042_get_pdata(chip); |
868 | if (!chip->pdata) { | 915 | if (!chip->pdata) { |
869 | dev_err(&client->dev, "no platform data provided\n"); | 916 | dev_err(&client->dev, "no platform data provided\n"); |
870 | return -EINVAL; | 917 | return -EINVAL; |
871 | } | 918 | } |
872 | 919 | ||
873 | i2c_set_clientdata(client, chip); | 920 | i2c_set_clientdata(client, chip); |
874 | chip->chip_type = id->driver_data; | ||
875 | psy_cfg.drv_data = chip; | 921 | psy_cfg.drv_data = chip; |
876 | 922 | ||
877 | /* When current is not measured, | 923 | /* When current is not measured, |
diff --git a/include/linux/power/max17042_battery.h b/include/linux/power/max17042_battery.h index 522757ac9cd4..3489fb0f9099 100644 --- a/include/linux/power/max17042_battery.h +++ b/include/linux/power/max17042_battery.h | |||
@@ -24,8 +24,12 @@ | |||
24 | #define __MAX17042_BATTERY_H_ | 24 | #define __MAX17042_BATTERY_H_ |
25 | 25 | ||
26 | #define MAX17042_STATUS_BattAbsent (1 << 3) | 26 | #define MAX17042_STATUS_BattAbsent (1 << 3) |
27 | #define MAX17042_BATTERY_FULL (100) | 27 | #define MAX17042_BATTERY_FULL (95) /* Recommend. FullSOCThr value */ |
28 | #define MAX17042_DEFAULT_SNS_RESISTOR (10000) | 28 | #define MAX17042_DEFAULT_SNS_RESISTOR (10000) |
29 | #define MAX17042_DEFAULT_VMIN (3000) | ||
30 | #define MAX17042_DEFAULT_VMAX (4500) /* LiHV cell max */ | ||
31 | #define MAX17042_DEFAULT_TEMP_MIN (0) /* For sys without temp sensor */ | ||
32 | #define MAX17042_DEFAULT_TEMP_MAX (700) /* 70 degrees Celcius */ | ||
29 | 33 | ||
30 | #define MAX17042_CHARACTERIZATION_DATA_SIZE 48 | 34 | #define MAX17042_CHARACTERIZATION_DATA_SIZE 48 |
31 | 35 | ||