.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) ST-Ericsson SA 2012 |
---|
3 | 4 | * |
---|
4 | 5 | * Battery temperature driver for AB8500 |
---|
5 | 6 | * |
---|
6 | | - * License Terms: GNU General Public License v2 |
---|
7 | 7 | * Author: |
---|
8 | 8 | * Johan Palsson <johan.palsson@stericsson.com> |
---|
9 | 9 | * Karl Komierowski <karl.komierowski@stericsson.com> |
---|
.. | .. |
---|
26 | 26 | #include <linux/mfd/abx500.h> |
---|
27 | 27 | #include <linux/mfd/abx500/ab8500.h> |
---|
28 | 28 | #include <linux/mfd/abx500/ab8500-bm.h> |
---|
29 | | -#include <linux/mfd/abx500/ab8500-gpadc.h> |
---|
| 29 | +#include <linux/iio/consumer.h> |
---|
30 | 30 | |
---|
31 | 31 | #define VTVOUT_V 1800 |
---|
32 | 32 | |
---|
.. | .. |
---|
79 | 79 | * @bat_temp: Dispatched battery temperature in degree Celsius |
---|
80 | 80 | * @prev_bat_temp Last measured battery temperature in degree Celsius |
---|
81 | 81 | * @parent: Pointer to the struct ab8500 |
---|
82 | | - * @gpadc: Pointer to the struct gpadc |
---|
| 82 | + * @adc_btemp_ball: ADC channel for the battery ball temperature |
---|
| 83 | + * @adc_bat_ctrl: ADC channel for the battery control |
---|
83 | 84 | * @fg: Pointer to the struct fg |
---|
84 | 85 | * @bm: Platform specific battery management information |
---|
85 | 86 | * @btemp_psy: Structure for BTEMP specific battery properties |
---|
.. | .. |
---|
96 | 97 | int bat_temp; |
---|
97 | 98 | int prev_bat_temp; |
---|
98 | 99 | struct ab8500 *parent; |
---|
99 | | - struct ab8500_gpadc *gpadc; |
---|
| 100 | + struct iio_channel *btemp_ball; |
---|
| 101 | + struct iio_channel *bat_ctrl; |
---|
100 | 102 | struct ab8500_fg *fg; |
---|
101 | 103 | struct abx500_bm_data *bm; |
---|
102 | 104 | struct power_supply *btemp_psy; |
---|
.. | .. |
---|
177 | 179 | */ |
---|
178 | 180 | static int ab8500_btemp_read_batctrl_voltage(struct ab8500_btemp *di) |
---|
179 | 181 | { |
---|
180 | | - int vbtemp; |
---|
| 182 | + int vbtemp, ret; |
---|
181 | 183 | static int prev; |
---|
182 | 184 | |
---|
183 | | - vbtemp = ab8500_gpadc_convert(di->gpadc, BAT_CTRL); |
---|
184 | | - if (vbtemp < 0) { |
---|
| 185 | + ret = iio_read_channel_processed(di->bat_ctrl, &vbtemp); |
---|
| 186 | + if (ret < 0) { |
---|
185 | 187 | dev_err(di->dev, |
---|
186 | | - "%s gpadc conversion failed, using previous value", |
---|
| 188 | + "%s ADC conversion failed, using previous value", |
---|
187 | 189 | __func__); |
---|
188 | 190 | return prev; |
---|
189 | 191 | } |
---|
.. | .. |
---|
455 | 457 | */ |
---|
456 | 458 | static int ab8500_btemp_measure_temp(struct ab8500_btemp *di) |
---|
457 | 459 | { |
---|
458 | | - int temp; |
---|
| 460 | + int temp, ret; |
---|
459 | 461 | static int prev; |
---|
460 | 462 | int rbat, rntc, vntc; |
---|
461 | 463 | u8 id; |
---|
.. | .. |
---|
480 | 482 | di->bm->bat_type[id].r_to_t_tbl, |
---|
481 | 483 | di->bm->bat_type[id].n_temp_tbl_elements, rbat); |
---|
482 | 484 | } else { |
---|
483 | | - vntc = ab8500_gpadc_convert(di->gpadc, BTEMP_BALL); |
---|
484 | | - if (vntc < 0) { |
---|
| 485 | + ret = iio_read_channel_processed(di->btemp_ball, &vntc); |
---|
| 486 | + if (ret < 0) { |
---|
485 | 487 | dev_err(di->dev, |
---|
486 | | - "%s gpadc conversion failed," |
---|
| 488 | + "%s ADC conversion failed," |
---|
487 | 489 | " using previous value\n", __func__); |
---|
488 | 490 | return prev; |
---|
489 | 491 | } |
---|
.. | .. |
---|
919 | 921 | */ |
---|
920 | 922 | static void ab8500_btemp_external_power_changed(struct power_supply *psy) |
---|
921 | 923 | { |
---|
922 | | - struct ab8500_btemp *di = power_supply_get_drvdata(psy); |
---|
923 | | - |
---|
924 | | - class_for_each_device(power_supply_class, NULL, |
---|
925 | | - di->btemp_psy, ab8500_btemp_get_ext_psy_data); |
---|
| 924 | + class_for_each_device(power_supply_class, NULL, psy, |
---|
| 925 | + ab8500_btemp_get_ext_psy_data); |
---|
926 | 926 | } |
---|
927 | 927 | |
---|
928 | 928 | /* ab8500 btemp driver interrupts and their respective isr */ |
---|
.. | .. |
---|
1024 | 1024 | /* get parent data */ |
---|
1025 | 1025 | di->dev = &pdev->dev; |
---|
1026 | 1026 | di->parent = dev_get_drvdata(pdev->dev.parent); |
---|
1027 | | - di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); |
---|
| 1027 | + |
---|
| 1028 | + /* Get ADC channels */ |
---|
| 1029 | + di->btemp_ball = devm_iio_channel_get(&pdev->dev, "btemp_ball"); |
---|
| 1030 | + if (IS_ERR(di->btemp_ball)) { |
---|
| 1031 | + if (PTR_ERR(di->btemp_ball) == -ENODEV) |
---|
| 1032 | + return -EPROBE_DEFER; |
---|
| 1033 | + dev_err(&pdev->dev, "failed to get BTEMP BALL ADC channel\n"); |
---|
| 1034 | + return PTR_ERR(di->btemp_ball); |
---|
| 1035 | + } |
---|
| 1036 | + di->bat_ctrl = devm_iio_channel_get(&pdev->dev, "bat_ctrl"); |
---|
| 1037 | + if (IS_ERR(di->bat_ctrl)) { |
---|
| 1038 | + if (PTR_ERR(di->bat_ctrl) == -ENODEV) |
---|
| 1039 | + return -EPROBE_DEFER; |
---|
| 1040 | + dev_err(&pdev->dev, "failed to get BAT CTRL ADC channel\n"); |
---|
| 1041 | + return PTR_ERR(di->bat_ctrl); |
---|
| 1042 | + } |
---|
1028 | 1043 | |
---|
1029 | 1044 | di->initialized = false; |
---|
1030 | 1045 | |
---|
.. | .. |
---|
1082 | 1097 | /* Register interrupts */ |
---|
1083 | 1098 | for (i = 0; i < ARRAY_SIZE(ab8500_btemp_irq); i++) { |
---|
1084 | 1099 | irq = platform_get_irq_byname(pdev, ab8500_btemp_irq[i].name); |
---|
| 1100 | + if (irq < 0) { |
---|
| 1101 | + ret = irq; |
---|
| 1102 | + goto free_irq; |
---|
| 1103 | + } |
---|
| 1104 | + |
---|
1085 | 1105 | ret = request_threaded_irq(irq, NULL, ab8500_btemp_irq[i].isr, |
---|
1086 | 1106 | IRQF_SHARED | IRQF_NO_SUSPEND, |
---|
1087 | 1107 | ab8500_btemp_irq[i].name, di); |
---|
.. | .. |
---|
1104 | 1124 | return ret; |
---|
1105 | 1125 | |
---|
1106 | 1126 | free_irq: |
---|
1107 | | - power_supply_unregister(di->btemp_psy); |
---|
1108 | | - |
---|
1109 | 1127 | /* We also have to free all successfully registered irqs */ |
---|
1110 | 1128 | for (i = i - 1; i >= 0; i--) { |
---|
1111 | 1129 | irq = platform_get_irq_byname(pdev, ab8500_btemp_irq[i].name); |
---|
1112 | 1130 | free_irq(irq, di); |
---|
1113 | 1131 | } |
---|
| 1132 | + |
---|
| 1133 | + power_supply_unregister(di->btemp_psy); |
---|
1114 | 1134 | free_btemp_wq: |
---|
1115 | 1135 | destroy_workqueue(di->btemp_wq); |
---|
1116 | 1136 | return ret; |
---|