- Fix kerneldoc format errors for Rockchip, Mediatek and Uniphier
(Randy Dunlap) - Add the missing 'qcom,adc-tm7' compatible string in the dt-bindings (Krzysztof Kozlowski) - Improve the calibration routine by relying on the nvmem to read the values and provide a set of fixes for the QCom tsens driver (Dmitry Baryshkov) - Remove the duplicate interrupt setting routine in the QCom tsens driver (Daniel Lezcano) - Fix a wrong loop condition in the i.MX SC thermal driver and add the iMX8QM sensors (Viorel Suman) - Fix header inclusion asm-generic.h by asm.h for the qcom-spmi-adc-tm5 driver (Andy Shevchenko) - Use the devm_platform_get_and_ioremap_resource() combo function in all the drivers where the conversion applies (Ye Xingchen) - Replace a literal mask by an existing corresponding macro (Yangtao Li) - Add support for MT7986 and MT7981 (Daniel Golle) - Use thermal_zone_get_crit_temp() for the Armada thermal driver (Daniel Lezcano) -----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEGn3N4YVz0WNVyHskqDIjiipP6E8FAmPSo/wACgkQqDIjiipP 6E8jPAf/dSGd92V/BEbPDNL3OvhW7duX1g05HLwnjSLo4r2W/I+YFsmLkaJ81iPj E/gC29jHw6TAQN9DrEMRnjmHGH8SBPrphfZMM7Sbh3pgzTPGW5tXQln8ysbh+JUr 0Aj4O6sA5mvcjd7r7u5JITGUHzZCm3L4Gv9bzr6O8M425u3di1PlI8XMsdaKBy5q N4zYR8yFCgbgM3ujjy/J4fYWRRTcYQ9kExa/OxvMDtZS4shBK34VN9IVt3z/W+Vs zNxKRynUZcVYddEZwYcBV+aTVAyFGLr5s5y6dzPo33h4M+Rl6reNE86el28fglu0 diZK79mef3KtV8Dn6lw9r+Fd/6heHw== =ZJEq -----END PGP SIGNATURE----- Merge tag 'thermal-v6.3-rc1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/thermal/linux into thermal-next Pull thermal control material for 6.3-rc1 from Daniel Lezcano: "- Fix kerneldoc format errors for Rockchip, Mediatek and Uniphier (Randy Dunlap) - Add the missing 'qcom,adc-tm7' compatible string in the dt-bindings (Krzysztof Kozlowski) - Improve the calibration routine by relying on the nvmem to read the values and provide a set of fixes for the QCom tsens driver (Dmitry Baryshkov) - Remove the duplicate interrupt setting routine in the QCom tsens driver (Daniel Lezcano) - Fix a wrong loop condition in the i.MX SC thermal driver and add the iMX8QM sensors (Viorel Suman) - Fix header inclusion asm-generic.h by asm.h for the qcom-spmi-adc-tm5 driver (Andy Shevchenko) - Use the devm_platform_get_and_ioremap_resource() combo function in all the drivers where the conversion applies (Ye Xingchen) - Replace a literal mask by an existing corresponding macro (Yangtao Li) - Add support for MT7986 and MT7981 (Daniel Golle) - Use thermal_zone_get_crit_temp() for the Armada thermal driver (Daniel Lezcano)" * tag 'thermal-v6.3-rc1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/thermal/linux: (35 commits) thermal/drivers/armada: Use the thermal_zone_get_crit_temp() thermal/drivers/mtk: Add support for MT7986 and MT7981 thermal/drivers/mtk: Use function pointer for raw_to_mcelsius thermal/drivers/sun8i: Convert to use macro thermal/drivers/spear: Use devm_platform_get_and_ioremap_resource() thermal/drivers/kirkwood: Use devm_platform_get_and_ioremap_resource() thermal/drivers/thermal_mmio: Use devm_platform_get_and_ioremap_resource() thermal/drivers/rockchip: Use devm_platform_get_and_ioremap_resource() thermal/drivers/mtk_thermal: Use devm_platform_get_and_ioremap_resource() thermal/drivers/armada: Use devm_platform_get_and_ioremap_resource() thermal/drivers/dove: Use devm_platform_get_and_ioremap_resource() thermal/drivers/bcm2835: Use devm_platform_get_and_ioremap_resource() thermal/drivers/brcmstb_thermal: Use devm_platform_get_and_ioremap_resource() thermal/drivers/qcom-spmi-adc-tm5: Use asm intead of asm-generic thermal/drivers/imx_sc_thermal: Add iMX8QM sensors thermal/drivers/imx_sc_thermal: Fix the loop condition thermal/drivers/qcom: Remove duplicate set next trip point interrupt code thermal/drivers/tsens: Drop single-cell code for msm8976/msm8956 thermal/drivers/tsens: Drop single-cell code for msm8939 thermal/drivers/tsens: Drop single-cell code for mdm9607 ...
This commit is contained in:
Коммит
02be605946
|
@ -13,6 +13,7 @@ properties:
|
|||
enum:
|
||||
- qcom,spmi-adc-tm5
|
||||
- qcom,spmi-adc-tm5-gen2
|
||||
- qcom,adc-tm7 # Incomplete / subject to change
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
@ -37,6 +37,7 @@ properties:
|
|||
- description: v1 of TSENS
|
||||
items:
|
||||
- enum:
|
||||
- qcom,msm8956-tsens
|
||||
- qcom,msm8976-tsens
|
||||
- qcom,qcs404-tsens
|
||||
- const: qcom,tsens-v1
|
||||
|
@ -80,18 +81,120 @@ properties:
|
|||
maxItems: 2
|
||||
|
||||
nvmem-cells:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
description:
|
||||
Reference to an nvmem node for the calibration data
|
||||
oneOf:
|
||||
- minItems: 1
|
||||
maxItems: 2
|
||||
description:
|
||||
Reference to an nvmem node for the calibration data
|
||||
- minItems: 5
|
||||
maxItems: 35
|
||||
description: |
|
||||
Reference to nvmem cells for the calibration mode, two calibration
|
||||
bases and two cells per each sensor
|
||||
# special case for msm8974 / apq8084
|
||||
- maxItems: 51
|
||||
description: |
|
||||
Reference to nvmem cells for the calibration mode, two calibration
|
||||
bases and two cells per each sensor, main and backup copies, plus use_backup cell
|
||||
|
||||
nvmem-cell-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: calib
|
||||
- enum:
|
||||
- calib_backup
|
||||
- calib_sel
|
||||
oneOf:
|
||||
- minItems: 1
|
||||
items:
|
||||
- const: calib
|
||||
- enum:
|
||||
- calib_backup
|
||||
- calib_sel
|
||||
- minItems: 5
|
||||
items:
|
||||
- const: mode
|
||||
- const: base1
|
||||
- const: base2
|
||||
- pattern: '^s[0-9]+_p1$'
|
||||
- pattern: '^s[0-9]+_p2$'
|
||||
- pattern: '^s[0-9]+_p1$'
|
||||
- pattern: '^s[0-9]+_p2$'
|
||||
- pattern: '^s[0-9]+_p1$'
|
||||
- pattern: '^s[0-9]+_p2$'
|
||||
- pattern: '^s[0-9]+_p1$'
|
||||
- pattern: '^s[0-9]+_p2$'
|
||||
- pattern: '^s[0-9]+_p1$'
|
||||
- pattern: '^s[0-9]+_p2$'
|
||||
- pattern: '^s[0-9]+_p1$'
|
||||
- pattern: '^s[0-9]+_p2$'
|
||||
- pattern: '^s[0-9]+_p1$'
|
||||
- pattern: '^s[0-9]+_p2$'
|
||||
- pattern: '^s[0-9]+_p1$'
|
||||
- pattern: '^s[0-9]+_p2$'
|
||||
- pattern: '^s[0-9]+_p1$'
|
||||
- pattern: '^s[0-9]+_p2$'
|
||||
- pattern: '^s[0-9]+_p1$'
|
||||
- pattern: '^s[0-9]+_p2$'
|
||||
- pattern: '^s[0-9]+_p1$'
|
||||
- pattern: '^s[0-9]+_p2$'
|
||||
- pattern: '^s[0-9]+_p1$'
|
||||
- pattern: '^s[0-9]+_p2$'
|
||||
- pattern: '^s[0-9]+_p1$'
|
||||
- pattern: '^s[0-9]+_p2$'
|
||||
- pattern: '^s[0-9]+_p1$'
|
||||
- pattern: '^s[0-9]+_p2$'
|
||||
- pattern: '^s[0-9]+_p1$'
|
||||
- pattern: '^s[0-9]+_p2$'
|
||||
- pattern: '^s[0-9]+_p1$'
|
||||
- pattern: '^s[0-9]+_p2$'
|
||||
# special case for msm8974 / apq8084
|
||||
- items:
|
||||
- const: mode
|
||||
- const: base1
|
||||
- const: base2
|
||||
- const: use_backup
|
||||
- const: mode_backup
|
||||
- const: base1_backup
|
||||
- const: base2_backup
|
||||
- const: s0_p1
|
||||
- const: s0_p2
|
||||
- const: s1_p1
|
||||
- const: s1_p2
|
||||
- const: s2_p1
|
||||
- const: s2_p2
|
||||
- const: s3_p1
|
||||
- const: s3_p2
|
||||
- const: s4_p1
|
||||
- const: s4_p2
|
||||
- const: s5_p1
|
||||
- const: s5_p2
|
||||
- const: s6_p1
|
||||
- const: s6_p2
|
||||
- const: s7_p1
|
||||
- const: s7_p2
|
||||
- const: s8_p1
|
||||
- const: s8_p2
|
||||
- const: s9_p1
|
||||
- const: s9_p2
|
||||
- const: s10_p1
|
||||
- const: s10_p2
|
||||
- const: s0_p1_backup
|
||||
- const: s0_p2_backup
|
||||
- const: s1_p1_backup
|
||||
- const: s1_p2_backup
|
||||
- const: s2_p1_backup
|
||||
- const: s2_p2_backup
|
||||
- const: s3_p1_backup
|
||||
- const: s3_p2_backup
|
||||
- const: s4_p1_backup
|
||||
- const: s4_p2_backup
|
||||
- const: s5_p1_backup
|
||||
- const: s5_p2_backup
|
||||
- const: s6_p1_backup
|
||||
- const: s6_p2_backup
|
||||
- const: s7_p1_backup
|
||||
- const: s7_p2_backup
|
||||
- const: s8_p1_backup
|
||||
- const: s8_p2_backup
|
||||
- const: s9_p1_backup
|
||||
- const: s9_p2_backup
|
||||
- const: s10_p1_backup
|
||||
- const: s10_p2_backup
|
||||
|
||||
"#qcom,sensors":
|
||||
description:
|
||||
|
@ -220,6 +323,36 @@ examples:
|
|||
};
|
||||
};
|
||||
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
// Example 1 (new calbiration data: for pre v1 IP):
|
||||
thermal-sensor@900000 {
|
||||
compatible = "qcom,msm8916-tsens", "qcom,tsens-v0_1";
|
||||
reg = <0x4a9000 0x1000>, /* TM */
|
||||
<0x4a8000 0x1000>; /* SROT */
|
||||
|
||||
nvmem-cells = <&tsens_mode>,
|
||||
<&tsens_base1>, <&tsens_base2>,
|
||||
<&tsens_s0_p1>, <&tsens_s0_p2>,
|
||||
<&tsens_s1_p1>, <&tsens_s1_p2>,
|
||||
<&tsens_s2_p1>, <&tsens_s2_p2>,
|
||||
<&tsens_s4_p1>, <&tsens_s4_p2>,
|
||||
<&tsens_s5_p1>, <&tsens_s5_p2>;
|
||||
nvmem-cell-names = "mode",
|
||||
"base1", "base2",
|
||||
"s0_p1", "s0_p2",
|
||||
"s1_p1", "s1_p2",
|
||||
"s2_p1", "s2_p2",
|
||||
"s4_p1", "s4_p2",
|
||||
"s5_p1", "s5_p2";
|
||||
|
||||
interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "uplow";
|
||||
|
||||
#qcom,sensors = <5>;
|
||||
#thermal-sensor-cells = <1>;
|
||||
};
|
||||
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
// Example 1 (legacy: for pre v1 IP):
|
||||
|
|
|
@ -709,12 +709,10 @@ static int armada_thermal_probe_legacy(struct platform_device *pdev,
|
|||
struct armada_thermal_priv *priv)
|
||||
{
|
||||
struct armada_thermal_data *data = priv->data;
|
||||
struct resource *res;
|
||||
void __iomem *base;
|
||||
|
||||
/* First memory region points towards the status register */
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(&pdev->dev, res);
|
||||
base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
|
@ -784,34 +782,26 @@ static int armada_configure_overheat_int(struct armada_thermal_priv *priv,
|
|||
int sensor_id)
|
||||
{
|
||||
/* Retrieve the critical trip point to enable the overheat interrupt */
|
||||
struct thermal_trip trip;
|
||||
int temperature;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < thermal_zone_get_num_trips(tz); i++) {
|
||||
ret = thermal_zone_get_crit_temp(tz, &temperature);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = thermal_zone_get_trip(tz, i, &trip);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = armada_select_channel(priv, sensor_id);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (trip.type != THERMAL_TRIP_CRITICAL)
|
||||
continue;
|
||||
/*
|
||||
* A critical temperature does not have a hysteresis
|
||||
*/
|
||||
armada_set_overheat_thresholds(priv, temperature, 0);
|
||||
priv->overheat_sensor = tz;
|
||||
priv->interrupt_source = sensor_id;
|
||||
armada_enable_overheat_interrupt(priv);
|
||||
|
||||
ret = armada_select_channel(priv, sensor_id);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
armada_set_overheat_thresholds(priv, trip.temperature,
|
||||
trip.hysteresis);
|
||||
priv->overheat_sensor = tz;
|
||||
priv->interrupt_source = sensor_id;
|
||||
|
||||
armada_enable_overheat_interrupt(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int armada_thermal_probe(struct platform_device *pdev)
|
||||
|
|
|
@ -167,7 +167,6 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
|
|||
const struct of_device_id *match;
|
||||
struct thermal_zone_device *tz;
|
||||
struct bcm2835_thermal_data *data;
|
||||
struct resource *res;
|
||||
int err = 0;
|
||||
u32 val;
|
||||
unsigned long rate;
|
||||
|
@ -181,8 +180,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
|
|||
if (!match)
|
||||
return -EINVAL;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
data->regs = devm_ioremap_resource(&pdev->dev, res);
|
||||
data->regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
|
||||
if (IS_ERR(data->regs)) {
|
||||
err = PTR_ERR(data->regs);
|
||||
return err;
|
||||
|
|
|
@ -321,7 +321,6 @@ static int brcmstb_thermal_probe(struct platform_device *pdev)
|
|||
const struct thermal_zone_device_ops *of_ops;
|
||||
struct thermal_zone_device *thermal;
|
||||
struct brcmstb_thermal_priv *priv;
|
||||
struct resource *res;
|
||||
int irq, ret;
|
||||
|
||||
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
|
@ -332,8 +331,7 @@ static int brcmstb_thermal_probe(struct platform_device *pdev)
|
|||
if (!priv->temp_params)
|
||||
return -EINVAL;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
priv->tmon_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
priv->tmon_base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
|
||||
if (IS_ERR(priv->tmon_base))
|
||||
return PTR_ERR(priv->tmon_base);
|
||||
|
||||
|
|
|
@ -122,20 +122,17 @@ static int dove_thermal_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct thermal_zone_device *thermal = NULL;
|
||||
struct dove_thermal_priv *priv;
|
||||
struct resource *res;
|
||||
int ret;
|
||||
|
||||
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
priv->sensor = devm_ioremap_resource(&pdev->dev, res);
|
||||
priv->sensor = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
|
||||
if (IS_ERR(priv->sensor))
|
||||
return PTR_ERR(priv->sensor);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
priv->control = devm_ioremap_resource(&pdev->dev, res);
|
||||
priv->control = devm_platform_get_and_ioremap_resource(pdev, 1, NULL);
|
||||
if (IS_ERR(priv->control))
|
||||
return PTR_ERR(priv->control);
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ static int imx_sc_thermal_probe(struct platform_device *pdev)
|
|||
if (!resource_id)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; resource_id[i] > 0; i++) {
|
||||
for (i = 0; resource_id[i] >= 0; i++) {
|
||||
|
||||
sensor = devm_kzalloc(&pdev->dev, sizeof(*sensor), GFP_KERNEL);
|
||||
if (!sensor)
|
||||
|
@ -127,7 +127,11 @@ static int imx_sc_thermal_probe(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int imx_sc_sensors[] = { IMX_SC_R_SYSTEM, IMX_SC_R_PMIC_0, -1 };
|
||||
static const int imx_sc_sensors[] = {
|
||||
IMX_SC_R_SYSTEM, IMX_SC_R_PMIC_0,
|
||||
IMX_SC_R_AP_0, IMX_SC_R_AP_1,
|
||||
IMX_SC_R_GPU_0_PID0, IMX_SC_R_GPU_1_PID0,
|
||||
IMX_SC_R_DRC_0, -1 };
|
||||
|
||||
static const struct of_device_id imx_sc_thermal_table[] = {
|
||||
{ .compatible = "fsl,imx-sc-thermal", .data = imx_sc_sensors },
|
||||
|
|
|
@ -64,15 +64,13 @@ static int kirkwood_thermal_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct thermal_zone_device *thermal = NULL;
|
||||
struct kirkwood_thermal_priv *priv;
|
||||
struct resource *res;
|
||||
int ret;
|
||||
|
||||
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
priv->sensor = devm_ioremap_resource(&pdev->dev, res);
|
||||
priv->sensor = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
|
||||
if (IS_ERR(priv->sensor))
|
||||
return PTR_ERR(priv->sensor);
|
||||
|
||||
|
|
|
@ -150,6 +150,20 @@
|
|||
#define CALIB_BUF1_VALID_V2(x) (((x) >> 4) & 0x1)
|
||||
#define CALIB_BUF1_O_SLOPE_SIGN_V2(x) (((x) >> 3) & 0x1)
|
||||
|
||||
/*
|
||||
* Layout of the fuses providing the calibration data
|
||||
* These macros can be used for MT7981 and MT7986.
|
||||
*/
|
||||
#define CALIB_BUF0_ADC_GE_V3(x) (((x) >> 0) & 0x3ff)
|
||||
#define CALIB_BUF0_DEGC_CALI_V3(x) (((x) >> 20) & 0x3f)
|
||||
#define CALIB_BUF0_O_SLOPE_V3(x) (((x) >> 26) & 0x3f)
|
||||
#define CALIB_BUF1_VTS_TS1_V3(x) (((x) >> 0) & 0x1ff)
|
||||
#define CALIB_BUF1_VTS_TS2_V3(x) (((x) >> 21) & 0x1ff)
|
||||
#define CALIB_BUF1_VTS_TSABB_V3(x) (((x) >> 9) & 0x1ff)
|
||||
#define CALIB_BUF1_VALID_V3(x) (((x) >> 18) & 0x1)
|
||||
#define CALIB_BUF1_O_SLOPE_SIGN_V3(x) (((x) >> 19) & 0x1)
|
||||
#define CALIB_BUF1_ID_V3(x) (((x) >> 20) & 0x1)
|
||||
|
||||
enum {
|
||||
VTS1,
|
||||
VTS2,
|
||||
|
@ -163,6 +177,7 @@ enum {
|
|||
enum mtk_thermal_version {
|
||||
MTK_THERMAL_V1 = 1,
|
||||
MTK_THERMAL_V2,
|
||||
MTK_THERMAL_V3,
|
||||
};
|
||||
|
||||
/* MT2701 thermal sensors */
|
||||
|
@ -245,6 +260,27 @@ enum mtk_thermal_version {
|
|||
/* The calibration coefficient of sensor */
|
||||
#define MT8183_CALIBRATION 153
|
||||
|
||||
/* AUXADC channel 11 is used for the temperature sensors */
|
||||
#define MT7986_TEMP_AUXADC_CHANNEL 11
|
||||
|
||||
/* The total number of temperature sensors in the MT7986 */
|
||||
#define MT7986_NUM_SENSORS 1
|
||||
|
||||
/* The number of banks in the MT7986 */
|
||||
#define MT7986_NUM_ZONES 1
|
||||
|
||||
/* The number of sensing points per bank */
|
||||
#define MT7986_NUM_SENSORS_PER_ZONE 1
|
||||
|
||||
/* MT7986 thermal sensors */
|
||||
#define MT7986_TS1 0
|
||||
|
||||
/* The number of controller in the MT7986 */
|
||||
#define MT7986_NUM_CONTROLLER 1
|
||||
|
||||
/* The calibration coefficient of sensor */
|
||||
#define MT7986_CALIBRATION 165
|
||||
|
||||
struct mtk_thermal;
|
||||
|
||||
struct thermal_bank_cfg {
|
||||
|
@ -292,6 +328,8 @@ struct mtk_thermal {
|
|||
|
||||
const struct mtk_thermal_data *conf;
|
||||
struct mtk_thermal_bank banks[MAX_NUM_ZONES];
|
||||
|
||||
int (*raw_to_mcelsius)(struct mtk_thermal *mt, int sensno, s32 raw);
|
||||
};
|
||||
|
||||
/* MT8183 thermal sensor data */
|
||||
|
@ -386,6 +424,14 @@ static const int mt7622_mux_values[MT7622_NUM_SENSORS] = { 0, };
|
|||
static const int mt7622_vts_index[MT7622_NUM_SENSORS] = { VTS1 };
|
||||
static const int mt7622_tc_offset[MT7622_NUM_CONTROLLER] = { 0x0, };
|
||||
|
||||
/* MT7986 thermal sensor data */
|
||||
static const int mt7986_bank_data[MT7986_NUM_SENSORS] = { MT7986_TS1, };
|
||||
static const int mt7986_msr[MT7986_NUM_SENSORS_PER_ZONE] = { TEMP_MSR0, };
|
||||
static const int mt7986_adcpnp[MT7986_NUM_SENSORS_PER_ZONE] = { TEMP_ADCPNP0, };
|
||||
static const int mt7986_mux_values[MT7986_NUM_SENSORS] = { 0, };
|
||||
static const int mt7986_vts_index[MT7986_NUM_SENSORS] = { VTS1 };
|
||||
static const int mt7986_tc_offset[MT7986_NUM_CONTROLLER] = { 0x0, };
|
||||
|
||||
/*
|
||||
* The MT8173 thermal controller has four banks. Each bank can read up to
|
||||
* four temperature sensors simultaneously. The MT8173 has a total of 5
|
||||
|
@ -549,8 +595,32 @@ static const struct mtk_thermal_data mt8183_thermal_data = {
|
|||
.version = MTK_THERMAL_V1,
|
||||
};
|
||||
|
||||
/*
|
||||
* MT7986 uses AUXADC Channel 11 for raw data access.
|
||||
*/
|
||||
static const struct mtk_thermal_data mt7986_thermal_data = {
|
||||
.auxadc_channel = MT7986_TEMP_AUXADC_CHANNEL,
|
||||
.num_banks = MT7986_NUM_ZONES,
|
||||
.num_sensors = MT7986_NUM_SENSORS,
|
||||
.vts_index = mt7986_vts_index,
|
||||
.cali_val = MT7986_CALIBRATION,
|
||||
.num_controller = MT7986_NUM_CONTROLLER,
|
||||
.controller_offset = mt7986_tc_offset,
|
||||
.need_switch_bank = true,
|
||||
.bank_data = {
|
||||
{
|
||||
.num_sensors = 1,
|
||||
.sensors = mt7986_bank_data,
|
||||
},
|
||||
},
|
||||
.msr = mt7986_msr,
|
||||
.adcpnp = mt7986_adcpnp,
|
||||
.sensor_mux_values = mt7986_mux_values,
|
||||
.version = MTK_THERMAL_V3,
|
||||
};
|
||||
|
||||
/**
|
||||
* raw_to_mcelsius - convert a raw ADC value to mcelsius
|
||||
* raw_to_mcelsius_v1 - convert a raw ADC value to mcelsius
|
||||
* @mt: The thermal controller
|
||||
* @sensno: sensor number
|
||||
* @raw: raw ADC value
|
||||
|
@ -603,6 +673,22 @@ static int raw_to_mcelsius_v2(struct mtk_thermal *mt, int sensno, s32 raw)
|
|||
return (format_2 - tmp) * 100;
|
||||
}
|
||||
|
||||
static int raw_to_mcelsius_v3(struct mtk_thermal *mt, int sensno, s32 raw)
|
||||
{
|
||||
s32 tmp;
|
||||
|
||||
if (raw == 0)
|
||||
return 0;
|
||||
|
||||
raw &= 0xfff;
|
||||
tmp = 100000 * 15 / 16 * 10000;
|
||||
tmp /= 4096 - 512 + mt->adc_ge;
|
||||
tmp /= 1490;
|
||||
tmp *= raw - mt->vts[sensno] - 2900;
|
||||
|
||||
return mt->degc_cali * 500 - tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* mtk_thermal_get_bank - get bank
|
||||
* @bank: The bank
|
||||
|
@ -656,13 +742,9 @@ static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank)
|
|||
for (i = 0; i < conf->bank_data[bank->id].num_sensors; i++) {
|
||||
raw = readl(mt->thermal_base + conf->msr[i]);
|
||||
|
||||
if (mt->conf->version == MTK_THERMAL_V1) {
|
||||
temp = raw_to_mcelsius_v1(
|
||||
mt, conf->bank_data[bank->id].sensors[i], raw);
|
||||
} else {
|
||||
temp = raw_to_mcelsius_v2(
|
||||
mt, conf->bank_data[bank->id].sensors[i], raw);
|
||||
}
|
||||
temp = mt->raw_to_mcelsius(
|
||||
mt, conf->bank_data[bank->id].sensors[i], raw);
|
||||
|
||||
|
||||
/*
|
||||
* The first read of a sensor often contains very high bogus
|
||||
|
@ -887,6 +969,25 @@ static int mtk_thermal_extract_efuse_v2(struct mtk_thermal *mt, u32 *buf)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_thermal_extract_efuse_v3(struct mtk_thermal *mt, u32 *buf)
|
||||
{
|
||||
if (!CALIB_BUF1_VALID_V3(buf[1]))
|
||||
return -EINVAL;
|
||||
|
||||
mt->adc_ge = CALIB_BUF0_ADC_GE_V3(buf[0]);
|
||||
mt->degc_cali = CALIB_BUF0_DEGC_CALI_V3(buf[0]);
|
||||
mt->o_slope = CALIB_BUF0_O_SLOPE_V3(buf[0]);
|
||||
mt->vts[VTS1] = CALIB_BUF1_VTS_TS1_V3(buf[1]);
|
||||
mt->vts[VTS2] = CALIB_BUF1_VTS_TS2_V3(buf[1]);
|
||||
mt->vts[VTSABB] = CALIB_BUF1_VTS_TSABB_V3(buf[1]);
|
||||
mt->o_slope_sign = CALIB_BUF1_O_SLOPE_SIGN_V3(buf[1]);
|
||||
|
||||
if (CALIB_BUF1_ID_V3(buf[1]) == 0)
|
||||
mt->o_slope = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_thermal_get_calibration_data(struct device *dev,
|
||||
struct mtk_thermal *mt)
|
||||
{
|
||||
|
@ -897,6 +998,7 @@ static int mtk_thermal_get_calibration_data(struct device *dev,
|
|||
|
||||
/* Start with default values */
|
||||
mt->adc_ge = 512;
|
||||
mt->adc_oe = 512;
|
||||
for (i = 0; i < mt->conf->num_sensors; i++)
|
||||
mt->vts[i] = 260;
|
||||
mt->degc_cali = 40;
|
||||
|
@ -922,10 +1024,20 @@ static int mtk_thermal_get_calibration_data(struct device *dev,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (mt->conf->version == MTK_THERMAL_V1)
|
||||
switch (mt->conf->version) {
|
||||
case MTK_THERMAL_V1:
|
||||
ret = mtk_thermal_extract_efuse_v1(mt, buf);
|
||||
else
|
||||
break;
|
||||
case MTK_THERMAL_V2:
|
||||
ret = mtk_thermal_extract_efuse_v2(mt, buf);
|
||||
break;
|
||||
case MTK_THERMAL_V3:
|
||||
ret = mtk_thermal_extract_efuse_v3(mt, buf);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
dev_info(dev, "Device not calibrated, using default calibration values\n");
|
||||
|
@ -955,6 +1067,10 @@ static const struct of_device_id mtk_thermal_of_match[] = {
|
|||
.compatible = "mediatek,mt7622-thermal",
|
||||
.data = (void *)&mt7622_thermal_data,
|
||||
},
|
||||
{
|
||||
.compatible = "mediatek,mt7986-thermal",
|
||||
.data = (void *)&mt7986_thermal_data,
|
||||
},
|
||||
{
|
||||
.compatible = "mediatek,mt8183-thermal",
|
||||
.data = (void *)&mt8183_thermal_data,
|
||||
|
@ -990,7 +1106,6 @@ static int mtk_thermal_probe(struct platform_device *pdev)
|
|||
int ret, i, ctrl_id;
|
||||
struct device_node *auxadc, *apmixedsys, *np = pdev->dev.of_node;
|
||||
struct mtk_thermal *mt;
|
||||
struct resource *res;
|
||||
u64 auxadc_phys_base, apmixed_phys_base;
|
||||
struct thermal_zone_device *tzdev;
|
||||
void __iomem *apmixed_base, *auxadc_base;
|
||||
|
@ -1009,8 +1124,7 @@ static int mtk_thermal_probe(struct platform_device *pdev)
|
|||
if (IS_ERR(mt->clk_auxadc))
|
||||
return PTR_ERR(mt->clk_auxadc);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
mt->thermal_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
mt->thermal_base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
|
||||
if (IS_ERR(mt->thermal_base))
|
||||
return PTR_ERR(mt->thermal_base);
|
||||
|
||||
|
@ -1070,11 +1184,18 @@ static int mtk_thermal_probe(struct platform_device *pdev)
|
|||
goto err_disable_clk_auxadc;
|
||||
}
|
||||
|
||||
if (mt->conf->version == MTK_THERMAL_V2) {
|
||||
if (mt->conf->version != MTK_THERMAL_V1) {
|
||||
mtk_thermal_turn_on_buffer(apmixed_base);
|
||||
mtk_thermal_release_periodic_ts(mt, auxadc_base);
|
||||
}
|
||||
|
||||
if (mt->conf->version == MTK_THERMAL_V1)
|
||||
mt->raw_to_mcelsius = raw_to_mcelsius_v1;
|
||||
else if (mt->conf->version == MTK_THERMAL_V2)
|
||||
mt->raw_to_mcelsius = raw_to_mcelsius_v2;
|
||||
else
|
||||
mt->raw_to_mcelsius = raw_to_mcelsius_v3;
|
||||
|
||||
for (ctrl_id = 0; ctrl_id < mt->conf->num_controller ; ctrl_id++)
|
||||
for (i = 0; i < mt->conf->num_banks; i++)
|
||||
mtk_thermal_init_bank(mt, i, apmixed_phys_base,
|
||||
|
|
|
@ -18,7 +18,8 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/thermal.h>
|
||||
#include <asm-generic/unaligned.h>
|
||||
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include "../thermal_hwmon.h"
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/nvmem-consumer.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include "tsens.h"
|
||||
|
||||
|
@ -15,220 +17,117 @@
|
|||
#define TM_Sn_STATUS_OFF 0x0030
|
||||
#define TM_TRDY_OFF 0x005c
|
||||
|
||||
/* eeprom layout data for 8916 */
|
||||
#define MSM8916_BASE0_MASK 0x0000007f
|
||||
#define MSM8916_BASE1_MASK 0xfe000000
|
||||
#define MSM8916_BASE0_SHIFT 0
|
||||
#define MSM8916_BASE1_SHIFT 25
|
||||
|
||||
#define MSM8916_S0_P1_MASK 0x00000f80
|
||||
#define MSM8916_S1_P1_MASK 0x003e0000
|
||||
#define MSM8916_S2_P1_MASK 0xf8000000
|
||||
#define MSM8916_S3_P1_MASK 0x000003e0
|
||||
#define MSM8916_S4_P1_MASK 0x000f8000
|
||||
|
||||
#define MSM8916_S0_P2_MASK 0x0001f000
|
||||
#define MSM8916_S1_P2_MASK 0x07c00000
|
||||
#define MSM8916_S2_P2_MASK 0x0000001f
|
||||
#define MSM8916_S3_P2_MASK 0x00007c00
|
||||
#define MSM8916_S4_P2_MASK 0x01f00000
|
||||
|
||||
#define MSM8916_S0_P1_SHIFT 7
|
||||
#define MSM8916_S1_P1_SHIFT 17
|
||||
#define MSM8916_S2_P1_SHIFT 27
|
||||
#define MSM8916_S3_P1_SHIFT 5
|
||||
#define MSM8916_S4_P1_SHIFT 15
|
||||
|
||||
#define MSM8916_S0_P2_SHIFT 12
|
||||
#define MSM8916_S1_P2_SHIFT 22
|
||||
#define MSM8916_S2_P2_SHIFT 0
|
||||
#define MSM8916_S3_P2_SHIFT 10
|
||||
#define MSM8916_S4_P2_SHIFT 20
|
||||
|
||||
#define MSM8916_CAL_SEL_MASK 0xe0000000
|
||||
#define MSM8916_CAL_SEL_SHIFT 29
|
||||
|
||||
/* eeprom layout data for 8939 */
|
||||
#define MSM8939_BASE0_MASK 0x000000ff
|
||||
#define MSM8939_BASE1_MASK 0xff000000
|
||||
#define MSM8939_BASE0_SHIFT 0
|
||||
#define MSM8939_BASE1_SHIFT 24
|
||||
|
||||
#define MSM8939_S0_P1_MASK 0x000001f8
|
||||
#define MSM8939_S1_P1_MASK 0x001f8000
|
||||
#define MSM8939_S2_P1_MASK_0_4 0xf8000000
|
||||
#define MSM8939_S2_P1_MASK_5 0x00000001
|
||||
#define MSM8939_S3_P1_MASK 0x00001f80
|
||||
#define MSM8939_S4_P1_MASK 0x01f80000
|
||||
#define MSM8939_S5_P1_MASK 0x00003f00
|
||||
#define MSM8939_S6_P1_MASK 0x03f00000
|
||||
#define MSM8939_S7_P1_MASK 0x0000003f
|
||||
#define MSM8939_S8_P1_MASK 0x0003f000
|
||||
#define MSM8939_S9_P1_MASK 0x07e00000
|
||||
|
||||
#define MSM8939_S0_P2_MASK 0x00007e00
|
||||
#define MSM8939_S1_P2_MASK 0x07e00000
|
||||
#define MSM8939_S2_P2_MASK 0x0000007e
|
||||
#define MSM8939_S3_P2_MASK 0x0007e000
|
||||
#define MSM8939_S4_P2_MASK 0x7e000000
|
||||
#define MSM8939_S5_P2_MASK 0x000fc000
|
||||
#define MSM8939_S6_P2_MASK 0xfc000000
|
||||
#define MSM8939_S7_P2_MASK 0x00000fc0
|
||||
#define MSM8939_S8_P2_MASK 0x00fc0000
|
||||
#define MSM8939_S9_P2_MASK_0_4 0xf8000000
|
||||
#define MSM8939_S9_P2_MASK_5 0x00002000
|
||||
|
||||
#define MSM8939_S0_P1_SHIFT 3
|
||||
#define MSM8939_S1_P1_SHIFT 15
|
||||
#define MSM8939_S2_P1_SHIFT_0_4 27
|
||||
#define MSM8939_S2_P1_SHIFT_5 0
|
||||
#define MSM8939_S3_P1_SHIFT 7
|
||||
#define MSM8939_S4_P1_SHIFT 19
|
||||
#define MSM8939_S5_P1_SHIFT 8
|
||||
#define MSM8939_S6_P1_SHIFT 20
|
||||
#define MSM8939_S7_P1_SHIFT 0
|
||||
#define MSM8939_S8_P1_SHIFT 12
|
||||
#define MSM8939_S9_P1_SHIFT 21
|
||||
|
||||
#define MSM8939_S0_P2_SHIFT 9
|
||||
#define MSM8939_S1_P2_SHIFT 21
|
||||
#define MSM8939_S2_P2_SHIFT 1
|
||||
#define MSM8939_S3_P2_SHIFT 13
|
||||
#define MSM8939_S4_P2_SHIFT 25
|
||||
#define MSM8939_S5_P2_SHIFT 14
|
||||
#define MSM8939_S6_P2_SHIFT 26
|
||||
#define MSM8939_S7_P2_SHIFT 6
|
||||
#define MSM8939_S8_P2_SHIFT 18
|
||||
#define MSM8939_S9_P2_SHIFT_0_4 27
|
||||
#define MSM8939_S9_P2_SHIFT_5 13
|
||||
|
||||
#define MSM8939_CAL_SEL_MASK 0x7
|
||||
#define MSM8939_CAL_SEL_SHIFT 0
|
||||
|
||||
/* eeprom layout data for 8974 */
|
||||
#define BASE1_MASK 0xff
|
||||
#define S0_P1_MASK 0x3f00
|
||||
#define S1_P1_MASK 0xfc000
|
||||
#define S2_P1_MASK 0x3f00000
|
||||
#define S3_P1_MASK 0xfc000000
|
||||
#define S4_P1_MASK 0x3f
|
||||
#define S5_P1_MASK 0xfc0
|
||||
#define S6_P1_MASK 0x3f000
|
||||
#define S7_P1_MASK 0xfc0000
|
||||
#define S8_P1_MASK 0x3f000000
|
||||
#define S8_P1_MASK_BKP 0x3f
|
||||
#define S9_P1_MASK 0x3f
|
||||
#define S9_P1_MASK_BKP 0xfc0
|
||||
#define S10_P1_MASK 0xfc0
|
||||
#define S10_P1_MASK_BKP 0x3f000
|
||||
#define CAL_SEL_0_1 0xc0000000
|
||||
#define CAL_SEL_2 0x40000000
|
||||
#define CAL_SEL_SHIFT 30
|
||||
#define CAL_SEL_SHIFT_2 28
|
||||
|
||||
#define S0_P1_SHIFT 8
|
||||
#define S1_P1_SHIFT 14
|
||||
#define S2_P1_SHIFT 20
|
||||
#define S3_P1_SHIFT 26
|
||||
#define S5_P1_SHIFT 6
|
||||
#define S6_P1_SHIFT 12
|
||||
#define S7_P1_SHIFT 18
|
||||
#define S8_P1_SHIFT 24
|
||||
#define S9_P1_BKP_SHIFT 6
|
||||
#define S10_P1_SHIFT 6
|
||||
#define S10_P1_BKP_SHIFT 12
|
||||
|
||||
#define BASE2_SHIFT 12
|
||||
#define BASE2_BKP_SHIFT 18
|
||||
#define S0_P2_SHIFT 20
|
||||
#define S0_P2_BKP_SHIFT 26
|
||||
#define S1_P2_SHIFT 26
|
||||
#define S2_P2_BKP_SHIFT 6
|
||||
#define S3_P2_SHIFT 6
|
||||
#define S3_P2_BKP_SHIFT 12
|
||||
#define S4_P2_SHIFT 12
|
||||
#define S4_P2_BKP_SHIFT 18
|
||||
#define S5_P2_SHIFT 18
|
||||
#define S5_P2_BKP_SHIFT 24
|
||||
#define S6_P2_SHIFT 24
|
||||
#define S7_P2_BKP_SHIFT 6
|
||||
#define S8_P2_SHIFT 6
|
||||
#define S8_P2_BKP_SHIFT 12
|
||||
#define S9_P2_SHIFT 12
|
||||
#define S9_P2_BKP_SHIFT 18
|
||||
#define S10_P2_SHIFT 18
|
||||
#define S10_P2_BKP_SHIFT 24
|
||||
|
||||
#define BASE2_MASK 0xff000
|
||||
#define BASE2_BKP_MASK 0xfc0000
|
||||
#define S0_P2_MASK 0x3f00000
|
||||
#define S0_P2_BKP_MASK 0xfc000000
|
||||
#define S1_P2_MASK 0xfc000000
|
||||
#define S1_P2_BKP_MASK 0x3f
|
||||
#define S2_P2_MASK 0x3f
|
||||
#define S2_P2_BKP_MASK 0xfc0
|
||||
#define S3_P2_MASK 0xfc0
|
||||
#define S3_P2_BKP_MASK 0x3f000
|
||||
#define S4_P2_MASK 0x3f000
|
||||
#define S4_P2_BKP_MASK 0xfc0000
|
||||
#define S5_P2_MASK 0xfc0000
|
||||
#define S5_P2_BKP_MASK 0x3f000000
|
||||
#define S6_P2_MASK 0x3f000000
|
||||
#define S6_P2_BKP_MASK 0x3f
|
||||
#define S7_P2_MASK 0x3f
|
||||
#define S7_P2_BKP_MASK 0xfc0
|
||||
#define S8_P2_MASK 0xfc0
|
||||
#define S8_P2_BKP_MASK 0x3f000
|
||||
#define S9_P2_MASK 0x3f000
|
||||
#define S9_P2_BKP_MASK 0xfc0000
|
||||
#define S10_P2_MASK 0xfc0000
|
||||
#define S10_P2_BKP_MASK 0x3f000000
|
||||
|
||||
/* extra data for 8974 */
|
||||
#define BKP_SEL 0x3
|
||||
#define BKP_REDUN_SEL 0xe0000000
|
||||
#define BKP_REDUN_SHIFT 29
|
||||
|
||||
#define BIT_APPEND 0x3
|
||||
|
||||
/* eeprom layout data for mdm9607 */
|
||||
#define MDM9607_BASE0_MASK 0x000000ff
|
||||
#define MDM9607_BASE1_MASK 0x000ff000
|
||||
#define MDM9607_BASE0_SHIFT 0
|
||||
#define MDM9607_BASE1_SHIFT 12
|
||||
struct tsens_legacy_calibration_format tsens_8916_nvmem = {
|
||||
.base_len = 7,
|
||||
.base_shift = 3,
|
||||
.sp_len = 5,
|
||||
.mode = { 0, 29, 1 },
|
||||
.invalid = { 0, 31, 1 },
|
||||
.base = { { 0, 0 }, { 1, 25 } },
|
||||
.sp = {
|
||||
{ { 0, 7 }, { 0, 12 } },
|
||||
{ { 0, 17 }, { 0, 22 } },
|
||||
{ { 0, 27 }, { 1, 0 } },
|
||||
{ { 1, 5 }, { 1, 10 } },
|
||||
{ { 1, 15 }, { 1, 20 } },
|
||||
},
|
||||
};
|
||||
|
||||
#define MDM9607_S0_P1_MASK 0x00003f00
|
||||
#define MDM9607_S1_P1_MASK 0x03f00000
|
||||
#define MDM9607_S2_P1_MASK 0x0000003f
|
||||
#define MDM9607_S3_P1_MASK 0x0003f000
|
||||
#define MDM9607_S4_P1_MASK 0x0000003f
|
||||
struct tsens_legacy_calibration_format tsens_8939_nvmem = {
|
||||
.base_len = 8,
|
||||
.base_shift = 2,
|
||||
.sp_len = 6,
|
||||
.mode = { 12, 0 },
|
||||
.invalid = { 12, 2 },
|
||||
.base = { { 0, 0 }, { 1, 24 } },
|
||||
.sp = {
|
||||
{ { 12, 3 }, { 12, 9 } },
|
||||
{ { 12, 15 }, { 12, 21 } },
|
||||
{ { 12, 27 }, { 13, 1 } },
|
||||
{ { 13, 7 }, { 13, 13 } },
|
||||
{ { 13, 19 }, { 13, 25 } },
|
||||
{ { 0, 8 }, { 0, 14 } },
|
||||
{ { 0, 20 }, { 0, 26 } },
|
||||
{ { 1, 0 }, { 1, 6 } },
|
||||
{ { 1, 12 }, { 1, 18 } },
|
||||
},
|
||||
};
|
||||
|
||||
#define MDM9607_S0_P2_MASK 0x000fc000
|
||||
#define MDM9607_S1_P2_MASK 0xfc000000
|
||||
#define MDM9607_S2_P2_MASK 0x00000fc0
|
||||
#define MDM9607_S3_P2_MASK 0x00fc0000
|
||||
#define MDM9607_S4_P2_MASK 0x00000fc0
|
||||
struct tsens_legacy_calibration_format tsens_8974_nvmem = {
|
||||
.base_len = 8,
|
||||
.base_shift = 2,
|
||||
.sp_len = 6,
|
||||
.mode = { 1, 30 },
|
||||
.invalid = { 3, 30 },
|
||||
.base = { { 0, 0 }, { 2, 12 } },
|
||||
.sp = {
|
||||
{ { 0, 8 }, { 2, 20 } },
|
||||
{ { 0, 14 }, { 2, 26 } },
|
||||
{ { 0, 20 }, { 3, 0 } },
|
||||
{ { 0, 26 }, { 3, 6 } },
|
||||
{ { 1, 0 }, { 3, 12 } },
|
||||
{ { 1, 6 }, { 3, 18 } },
|
||||
{ { 1, 12 }, { 3, 24 } },
|
||||
{ { 1, 18 }, { 4, 0 } },
|
||||
{ { 1, 24 }, { 4, 6 } },
|
||||
{ { 2, 0 }, { 4, 12 } },
|
||||
{ { 2, 6 }, { 4, 18 } },
|
||||
},
|
||||
};
|
||||
|
||||
#define MDM9607_S0_P1_SHIFT 8
|
||||
#define MDM9607_S1_P1_SHIFT 20
|
||||
#define MDM9607_S2_P1_SHIFT 0
|
||||
#define MDM9607_S3_P1_SHIFT 12
|
||||
#define MDM9607_S4_P1_SHIFT 0
|
||||
struct tsens_legacy_calibration_format tsens_8974_backup_nvmem = {
|
||||
.base_len = 8,
|
||||
.base_shift = 2,
|
||||
.sp_len = 6,
|
||||
.mode = { 4, 30, 1 },
|
||||
.invalid = { 5, 30, 1 },
|
||||
.base = { { 0, 0 }, { 2, 18 } },
|
||||
.sp = {
|
||||
{ { 0, 8 }, { 2, 26 } },
|
||||
{ { 0, 14 }, { 3, 0 } },
|
||||
{ { 0, 20 }, { 3, 6 } },
|
||||
{ { 0, 26 }, { 3, 12 } },
|
||||
{ { 1, 0 }, { 3, 18 } },
|
||||
{ { 1, 6 }, { 3, 24, 1 } },
|
||||
{ { 1, 12 }, { 4, 0, 1 } },
|
||||
{ { 1, 18 }, { 4, 6, 1 } },
|
||||
{ { 2, 0 }, { 4, 12, 1 } },
|
||||
{ { 2, 6 }, { 4, 18, 1 } },
|
||||
{ { 2, 12 }, { 4, 24, 1 } },
|
||||
},
|
||||
};
|
||||
|
||||
#define MDM9607_S0_P2_SHIFT 14
|
||||
#define MDM9607_S1_P2_SHIFT 26
|
||||
#define MDM9607_S2_P2_SHIFT 6
|
||||
#define MDM9607_S3_P2_SHIFT 18
|
||||
#define MDM9607_S4_P2_SHIFT 6
|
||||
|
||||
#define MDM9607_CAL_SEL_MASK 0x00700000
|
||||
#define MDM9607_CAL_SEL_SHIFT 20
|
||||
struct tsens_legacy_calibration_format tsens_9607_nvmem = {
|
||||
.base_len = 8,
|
||||
.base_shift = 2,
|
||||
.sp_len = 6,
|
||||
.mode = { 2, 20 },
|
||||
.invalid = { 2, 22 },
|
||||
.base = { { 0, 0 }, { 2, 12 } },
|
||||
.sp = {
|
||||
{ { 0, 8 }, { 0, 14 } },
|
||||
{ { 0, 20 }, { 0, 26 } },
|
||||
{ { 1, 0 }, { 1, 6 } },
|
||||
{ { 1, 12 }, { 1, 18 } },
|
||||
{ { 2, 0 }, { 2, 6 } },
|
||||
},
|
||||
};
|
||||
|
||||
static int calibrate_8916(struct tsens_priv *priv)
|
||||
{
|
||||
int base0 = 0, base1 = 0, i;
|
||||
u32 p1[5], p2[5];
|
||||
int mode = 0;
|
||||
u32 *qfprom_cdata, *qfprom_csel;
|
||||
int mode, ret;
|
||||
|
||||
ret = tsens_calibrate_nvmem(priv, 3);
|
||||
if (!ret)
|
||||
return 0;
|
||||
|
||||
qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");
|
||||
if (IS_ERR(qfprom_cdata))
|
||||
|
@ -240,37 +139,9 @@ static int calibrate_8916(struct tsens_priv *priv)
|
|||
return PTR_ERR(qfprom_csel);
|
||||
}
|
||||
|
||||
mode = (qfprom_csel[0] & MSM8916_CAL_SEL_MASK) >> MSM8916_CAL_SEL_SHIFT;
|
||||
dev_dbg(priv->dev, "calibration mode is %d\n", mode);
|
||||
|
||||
switch (mode) {
|
||||
case TWO_PT_CALIB:
|
||||
base1 = (qfprom_cdata[1] & MSM8916_BASE1_MASK) >> MSM8916_BASE1_SHIFT;
|
||||
p2[0] = (qfprom_cdata[0] & MSM8916_S0_P2_MASK) >> MSM8916_S0_P2_SHIFT;
|
||||
p2[1] = (qfprom_cdata[0] & MSM8916_S1_P2_MASK) >> MSM8916_S1_P2_SHIFT;
|
||||
p2[2] = (qfprom_cdata[1] & MSM8916_S2_P2_MASK) >> MSM8916_S2_P2_SHIFT;
|
||||
p2[3] = (qfprom_cdata[1] & MSM8916_S3_P2_MASK) >> MSM8916_S3_P2_SHIFT;
|
||||
p2[4] = (qfprom_cdata[1] & MSM8916_S4_P2_MASK) >> MSM8916_S4_P2_SHIFT;
|
||||
for (i = 0; i < priv->num_sensors; i++)
|
||||
p2[i] = ((base1 + p2[i]) << 3);
|
||||
fallthrough;
|
||||
case ONE_PT_CALIB2:
|
||||
base0 = (qfprom_cdata[0] & MSM8916_BASE0_MASK);
|
||||
p1[0] = (qfprom_cdata[0] & MSM8916_S0_P1_MASK) >> MSM8916_S0_P1_SHIFT;
|
||||
p1[1] = (qfprom_cdata[0] & MSM8916_S1_P1_MASK) >> MSM8916_S1_P1_SHIFT;
|
||||
p1[2] = (qfprom_cdata[0] & MSM8916_S2_P1_MASK) >> MSM8916_S2_P1_SHIFT;
|
||||
p1[3] = (qfprom_cdata[1] & MSM8916_S3_P1_MASK) >> MSM8916_S3_P1_SHIFT;
|
||||
p1[4] = (qfprom_cdata[1] & MSM8916_S4_P1_MASK) >> MSM8916_S4_P1_SHIFT;
|
||||
for (i = 0; i < priv->num_sensors; i++)
|
||||
p1[i] = (((base0) + p1[i]) << 3);
|
||||
break;
|
||||
default:
|
||||
for (i = 0; i < priv->num_sensors; i++) {
|
||||
p1[i] = 500;
|
||||
p2[i] = 780;
|
||||
}
|
||||
break;
|
||||
}
|
||||
mode = tsens_read_calibration_legacy(priv, &tsens_8916_nvmem,
|
||||
p1, p2,
|
||||
qfprom_cdata, qfprom_csel);
|
||||
|
||||
compute_intercept_slope(priv, p1, p2, mode);
|
||||
kfree(qfprom_cdata);
|
||||
|
@ -279,83 +150,68 @@ static int calibrate_8916(struct tsens_priv *priv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int calibrate_8939(struct tsens_priv *priv)
|
||||
static void fixup_8974_points(int mode, u32 *p1, u32 *p2)
|
||||
{
|
||||
int base0 = 0, base1 = 0, i;
|
||||
u32 p1[10], p2[10];
|
||||
int mode = 0;
|
||||
u32 *qfprom_cdata;
|
||||
u32 cdata[6];
|
||||
int i;
|
||||
|
||||
qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");
|
||||
if (IS_ERR(qfprom_cdata))
|
||||
return PTR_ERR(qfprom_cdata);
|
||||
|
||||
/* Mapping between qfprom nvmem and calibration data */
|
||||
cdata[0] = qfprom_cdata[12];
|
||||
cdata[1] = qfprom_cdata[13];
|
||||
cdata[2] = qfprom_cdata[0];
|
||||
cdata[3] = qfprom_cdata[1];
|
||||
cdata[4] = qfprom_cdata[22];
|
||||
cdata[5] = qfprom_cdata[21];
|
||||
|
||||
mode = (cdata[0] & MSM8939_CAL_SEL_MASK) >> MSM8939_CAL_SEL_SHIFT;
|
||||
dev_dbg(priv->dev, "calibration mode is %d\n", mode);
|
||||
|
||||
switch (mode) {
|
||||
case TWO_PT_CALIB:
|
||||
base1 = (cdata[3] & MSM8939_BASE1_MASK) >> MSM8939_BASE1_SHIFT;
|
||||
p2[0] = (cdata[0] & MSM8939_S0_P2_MASK) >> MSM8939_S0_P2_SHIFT;
|
||||
p2[1] = (cdata[0] & MSM8939_S1_P2_MASK) >> MSM8939_S1_P2_SHIFT;
|
||||
p2[2] = (cdata[1] & MSM8939_S2_P2_MASK) >> MSM8939_S2_P2_SHIFT;
|
||||
p2[3] = (cdata[1] & MSM8939_S3_P2_MASK) >> MSM8939_S3_P2_SHIFT;
|
||||
p2[4] = (cdata[1] & MSM8939_S4_P2_MASK) >> MSM8939_S4_P2_SHIFT;
|
||||
p2[5] = (cdata[2] & MSM8939_S5_P2_MASK) >> MSM8939_S5_P2_SHIFT;
|
||||
p2[6] = (cdata[2] & MSM8939_S6_P2_MASK) >> MSM8939_S6_P2_SHIFT;
|
||||
p2[7] = (cdata[3] & MSM8939_S7_P2_MASK) >> MSM8939_S7_P2_SHIFT;
|
||||
p2[8] = (cdata[3] & MSM8939_S8_P2_MASK) >> MSM8939_S8_P2_SHIFT;
|
||||
p2[9] = (cdata[4] & MSM8939_S9_P2_MASK_0_4) >> MSM8939_S9_P2_SHIFT_0_4;
|
||||
p2[9] |= ((cdata[5] & MSM8939_S9_P2_MASK_5) >> MSM8939_S9_P2_SHIFT_5) << 5;
|
||||
for (i = 0; i < priv->num_sensors; i++)
|
||||
p2[i] = (base1 + p2[i]) << 2;
|
||||
fallthrough;
|
||||
case ONE_PT_CALIB2:
|
||||
base0 = (cdata[2] & MSM8939_BASE0_MASK) >> MSM8939_BASE0_SHIFT;
|
||||
p1[0] = (cdata[0] & MSM8939_S0_P1_MASK) >> MSM8939_S0_P1_SHIFT;
|
||||
p1[1] = (cdata[0] & MSM8939_S1_P1_MASK) >> MSM8939_S1_P1_SHIFT;
|
||||
p1[2] = (cdata[0] & MSM8939_S2_P1_MASK_0_4) >> MSM8939_S2_P1_SHIFT_0_4;
|
||||
p1[2] |= ((cdata[1] & MSM8939_S2_P1_MASK_5) >> MSM8939_S2_P1_SHIFT_5) << 5;
|
||||
p1[3] = (cdata[1] & MSM8939_S3_P1_MASK) >> MSM8939_S3_P1_SHIFT;
|
||||
p1[4] = (cdata[1] & MSM8939_S4_P1_MASK) >> MSM8939_S4_P1_SHIFT;
|
||||
p1[5] = (cdata[2] & MSM8939_S5_P1_MASK) >> MSM8939_S5_P1_SHIFT;
|
||||
p1[6] = (cdata[2] & MSM8939_S6_P1_MASK) >> MSM8939_S6_P1_SHIFT;
|
||||
p1[7] = (cdata[3] & MSM8939_S7_P1_MASK) >> MSM8939_S7_P1_SHIFT;
|
||||
p1[8] = (cdata[3] & MSM8939_S8_P1_MASK) >> MSM8939_S8_P1_SHIFT;
|
||||
p1[9] = (cdata[4] & MSM8939_S9_P1_MASK) >> MSM8939_S9_P1_SHIFT;
|
||||
for (i = 0; i < priv->num_sensors; i++)
|
||||
p1[i] = ((base0) + p1[i]) << 2;
|
||||
break;
|
||||
default:
|
||||
for (i = 0; i < priv->num_sensors; i++) {
|
||||
p1[i] = 500;
|
||||
p2[i] = 780;
|
||||
if (mode == NO_PT_CALIB) {
|
||||
p1[0] += 2;
|
||||
p1[1] += 9;
|
||||
p1[2] += 3;
|
||||
p1[3] += 9;
|
||||
p1[4] += 5;
|
||||
p1[5] += 9;
|
||||
p1[6] += 7;
|
||||
p1[7] += 10;
|
||||
p1[8] += 8;
|
||||
p1[9] += 9;
|
||||
p1[10] += 8;
|
||||
} else {
|
||||
for (i = 0; i < 11; i++) {
|
||||
/*
|
||||
* ONE_PT_CALIB requires using addition here instead of
|
||||
* using OR operation.
|
||||
*/
|
||||
p1[i] += BIT_APPEND;
|
||||
p2[i] += BIT_APPEND;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int calibrate_8974_nvmem(struct tsens_priv *priv)
|
||||
{
|
||||
u32 p1[11], p2[11];
|
||||
u32 backup;
|
||||
int ret, mode;
|
||||
|
||||
ret = nvmem_cell_read_variable_le_u32(priv->dev, "use_backup", &backup);
|
||||
if (ret == -ENOENT)
|
||||
dev_warn(priv->dev, "Please migrate to separate nvmem cells for calibration data\n");
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
mode = tsens_read_calibration(priv, 2, p1, p2, backup == BKP_SEL);
|
||||
if (mode < 0)
|
||||
return mode;
|
||||
|
||||
fixup_8974_points(mode, p1, p2);
|
||||
|
||||
compute_intercept_slope(priv, p1, p2, mode);
|
||||
kfree(qfprom_cdata);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int calibrate_8974(struct tsens_priv *priv)
|
||||
{
|
||||
int base1 = 0, base2 = 0, i;
|
||||
u32 p1[11], p2[11];
|
||||
int mode = 0;
|
||||
u32 *calib, *bkp;
|
||||
u32 calib_redun_sel;
|
||||
int mode, ret;
|
||||
|
||||
ret = calibrate_8974_nvmem(priv);
|
||||
if (ret == 0)
|
||||
return 0;
|
||||
|
||||
calib = (u32 *)qfprom_read(priv->dev, "calib");
|
||||
if (IS_ERR(calib))
|
||||
|
@ -367,116 +223,18 @@ static int calibrate_8974(struct tsens_priv *priv)
|
|||
return PTR_ERR(bkp);
|
||||
}
|
||||
|
||||
calib_redun_sel = bkp[1] & BKP_REDUN_SEL;
|
||||
calib_redun_sel >>= BKP_REDUN_SHIFT;
|
||||
calib_redun_sel = FIELD_GET(BKP_REDUN_SEL, bkp[1]);
|
||||
|
||||
if (calib_redun_sel == BKP_SEL) {
|
||||
mode = (calib[4] & CAL_SEL_0_1) >> CAL_SEL_SHIFT;
|
||||
mode |= (calib[5] & CAL_SEL_2) >> CAL_SEL_SHIFT_2;
|
||||
if (calib_redun_sel == BKP_SEL)
|
||||
mode = tsens_read_calibration_legacy(priv, &tsens_8974_backup_nvmem,
|
||||
p1, p2,
|
||||
bkp, calib);
|
||||
else
|
||||
mode = tsens_read_calibration_legacy(priv, &tsens_8974_nvmem,
|
||||
p1, p2,
|
||||
calib, NULL);
|
||||
|
||||
switch (mode) {
|
||||
case TWO_PT_CALIB:
|
||||
base2 = (bkp[2] & BASE2_BKP_MASK) >> BASE2_BKP_SHIFT;
|
||||
p2[0] = (bkp[2] & S0_P2_BKP_MASK) >> S0_P2_BKP_SHIFT;
|
||||
p2[1] = (bkp[3] & S1_P2_BKP_MASK);
|
||||
p2[2] = (bkp[3] & S2_P2_BKP_MASK) >> S2_P2_BKP_SHIFT;
|
||||
p2[3] = (bkp[3] & S3_P2_BKP_MASK) >> S3_P2_BKP_SHIFT;
|
||||
p2[4] = (bkp[3] & S4_P2_BKP_MASK) >> S4_P2_BKP_SHIFT;
|
||||
p2[5] = (calib[4] & S5_P2_BKP_MASK) >> S5_P2_BKP_SHIFT;
|
||||
p2[6] = (calib[5] & S6_P2_BKP_MASK);
|
||||
p2[7] = (calib[5] & S7_P2_BKP_MASK) >> S7_P2_BKP_SHIFT;
|
||||
p2[8] = (calib[5] & S8_P2_BKP_MASK) >> S8_P2_BKP_SHIFT;
|
||||
p2[9] = (calib[5] & S9_P2_BKP_MASK) >> S9_P2_BKP_SHIFT;
|
||||
p2[10] = (calib[5] & S10_P2_BKP_MASK) >> S10_P2_BKP_SHIFT;
|
||||
fallthrough;
|
||||
case ONE_PT_CALIB:
|
||||
case ONE_PT_CALIB2:
|
||||
base1 = bkp[0] & BASE1_MASK;
|
||||
p1[0] = (bkp[0] & S0_P1_MASK) >> S0_P1_SHIFT;
|
||||
p1[1] = (bkp[0] & S1_P1_MASK) >> S1_P1_SHIFT;
|
||||
p1[2] = (bkp[0] & S2_P1_MASK) >> S2_P1_SHIFT;
|
||||
p1[3] = (bkp[0] & S3_P1_MASK) >> S3_P1_SHIFT;
|
||||
p1[4] = (bkp[1] & S4_P1_MASK);
|
||||
p1[5] = (bkp[1] & S5_P1_MASK) >> S5_P1_SHIFT;
|
||||
p1[6] = (bkp[1] & S6_P1_MASK) >> S6_P1_SHIFT;
|
||||
p1[7] = (bkp[1] & S7_P1_MASK) >> S7_P1_SHIFT;
|
||||
p1[8] = (bkp[2] & S8_P1_MASK_BKP) >> S8_P1_SHIFT;
|
||||
p1[9] = (bkp[2] & S9_P1_MASK_BKP) >> S9_P1_BKP_SHIFT;
|
||||
p1[10] = (bkp[2] & S10_P1_MASK_BKP) >> S10_P1_BKP_SHIFT;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
mode = (calib[1] & CAL_SEL_0_1) >> CAL_SEL_SHIFT;
|
||||
mode |= (calib[3] & CAL_SEL_2) >> CAL_SEL_SHIFT_2;
|
||||
|
||||
switch (mode) {
|
||||
case TWO_PT_CALIB:
|
||||
base2 = (calib[2] & BASE2_MASK) >> BASE2_SHIFT;
|
||||
p2[0] = (calib[2] & S0_P2_MASK) >> S0_P2_SHIFT;
|
||||
p2[1] = (calib[2] & S1_P2_MASK) >> S1_P2_SHIFT;
|
||||
p2[2] = (calib[3] & S2_P2_MASK);
|
||||
p2[3] = (calib[3] & S3_P2_MASK) >> S3_P2_SHIFT;
|
||||
p2[4] = (calib[3] & S4_P2_MASK) >> S4_P2_SHIFT;
|
||||
p2[5] = (calib[3] & S5_P2_MASK) >> S5_P2_SHIFT;
|
||||
p2[6] = (calib[3] & S6_P2_MASK) >> S6_P2_SHIFT;
|
||||
p2[7] = (calib[4] & S7_P2_MASK);
|
||||
p2[8] = (calib[4] & S8_P2_MASK) >> S8_P2_SHIFT;
|
||||
p2[9] = (calib[4] & S9_P2_MASK) >> S9_P2_SHIFT;
|
||||
p2[10] = (calib[4] & S10_P2_MASK) >> S10_P2_SHIFT;
|
||||
fallthrough;
|
||||
case ONE_PT_CALIB:
|
||||
case ONE_PT_CALIB2:
|
||||
base1 = calib[0] & BASE1_MASK;
|
||||
p1[0] = (calib[0] & S0_P1_MASK) >> S0_P1_SHIFT;
|
||||
p1[1] = (calib[0] & S1_P1_MASK) >> S1_P1_SHIFT;
|
||||
p1[2] = (calib[0] & S2_P1_MASK) >> S2_P1_SHIFT;
|
||||
p1[3] = (calib[0] & S3_P1_MASK) >> S3_P1_SHIFT;
|
||||
p1[4] = (calib[1] & S4_P1_MASK);
|
||||
p1[5] = (calib[1] & S5_P1_MASK) >> S5_P1_SHIFT;
|
||||
p1[6] = (calib[1] & S6_P1_MASK) >> S6_P1_SHIFT;
|
||||
p1[7] = (calib[1] & S7_P1_MASK) >> S7_P1_SHIFT;
|
||||
p1[8] = (calib[1] & S8_P1_MASK) >> S8_P1_SHIFT;
|
||||
p1[9] = (calib[2] & S9_P1_MASK);
|
||||
p1[10] = (calib[2] & S10_P1_MASK) >> S10_P1_SHIFT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case ONE_PT_CALIB:
|
||||
for (i = 0; i < priv->num_sensors; i++)
|
||||
p1[i] += (base1 << 2) | BIT_APPEND;
|
||||
break;
|
||||
case TWO_PT_CALIB:
|
||||
for (i = 0; i < priv->num_sensors; i++) {
|
||||
p2[i] += base2;
|
||||
p2[i] <<= 2;
|
||||
p2[i] |= BIT_APPEND;
|
||||
}
|
||||
fallthrough;
|
||||
case ONE_PT_CALIB2:
|
||||
for (i = 0; i < priv->num_sensors; i++) {
|
||||
p1[i] += base1;
|
||||
p1[i] <<= 2;
|
||||
p1[i] |= BIT_APPEND;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
for (i = 0; i < priv->num_sensors; i++)
|
||||
p2[i] = 780;
|
||||
p1[0] = 502;
|
||||
p1[1] = 509;
|
||||
p1[2] = 503;
|
||||
p1[3] = 509;
|
||||
p1[4] = 505;
|
||||
p1[5] = 509;
|
||||
p1[6] = 507;
|
||||
p1[7] = 510;
|
||||
p1[8] = 508;
|
||||
p1[9] = 509;
|
||||
p1[10] = 508;
|
||||
break;
|
||||
}
|
||||
fixup_8974_points(mode, p1, p2);
|
||||
|
||||
compute_intercept_slope(priv, p1, p2, mode);
|
||||
kfree(calib);
|
||||
|
@ -485,53 +243,19 @@ static int calibrate_8974(struct tsens_priv *priv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int calibrate_9607(struct tsens_priv *priv)
|
||||
{
|
||||
int base, i;
|
||||
u32 p1[5], p2[5];
|
||||
int mode = 0;
|
||||
u32 *qfprom_cdata;
|
||||
static int __init init_8939(struct tsens_priv *priv) {
|
||||
priv->sensor[0].slope = 2911;
|
||||
priv->sensor[1].slope = 2789;
|
||||
priv->sensor[2].slope = 2906;
|
||||
priv->sensor[3].slope = 2763;
|
||||
priv->sensor[4].slope = 2922;
|
||||
priv->sensor[5].slope = 2867;
|
||||
priv->sensor[6].slope = 2833;
|
||||
priv->sensor[7].slope = 2838;
|
||||
priv->sensor[8].slope = 2840;
|
||||
/* priv->sensor[9].slope = 2852; */
|
||||
|
||||
qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");
|
||||
if (IS_ERR(qfprom_cdata))
|
||||
return PTR_ERR(qfprom_cdata);
|
||||
|
||||
mode = (qfprom_cdata[2] & MDM9607_CAL_SEL_MASK) >> MDM9607_CAL_SEL_SHIFT;
|
||||
dev_dbg(priv->dev, "calibration mode is %d\n", mode);
|
||||
|
||||
switch (mode) {
|
||||
case TWO_PT_CALIB:
|
||||
base = (qfprom_cdata[2] & MDM9607_BASE1_MASK) >> MDM9607_BASE1_SHIFT;
|
||||
p2[0] = (qfprom_cdata[0] & MDM9607_S0_P2_MASK) >> MDM9607_S0_P2_SHIFT;
|
||||
p2[1] = (qfprom_cdata[0] & MDM9607_S1_P2_MASK) >> MDM9607_S1_P2_SHIFT;
|
||||
p2[2] = (qfprom_cdata[1] & MDM9607_S2_P2_MASK) >> MDM9607_S2_P2_SHIFT;
|
||||
p2[3] = (qfprom_cdata[1] & MDM9607_S3_P2_MASK) >> MDM9607_S3_P2_SHIFT;
|
||||
p2[4] = (qfprom_cdata[2] & MDM9607_S4_P2_MASK) >> MDM9607_S4_P2_SHIFT;
|
||||
for (i = 0; i < priv->num_sensors; i++)
|
||||
p2[i] = ((base + p2[i]) << 2);
|
||||
fallthrough;
|
||||
case ONE_PT_CALIB2:
|
||||
base = (qfprom_cdata[0] & MDM9607_BASE0_MASK);
|
||||
p1[0] = (qfprom_cdata[0] & MDM9607_S0_P1_MASK) >> MDM9607_S0_P1_SHIFT;
|
||||
p1[1] = (qfprom_cdata[0] & MDM9607_S1_P1_MASK) >> MDM9607_S1_P1_SHIFT;
|
||||
p1[2] = (qfprom_cdata[1] & MDM9607_S2_P1_MASK) >> MDM9607_S2_P1_SHIFT;
|
||||
p1[3] = (qfprom_cdata[1] & MDM9607_S3_P1_MASK) >> MDM9607_S3_P1_SHIFT;
|
||||
p1[4] = (qfprom_cdata[2] & MDM9607_S4_P1_MASK) >> MDM9607_S4_P1_SHIFT;
|
||||
for (i = 0; i < priv->num_sensors; i++)
|
||||
p1[i] = ((base + p1[i]) << 2);
|
||||
break;
|
||||
default:
|
||||
for (i = 0; i < priv->num_sensors; i++) {
|
||||
p1[i] = 500;
|
||||
p2[i] = 780;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
compute_intercept_slope(priv, p1, p2, mode);
|
||||
kfree(qfprom_cdata);
|
||||
|
||||
return 0;
|
||||
return init_common(priv);
|
||||
}
|
||||
|
||||
/* v0.1: 8916, 8939, 8974, 9607 */
|
||||
|
@ -583,6 +307,12 @@ static const struct reg_field tsens_v0_1_regfields[MAX_REGFIELDS] = {
|
|||
[TRDY] = REG_FIELD(TM_TRDY_OFF, 0, 0),
|
||||
};
|
||||
|
||||
static const struct tsens_ops ops_v0_1 = {
|
||||
.init = init_common,
|
||||
.calibrate = tsens_calibrate_common,
|
||||
.get_temp = get_temp_common,
|
||||
};
|
||||
|
||||
static const struct tsens_ops ops_8916 = {
|
||||
.init = init_common,
|
||||
.calibrate = calibrate_8916,
|
||||
|
@ -599,15 +329,15 @@ struct tsens_plat_data data_8916 = {
|
|||
};
|
||||
|
||||
static const struct tsens_ops ops_8939 = {
|
||||
.init = init_common,
|
||||
.calibrate = calibrate_8939,
|
||||
.init = init_8939,
|
||||
.calibrate = tsens_calibrate_common,
|
||||
.get_temp = get_temp_common,
|
||||
};
|
||||
|
||||
struct tsens_plat_data data_8939 = {
|
||||
.num_sensors = 10,
|
||||
.num_sensors = 9,
|
||||
.ops = &ops_8939,
|
||||
.hw_ids = (unsigned int []){ 0, 1, 2, 3, 5, 6, 7, 8, 9, 10 },
|
||||
.hw_ids = (unsigned int []){ 0, 1, 2, 3, 5, 6, 7, 8, 9, /* 10 */ },
|
||||
|
||||
.feat = &tsens_v0_1_feat,
|
||||
.fields = tsens_v0_1_regfields,
|
||||
|
@ -626,16 +356,9 @@ struct tsens_plat_data data_8974 = {
|
|||
.fields = tsens_v0_1_regfields,
|
||||
};
|
||||
|
||||
static const struct tsens_ops ops_9607 = {
|
||||
.init = init_common,
|
||||
.calibrate = calibrate_9607,
|
||||
.get_temp = get_temp_common,
|
||||
};
|
||||
|
||||
struct tsens_plat_data data_9607 = {
|
||||
.num_sensors = 5,
|
||||
.ops = &ops_9607,
|
||||
.hw_ids = (unsigned int []){ 0, 1, 2, 3, 4 },
|
||||
.ops = &ops_v0_1,
|
||||
.feat = &tsens_v0_1_feat,
|
||||
.fields = tsens_v0_1_regfields,
|
||||
};
|
||||
|
|
|
@ -21,210 +21,66 @@
|
|||
#define TM_HIGH_LOW_INT_STATUS_OFF 0x0088
|
||||
#define TM_HIGH_LOW_Sn_INT_THRESHOLD_OFF 0x0090
|
||||
|
||||
/* eeprom layout data for msm8956/76 (v1) */
|
||||
#define MSM8976_BASE0_MASK 0xff
|
||||
#define MSM8976_BASE1_MASK 0xff
|
||||
#define MSM8976_BASE1_SHIFT 8
|
||||
struct tsens_legacy_calibration_format tsens_qcs404_nvmem = {
|
||||
.base_len = 8,
|
||||
.base_shift = 2,
|
||||
.sp_len = 6,
|
||||
.mode = { 4, 0 },
|
||||
.invalid = { 4, 2 },
|
||||
.base = { { 4, 3 }, { 4, 11 } },
|
||||
.sp = {
|
||||
{ { 0, 0 }, { 0, 6 } },
|
||||
{ { 0, 12 }, { 0, 18 } },
|
||||
{ { 0, 24 }, { 0, 30 } },
|
||||
{ { 1, 4 }, { 1, 10 } },
|
||||
{ { 1, 16 }, { 1, 22 } },
|
||||
{ { 2, 0 }, { 2, 6 } },
|
||||
{ { 2, 12 }, { 2, 18 } },
|
||||
{ { 2, 24 }, { 2, 30 } },
|
||||
{ { 3, 4 }, { 3, 10 } },
|
||||
{ { 3, 16 }, { 3, 22 } },
|
||||
},
|
||||
};
|
||||
|
||||
#define MSM8976_S0_P1_MASK 0x3f00
|
||||
#define MSM8976_S1_P1_MASK 0x3f00000
|
||||
#define MSM8976_S2_P1_MASK 0x3f
|
||||
#define MSM8976_S3_P1_MASK 0x3f000
|
||||
#define MSM8976_S4_P1_MASK 0x3f00
|
||||
#define MSM8976_S5_P1_MASK 0x3f00000
|
||||
#define MSM8976_S6_P1_MASK 0x3f
|
||||
#define MSM8976_S7_P1_MASK 0x3f000
|
||||
#define MSM8976_S8_P1_MASK 0x1f8
|
||||
#define MSM8976_S9_P1_MASK 0x1f8000
|
||||
#define MSM8976_S10_P1_MASK 0xf8000000
|
||||
#define MSM8976_S10_P1_MASK_1 0x1
|
||||
|
||||
#define MSM8976_S0_P2_MASK 0xfc000
|
||||
#define MSM8976_S1_P2_MASK 0xfc000000
|
||||
#define MSM8976_S2_P2_MASK 0xfc0
|
||||
#define MSM8976_S3_P2_MASK 0xfc0000
|
||||
#define MSM8976_S4_P2_MASK 0xfc000
|
||||
#define MSM8976_S5_P2_MASK 0xfc000000
|
||||
#define MSM8976_S6_P2_MASK 0xfc0
|
||||
#define MSM8976_S7_P2_MASK 0xfc0000
|
||||
#define MSM8976_S8_P2_MASK 0x7e00
|
||||
#define MSM8976_S9_P2_MASK 0x7e00000
|
||||
#define MSM8976_S10_P2_MASK 0x7e
|
||||
|
||||
#define MSM8976_S0_P1_SHIFT 8
|
||||
#define MSM8976_S1_P1_SHIFT 20
|
||||
#define MSM8976_S2_P1_SHIFT 0
|
||||
#define MSM8976_S3_P1_SHIFT 12
|
||||
#define MSM8976_S4_P1_SHIFT 8
|
||||
#define MSM8976_S5_P1_SHIFT 20
|
||||
#define MSM8976_S6_P1_SHIFT 0
|
||||
#define MSM8976_S7_P1_SHIFT 12
|
||||
#define MSM8976_S8_P1_SHIFT 3
|
||||
#define MSM8976_S9_P1_SHIFT 15
|
||||
#define MSM8976_S10_P1_SHIFT 27
|
||||
#define MSM8976_S10_P1_SHIFT_1 0
|
||||
|
||||
#define MSM8976_S0_P2_SHIFT 14
|
||||
#define MSM8976_S1_P2_SHIFT 26
|
||||
#define MSM8976_S2_P2_SHIFT 6
|
||||
#define MSM8976_S3_P2_SHIFT 18
|
||||
#define MSM8976_S4_P2_SHIFT 14
|
||||
#define MSM8976_S5_P2_SHIFT 26
|
||||
#define MSM8976_S6_P2_SHIFT 6
|
||||
#define MSM8976_S7_P2_SHIFT 18
|
||||
#define MSM8976_S8_P2_SHIFT 9
|
||||
#define MSM8976_S9_P2_SHIFT 21
|
||||
#define MSM8976_S10_P2_SHIFT 1
|
||||
|
||||
#define MSM8976_CAL_SEL_MASK 0x3
|
||||
|
||||
#define MSM8976_CAL_DEGC_PT1 30
|
||||
#define MSM8976_CAL_DEGC_PT2 120
|
||||
#define MSM8976_SLOPE_FACTOR 1000
|
||||
#define MSM8976_SLOPE_DEFAULT 3200
|
||||
|
||||
/* eeprom layout data for qcs404/405 (v1) */
|
||||
#define BASE0_MASK 0x000007f8
|
||||
#define BASE1_MASK 0x0007f800
|
||||
#define BASE0_SHIFT 3
|
||||
#define BASE1_SHIFT 11
|
||||
|
||||
#define S0_P1_MASK 0x0000003f
|
||||
#define S1_P1_MASK 0x0003f000
|
||||
#define S2_P1_MASK 0x3f000000
|
||||
#define S3_P1_MASK 0x000003f0
|
||||
#define S4_P1_MASK 0x003f0000
|
||||
#define S5_P1_MASK 0x0000003f
|
||||
#define S6_P1_MASK 0x0003f000
|
||||
#define S7_P1_MASK 0x3f000000
|
||||
#define S8_P1_MASK 0x000003f0
|
||||
#define S9_P1_MASK 0x003f0000
|
||||
|
||||
#define S0_P2_MASK 0x00000fc0
|
||||
#define S1_P2_MASK 0x00fc0000
|
||||
#define S2_P2_MASK_1_0 0xc0000000
|
||||
#define S2_P2_MASK_5_2 0x0000000f
|
||||
#define S3_P2_MASK 0x0000fc00
|
||||
#define S4_P2_MASK 0x0fc00000
|
||||
#define S5_P2_MASK 0x00000fc0
|
||||
#define S6_P2_MASK 0x00fc0000
|
||||
#define S7_P2_MASK_1_0 0xc0000000
|
||||
#define S7_P2_MASK_5_2 0x0000000f
|
||||
#define S8_P2_MASK 0x0000fc00
|
||||
#define S9_P2_MASK 0x0fc00000
|
||||
|
||||
#define S0_P1_SHIFT 0
|
||||
#define S0_P2_SHIFT 6
|
||||
#define S1_P1_SHIFT 12
|
||||
#define S1_P2_SHIFT 18
|
||||
#define S2_P1_SHIFT 24
|
||||
#define S2_P2_SHIFT_1_0 30
|
||||
|
||||
#define S2_P2_SHIFT_5_2 0
|
||||
#define S3_P1_SHIFT 4
|
||||
#define S3_P2_SHIFT 10
|
||||
#define S4_P1_SHIFT 16
|
||||
#define S4_P2_SHIFT 22
|
||||
|
||||
#define S5_P1_SHIFT 0
|
||||
#define S5_P2_SHIFT 6
|
||||
#define S6_P1_SHIFT 12
|
||||
#define S6_P2_SHIFT 18
|
||||
#define S7_P1_SHIFT 24
|
||||
#define S7_P2_SHIFT_1_0 30
|
||||
|
||||
#define S7_P2_SHIFT_5_2 0
|
||||
#define S8_P1_SHIFT 4
|
||||
#define S8_P2_SHIFT 10
|
||||
#define S9_P1_SHIFT 16
|
||||
#define S9_P2_SHIFT 22
|
||||
|
||||
#define CAL_SEL_MASK 7
|
||||
#define CAL_SEL_SHIFT 0
|
||||
|
||||
static void compute_intercept_slope_8976(struct tsens_priv *priv,
|
||||
u32 *p1, u32 *p2, u32 mode)
|
||||
{
|
||||
int i;
|
||||
|
||||
priv->sensor[0].slope = 3313;
|
||||
priv->sensor[1].slope = 3275;
|
||||
priv->sensor[2].slope = 3320;
|
||||
priv->sensor[3].slope = 3246;
|
||||
priv->sensor[4].slope = 3279;
|
||||
priv->sensor[5].slope = 3257;
|
||||
priv->sensor[6].slope = 3234;
|
||||
priv->sensor[7].slope = 3269;
|
||||
priv->sensor[8].slope = 3255;
|
||||
priv->sensor[9].slope = 3239;
|
||||
priv->sensor[10].slope = 3286;
|
||||
|
||||
for (i = 0; i < priv->num_sensors; i++) {
|
||||
priv->sensor[i].offset = (p1[i] * MSM8976_SLOPE_FACTOR) -
|
||||
(MSM8976_CAL_DEGC_PT1 *
|
||||
priv->sensor[i].slope);
|
||||
}
|
||||
}
|
||||
struct tsens_legacy_calibration_format tsens_8976_nvmem = {
|
||||
.base_len = 8,
|
||||
.base_shift = 2,
|
||||
.sp_len = 6,
|
||||
.mode = { 4, 0 },
|
||||
.invalid = { 4, 2 },
|
||||
.base = { { 0, 0 }, { 2, 8 } },
|
||||
.sp = {
|
||||
{ { 0, 8 }, { 0, 14 } },
|
||||
{ { 0, 20 }, { 0, 26 } },
|
||||
{ { 1, 0 }, { 1, 6 } },
|
||||
{ { 1, 12 }, { 1, 18 } },
|
||||
{ { 2, 8 }, { 2, 14 } },
|
||||
{ { 2, 20 }, { 2, 26 } },
|
||||
{ { 3, 0 }, { 3, 6 } },
|
||||
{ { 3, 12 }, { 3, 18 } },
|
||||
{ { 4, 2 }, { 4, 9 } },
|
||||
{ { 4, 14 }, { 4, 21 } },
|
||||
{ { 4, 26 }, { 5, 1 } },
|
||||
},
|
||||
};
|
||||
|
||||
static int calibrate_v1(struct tsens_priv *priv)
|
||||
{
|
||||
u32 base0 = 0, base1 = 0;
|
||||
u32 p1[10], p2[10];
|
||||
u32 mode = 0, lsb = 0, msb = 0;
|
||||
u32 *qfprom_cdata;
|
||||
int i;
|
||||
int mode, ret;
|
||||
|
||||
ret = tsens_calibrate_common(priv);
|
||||
if (!ret)
|
||||
return 0;
|
||||
|
||||
qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");
|
||||
if (IS_ERR(qfprom_cdata))
|
||||
return PTR_ERR(qfprom_cdata);
|
||||
|
||||
mode = (qfprom_cdata[4] & CAL_SEL_MASK) >> CAL_SEL_SHIFT;
|
||||
dev_dbg(priv->dev, "calibration mode is %d\n", mode);
|
||||
|
||||
switch (mode) {
|
||||
case TWO_PT_CALIB:
|
||||
base1 = (qfprom_cdata[4] & BASE1_MASK) >> BASE1_SHIFT;
|
||||
p2[0] = (qfprom_cdata[0] & S0_P2_MASK) >> S0_P2_SHIFT;
|
||||
p2[1] = (qfprom_cdata[0] & S1_P2_MASK) >> S1_P2_SHIFT;
|
||||
/* This value is split over two registers, 2 bits and 4 bits */
|
||||
lsb = (qfprom_cdata[0] & S2_P2_MASK_1_0) >> S2_P2_SHIFT_1_0;
|
||||
msb = (qfprom_cdata[1] & S2_P2_MASK_5_2) >> S2_P2_SHIFT_5_2;
|
||||
p2[2] = msb << 2 | lsb;
|
||||
p2[3] = (qfprom_cdata[1] & S3_P2_MASK) >> S3_P2_SHIFT;
|
||||
p2[4] = (qfprom_cdata[1] & S4_P2_MASK) >> S4_P2_SHIFT;
|
||||
p2[5] = (qfprom_cdata[2] & S5_P2_MASK) >> S5_P2_SHIFT;
|
||||
p2[6] = (qfprom_cdata[2] & S6_P2_MASK) >> S6_P2_SHIFT;
|
||||
/* This value is split over two registers, 2 bits and 4 bits */
|
||||
lsb = (qfprom_cdata[2] & S7_P2_MASK_1_0) >> S7_P2_SHIFT_1_0;
|
||||
msb = (qfprom_cdata[3] & S7_P2_MASK_5_2) >> S7_P2_SHIFT_5_2;
|
||||
p2[7] = msb << 2 | lsb;
|
||||
p2[8] = (qfprom_cdata[3] & S8_P2_MASK) >> S8_P2_SHIFT;
|
||||
p2[9] = (qfprom_cdata[3] & S9_P2_MASK) >> S9_P2_SHIFT;
|
||||
for (i = 0; i < priv->num_sensors; i++)
|
||||
p2[i] = ((base1 + p2[i]) << 2);
|
||||
fallthrough;
|
||||
case ONE_PT_CALIB2:
|
||||
base0 = (qfprom_cdata[4] & BASE0_MASK) >> BASE0_SHIFT;
|
||||
p1[0] = (qfprom_cdata[0] & S0_P1_MASK) >> S0_P1_SHIFT;
|
||||
p1[1] = (qfprom_cdata[0] & S1_P1_MASK) >> S1_P1_SHIFT;
|
||||
p1[2] = (qfprom_cdata[0] & S2_P1_MASK) >> S2_P1_SHIFT;
|
||||
p1[3] = (qfprom_cdata[1] & S3_P1_MASK) >> S3_P1_SHIFT;
|
||||
p1[4] = (qfprom_cdata[1] & S4_P1_MASK) >> S4_P1_SHIFT;
|
||||
p1[5] = (qfprom_cdata[2] & S5_P1_MASK) >> S5_P1_SHIFT;
|
||||
p1[6] = (qfprom_cdata[2] & S6_P1_MASK) >> S6_P1_SHIFT;
|
||||
p1[7] = (qfprom_cdata[2] & S7_P1_MASK) >> S7_P1_SHIFT;
|
||||
p1[8] = (qfprom_cdata[3] & S8_P1_MASK) >> S8_P1_SHIFT;
|
||||
p1[9] = (qfprom_cdata[3] & S9_P1_MASK) >> S9_P1_SHIFT;
|
||||
for (i = 0; i < priv->num_sensors; i++)
|
||||
p1[i] = (((base0) + p1[i]) << 2);
|
||||
break;
|
||||
default:
|
||||
for (i = 0; i < priv->num_sensors; i++) {
|
||||
p1[i] = 500;
|
||||
p2[i] = 780;
|
||||
}
|
||||
break;
|
||||
}
|
||||
mode = tsens_read_calibration_legacy(priv, &tsens_qcs404_nvmem,
|
||||
p1, p2,
|
||||
qfprom_cdata, NULL);
|
||||
|
||||
compute_intercept_slope(priv, p1, p2, mode);
|
||||
kfree(qfprom_cdata);
|
||||
|
@ -232,71 +88,6 @@ static int calibrate_v1(struct tsens_priv *priv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int calibrate_8976(struct tsens_priv *priv)
|
||||
{
|
||||
int base0 = 0, base1 = 0, i;
|
||||
u32 p1[11], p2[11];
|
||||
int mode = 0, tmp = 0;
|
||||
u32 *qfprom_cdata;
|
||||
|
||||
qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");
|
||||
if (IS_ERR(qfprom_cdata))
|
||||
return PTR_ERR(qfprom_cdata);
|
||||
|
||||
mode = (qfprom_cdata[4] & MSM8976_CAL_SEL_MASK);
|
||||
dev_dbg(priv->dev, "calibration mode is %d\n", mode);
|
||||
|
||||
switch (mode) {
|
||||
case TWO_PT_CALIB:
|
||||
base1 = (qfprom_cdata[2] & MSM8976_BASE1_MASK) >> MSM8976_BASE1_SHIFT;
|
||||
p2[0] = (qfprom_cdata[0] & MSM8976_S0_P2_MASK) >> MSM8976_S0_P2_SHIFT;
|
||||
p2[1] = (qfprom_cdata[0] & MSM8976_S1_P2_MASK) >> MSM8976_S1_P2_SHIFT;
|
||||
p2[2] = (qfprom_cdata[1] & MSM8976_S2_P2_MASK) >> MSM8976_S2_P2_SHIFT;
|
||||
p2[3] = (qfprom_cdata[1] & MSM8976_S3_P2_MASK) >> MSM8976_S3_P2_SHIFT;
|
||||
p2[4] = (qfprom_cdata[2] & MSM8976_S4_P2_MASK) >> MSM8976_S4_P2_SHIFT;
|
||||
p2[5] = (qfprom_cdata[2] & MSM8976_S5_P2_MASK) >> MSM8976_S5_P2_SHIFT;
|
||||
p2[6] = (qfprom_cdata[3] & MSM8976_S6_P2_MASK) >> MSM8976_S6_P2_SHIFT;
|
||||
p2[7] = (qfprom_cdata[3] & MSM8976_S7_P2_MASK) >> MSM8976_S7_P2_SHIFT;
|
||||
p2[8] = (qfprom_cdata[4] & MSM8976_S8_P2_MASK) >> MSM8976_S8_P2_SHIFT;
|
||||
p2[9] = (qfprom_cdata[4] & MSM8976_S9_P2_MASK) >> MSM8976_S9_P2_SHIFT;
|
||||
p2[10] = (qfprom_cdata[5] & MSM8976_S10_P2_MASK) >> MSM8976_S10_P2_SHIFT;
|
||||
|
||||
for (i = 0; i < priv->num_sensors; i++)
|
||||
p2[i] = ((base1 + p2[i]) << 2);
|
||||
fallthrough;
|
||||
case ONE_PT_CALIB2:
|
||||
base0 = qfprom_cdata[0] & MSM8976_BASE0_MASK;
|
||||
p1[0] = (qfprom_cdata[0] & MSM8976_S0_P1_MASK) >> MSM8976_S0_P1_SHIFT;
|
||||
p1[1] = (qfprom_cdata[0] & MSM8976_S1_P1_MASK) >> MSM8976_S1_P1_SHIFT;
|
||||
p1[2] = (qfprom_cdata[1] & MSM8976_S2_P1_MASK) >> MSM8976_S2_P1_SHIFT;
|
||||
p1[3] = (qfprom_cdata[1] & MSM8976_S3_P1_MASK) >> MSM8976_S3_P1_SHIFT;
|
||||
p1[4] = (qfprom_cdata[2] & MSM8976_S4_P1_MASK) >> MSM8976_S4_P1_SHIFT;
|
||||
p1[5] = (qfprom_cdata[2] & MSM8976_S5_P1_MASK) >> MSM8976_S5_P1_SHIFT;
|
||||
p1[6] = (qfprom_cdata[3] & MSM8976_S6_P1_MASK) >> MSM8976_S6_P1_SHIFT;
|
||||
p1[7] = (qfprom_cdata[3] & MSM8976_S7_P1_MASK) >> MSM8976_S7_P1_SHIFT;
|
||||
p1[8] = (qfprom_cdata[4] & MSM8976_S8_P1_MASK) >> MSM8976_S8_P1_SHIFT;
|
||||
p1[9] = (qfprom_cdata[4] & MSM8976_S9_P1_MASK) >> MSM8976_S9_P1_SHIFT;
|
||||
p1[10] = (qfprom_cdata[4] & MSM8976_S10_P1_MASK) >> MSM8976_S10_P1_SHIFT;
|
||||
tmp = (qfprom_cdata[5] & MSM8976_S10_P1_MASK_1) << MSM8976_S10_P1_SHIFT_1;
|
||||
p1[10] |= tmp;
|
||||
|
||||
for (i = 0; i < priv->num_sensors; i++)
|
||||
p1[i] = (((base0) + p1[i]) << 2);
|
||||
break;
|
||||
default:
|
||||
for (i = 0; i < priv->num_sensors; i++) {
|
||||
p1[i] = 500;
|
||||
p2[i] = 780;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
compute_intercept_slope_8976(priv, p1, p2, mode);
|
||||
kfree(qfprom_cdata);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* v1.x: msm8956,8976,qcs404,405 */
|
||||
|
||||
static struct tsens_features tsens_v1_feat = {
|
||||
|
@ -365,6 +156,22 @@ static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = {
|
|||
[TRDY] = REG_FIELD(TM_TRDY_OFF, 0, 0),
|
||||
};
|
||||
|
||||
static int __init init_8956(struct tsens_priv *priv) {
|
||||
priv->sensor[0].slope = 3313;
|
||||
priv->sensor[1].slope = 3275;
|
||||
priv->sensor[2].slope = 3320;
|
||||
priv->sensor[3].slope = 3246;
|
||||
priv->sensor[4].slope = 3279;
|
||||
priv->sensor[5].slope = 3257;
|
||||
priv->sensor[6].slope = 3234;
|
||||
priv->sensor[7].slope = 3269;
|
||||
priv->sensor[8].slope = 3255;
|
||||
priv->sensor[9].slope = 3239;
|
||||
priv->sensor[10].slope = 3286;
|
||||
|
||||
return init_common(priv);
|
||||
}
|
||||
|
||||
static const struct tsens_ops ops_generic_v1 = {
|
||||
.init = init_common,
|
||||
.calibrate = calibrate_v1,
|
||||
|
@ -377,17 +184,28 @@ struct tsens_plat_data data_tsens_v1 = {
|
|||
.fields = tsens_v1_regfields,
|
||||
};
|
||||
|
||||
static const struct tsens_ops ops_8976 = {
|
||||
.init = init_common,
|
||||
.calibrate = calibrate_8976,
|
||||
static const struct tsens_ops ops_8956 = {
|
||||
.init = init_8956,
|
||||
.calibrate = tsens_calibrate_common,
|
||||
.get_temp = get_temp_tsens_valid,
|
||||
};
|
||||
|
||||
/* Valid for both MSM8956 and MSM8976. */
|
||||
struct tsens_plat_data data_8976 = {
|
||||
struct tsens_plat_data data_8956 = {
|
||||
.num_sensors = 11,
|
||||
.ops = &ops_8976,
|
||||
.hw_ids = (unsigned int[]){0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
|
||||
.ops = &ops_8956,
|
||||
.feat = &tsens_v1_feat,
|
||||
.fields = tsens_v1_regfields,
|
||||
};
|
||||
|
||||
static const struct tsens_ops ops_8976 = {
|
||||
.init = init_common,
|
||||
.calibrate = tsens_calibrate_common,
|
||||
.get_temp = get_temp_tsens_valid,
|
||||
};
|
||||
|
||||
struct tsens_plat_data data_8976 = {
|
||||
.num_sensors = 11,
|
||||
.ops = &ops_8976,
|
||||
.feat = &tsens_v1_feat,
|
||||
.fields = tsens_v1_regfields,
|
||||
};
|
||||
|
|
|
@ -70,6 +70,171 @@ char *qfprom_read(struct device *dev, const char *cname)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int tsens_read_calibration(struct tsens_priv *priv, int shift, u32 *p1, u32 *p2, bool backup)
|
||||
{
|
||||
u32 mode;
|
||||
u32 base1, base2;
|
||||
char name[] = "sXX_pY_backup"; /* s10_p1_backup */
|
||||
int i, ret;
|
||||
|
||||
if (priv->num_sensors > MAX_SENSORS)
|
||||
return -EINVAL;
|
||||
|
||||
ret = snprintf(name, sizeof(name), "mode%s", backup ? "_backup" : "");
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &mode);
|
||||
if (ret == -ENOENT)
|
||||
dev_warn(priv->dev, "Please migrate to separate nvmem cells for calibration data\n");
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dev_dbg(priv->dev, "calibration mode is %d\n", mode);
|
||||
|
||||
ret = snprintf(name, sizeof(name), "base1%s", backup ? "_backup" : "");
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &base1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = snprintf(name, sizeof(name), "base2%s", backup ? "_backup" : "");
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &base2);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < priv->num_sensors; i++) {
|
||||
ret = snprintf(name, sizeof(name), "s%d_p1%s", priv->sensor[i].hw_id,
|
||||
backup ? "_backup" : "");
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &p1[i]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = snprintf(name, sizeof(name), "s%d_p2%s", priv->sensor[i].hw_id,
|
||||
backup ? "_backup" : "");
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &p2[i]);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case ONE_PT_CALIB:
|
||||
for (i = 0; i < priv->num_sensors; i++)
|
||||
p1[i] = p1[i] + (base1 << shift);
|
||||
break;
|
||||
case TWO_PT_CALIB:
|
||||
for (i = 0; i < priv->num_sensors; i++)
|
||||
p2[i] = (p2[i] + base2) << shift;
|
||||
fallthrough;
|
||||
case ONE_PT_CALIB2:
|
||||
for (i = 0; i < priv->num_sensors; i++)
|
||||
p1[i] = (p1[i] + base1) << shift;
|
||||
break;
|
||||
default:
|
||||
dev_dbg(priv->dev, "calibrationless mode\n");
|
||||
for (i = 0; i < priv->num_sensors; i++) {
|
||||
p1[i] = 500;
|
||||
p2[i] = 780;
|
||||
}
|
||||
}
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
int tsens_calibrate_nvmem(struct tsens_priv *priv, int shift)
|
||||
{
|
||||
u32 p1[MAX_SENSORS], p2[MAX_SENSORS];
|
||||
int mode;
|
||||
|
||||
mode = tsens_read_calibration(priv, shift, p1, p2, false);
|
||||
if (mode < 0)
|
||||
return mode;
|
||||
|
||||
compute_intercept_slope(priv, p1, p2, mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tsens_calibrate_common(struct tsens_priv *priv)
|
||||
{
|
||||
return tsens_calibrate_nvmem(priv, 2);
|
||||
}
|
||||
|
||||
static u32 tsens_read_cell(const struct tsens_single_value *cell, u8 len, u32 *data0, u32 *data1)
|
||||
{
|
||||
u32 val;
|
||||
u32 *data = cell->blob ? data1 : data0;
|
||||
|
||||
if (cell->shift + len <= 32) {
|
||||
val = data[cell->idx] >> cell->shift;
|
||||
} else {
|
||||
u8 part = 32 - cell->shift;
|
||||
|
||||
val = data[cell->idx] >> cell->shift;
|
||||
val |= data[cell->idx + 1] << part;
|
||||
}
|
||||
|
||||
return val & ((1 << len) - 1);
|
||||
}
|
||||
|
||||
int tsens_read_calibration_legacy(struct tsens_priv *priv,
|
||||
const struct tsens_legacy_calibration_format *format,
|
||||
u32 *p1, u32 *p2,
|
||||
u32 *cdata0, u32 *cdata1)
|
||||
{
|
||||
u32 mode, invalid;
|
||||
u32 base1, base2;
|
||||
int i;
|
||||
|
||||
mode = tsens_read_cell(&format->mode, 2, cdata0, cdata1);
|
||||
invalid = tsens_read_cell(&format->invalid, 1, cdata0, cdata1);
|
||||
if (invalid)
|
||||
mode = NO_PT_CALIB;
|
||||
dev_dbg(priv->dev, "calibration mode is %d\n", mode);
|
||||
|
||||
base1 = tsens_read_cell(&format->base[0], format->base_len, cdata0, cdata1);
|
||||
base2 = tsens_read_cell(&format->base[1], format->base_len, cdata0, cdata1);
|
||||
|
||||
for (i = 0; i < priv->num_sensors; i++) {
|
||||
p1[i] = tsens_read_cell(&format->sp[i][0], format->sp_len, cdata0, cdata1);
|
||||
p2[i] = tsens_read_cell(&format->sp[i][1], format->sp_len, cdata0, cdata1);
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case ONE_PT_CALIB:
|
||||
for (i = 0; i < priv->num_sensors; i++)
|
||||
p1[i] = p1[i] + (base1 << format->base_shift);
|
||||
break;
|
||||
case TWO_PT_CALIB:
|
||||
for (i = 0; i < priv->num_sensors; i++)
|
||||
p2[i] = (p2[i] + base2) << format->base_shift;
|
||||
fallthrough;
|
||||
case ONE_PT_CALIB2:
|
||||
for (i = 0; i < priv->num_sensors; i++)
|
||||
p1[i] = (p1[i] + base1) << format->base_shift;
|
||||
break;
|
||||
default:
|
||||
dev_dbg(priv->dev, "calibrationless mode\n");
|
||||
for (i = 0; i < priv->num_sensors; i++) {
|
||||
p1[i] = 500;
|
||||
p2[i] = 780;
|
||||
}
|
||||
}
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use this function on devices where slope and offset calculations
|
||||
* depend on calibration data read from qfprom. On others the slope
|
||||
|
@ -459,12 +624,9 @@ static irqreturn_t tsens_irq_thread(int irq, void *data)
|
|||
{
|
||||
struct tsens_priv *priv = data;
|
||||
struct tsens_irq_data d;
|
||||
bool enable = true, disable = false;
|
||||
unsigned long flags;
|
||||
int temp, ret, i;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < priv->num_sensors; i++) {
|
||||
bool trigger = false;
|
||||
const struct tsens_sensor *s = &priv->sensor[i];
|
||||
u32 hw_id = s->hw_id;
|
||||
|
||||
|
@ -472,52 +634,8 @@ static irqreturn_t tsens_irq_thread(int irq, void *data)
|
|||
continue;
|
||||
if (!tsens_threshold_violated(priv, hw_id, &d))
|
||||
continue;
|
||||
ret = get_temp_tsens_valid(s, &temp);
|
||||
if (ret) {
|
||||
dev_err(priv->dev, "[%u] %s: error reading sensor\n",
|
||||
hw_id, __func__);
|
||||
continue;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&priv->ul_lock, flags);
|
||||
|
||||
tsens_read_irq_state(priv, hw_id, s, &d);
|
||||
|
||||
if (d.up_viol &&
|
||||
!masked_irq(hw_id, d.up_irq_mask, tsens_version(priv))) {
|
||||
tsens_set_interrupt(priv, hw_id, UPPER, disable);
|
||||
if (d.up_thresh > temp) {
|
||||
dev_dbg(priv->dev, "[%u] %s: re-arm upper\n",
|
||||
hw_id, __func__);
|
||||
tsens_set_interrupt(priv, hw_id, UPPER, enable);
|
||||
} else {
|
||||
trigger = true;
|
||||
/* Keep irq masked */
|
||||
}
|
||||
} else if (d.low_viol &&
|
||||
!masked_irq(hw_id, d.low_irq_mask, tsens_version(priv))) {
|
||||
tsens_set_interrupt(priv, hw_id, LOWER, disable);
|
||||
if (d.low_thresh < temp) {
|
||||
dev_dbg(priv->dev, "[%u] %s: re-arm low\n",
|
||||
hw_id, __func__);
|
||||
tsens_set_interrupt(priv, hw_id, LOWER, enable);
|
||||
} else {
|
||||
trigger = true;
|
||||
/* Keep irq masked */
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&priv->ul_lock, flags);
|
||||
|
||||
if (trigger) {
|
||||
dev_dbg(priv->dev, "[%u] %s: TZ update trigger (%d mC)\n",
|
||||
hw_id, __func__, temp);
|
||||
thermal_zone_device_update(s->tzd,
|
||||
THERMAL_EVENT_UNSPECIFIED);
|
||||
} else {
|
||||
dev_dbg(priv->dev, "[%u] %s: no violation: %d\n",
|
||||
hw_id, __func__, temp);
|
||||
}
|
||||
thermal_zone_device_update(s->tzd, THERMAL_EVENT_UNSPECIFIED);
|
||||
|
||||
if (tsens_version(priv) < VER_0_1) {
|
||||
/* Constraint: There is only 1 interrupt control register for all
|
||||
|
@ -983,6 +1101,9 @@ static const struct of_device_id tsens_table[] = {
|
|||
}, {
|
||||
.compatible = "qcom,msm8939-tsens",
|
||||
.data = &data_8939,
|
||||
}, {
|
||||
.compatible = "qcom,msm8956-tsens",
|
||||
.data = &data_8956,
|
||||
}, {
|
||||
.compatible = "qcom,msm8960-tsens",
|
||||
.data = &data_8960,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#ifndef __QCOM_TSENS_H__
|
||||
#define __QCOM_TSENS_H__
|
||||
|
||||
#define NO_PT_CALIB 0x0
|
||||
#define ONE_PT_CALIB 0x1
|
||||
#define ONE_PT_CALIB2 0x2
|
||||
#define TWO_PT_CALIB 0x3
|
||||
|
@ -17,6 +18,8 @@
|
|||
#define THRESHOLD_MAX_ADC_CODE 0x3ff
|
||||
#define THRESHOLD_MIN_ADC_CODE 0x0
|
||||
|
||||
#define MAX_SENSORS 16
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/thermal.h>
|
||||
#include <linux/regmap.h>
|
||||
|
@ -581,7 +584,48 @@ struct tsens_priv {
|
|||
struct tsens_sensor sensor[];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct tsens_single_value - internal representation of a single field inside nvmem calibration data
|
||||
* @idx: index into the u32 data array
|
||||
* @shift: the shift of the first bit in the value
|
||||
* @blob: index of the data blob to use for this cell
|
||||
*/
|
||||
struct tsens_single_value {
|
||||
u8 idx;
|
||||
u8 shift;
|
||||
u8 blob;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct tsens_legacy_calibration_format - description of calibration data used when parsing the legacy nvmem blob
|
||||
* @base_len: the length of the base fields inside calibration data
|
||||
* @base_shift: the shift to be applied to base data
|
||||
* @sp_len: the length of the sN_pM fields inside calibration data
|
||||
* @mode: descriptor of the calibration mode field
|
||||
* @invalid: descriptor of the calibration mode invalid field
|
||||
* @base: descriptors of the base0 and base1 fields
|
||||
* @sp: descriptors of the sN_pM fields
|
||||
*/
|
||||
struct tsens_legacy_calibration_format {
|
||||
unsigned int base_len;
|
||||
unsigned int base_shift;
|
||||
unsigned int sp_len;
|
||||
/* just two bits */
|
||||
struct tsens_single_value mode;
|
||||
/* on all platforms except 8974 invalid is the third bit of what downstream calls 'mode' */
|
||||
struct tsens_single_value invalid;
|
||||
struct tsens_single_value base[2];
|
||||
struct tsens_single_value sp[][2];
|
||||
};
|
||||
|
||||
char *qfprom_read(struct device *dev, const char *cname);
|
||||
int tsens_read_calibration_legacy(struct tsens_priv *priv,
|
||||
const struct tsens_legacy_calibration_format *format,
|
||||
u32 *p1, u32 *p2,
|
||||
u32 *cdata, u32 *csel);
|
||||
int tsens_read_calibration(struct tsens_priv *priv, int shift, u32 *p1, u32 *p2, bool backup);
|
||||
int tsens_calibrate_nvmem(struct tsens_priv *priv, int shift);
|
||||
int tsens_calibrate_common(struct tsens_priv *priv);
|
||||
void compute_intercept_slope(struct tsens_priv *priv, u32 *pt1, u32 *pt2, u32 mode);
|
||||
int init_common(struct tsens_priv *priv);
|
||||
int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp);
|
||||
|
@ -594,7 +638,7 @@ extern struct tsens_plat_data data_8960;
|
|||
extern struct tsens_plat_data data_8916, data_8939, data_8974, data_9607;
|
||||
|
||||
/* TSENS v1 targets */
|
||||
extern struct tsens_plat_data data_tsens_v1, data_8976;
|
||||
extern struct tsens_plat_data data_tsens_v1, data_8976, data_8956;
|
||||
|
||||
/* TSENS v2 targets */
|
||||
extern struct tsens_plat_data data_8996, data_ipq8074, data_tsens_v2;
|
||||
|
|
|
@ -60,7 +60,7 @@ enum adc_sort_mode {
|
|||
|
||||
#include "thermal_hwmon.h"
|
||||
|
||||
/**
|
||||
/*
|
||||
* The max sensors is two in rockchip SoCs.
|
||||
* Two sensors: CPU and GPU sensor.
|
||||
*/
|
||||
|
@ -169,7 +169,7 @@ struct rockchip_thermal_data {
|
|||
enum tshut_polarity tshut_polarity;
|
||||
};
|
||||
|
||||
/**
|
||||
/*
|
||||
* TSADC Sensor Register description:
|
||||
*
|
||||
* TSADCV2_* are used for RK3288 SoCs, the other chips can reuse it.
|
||||
|
@ -1339,7 +1339,7 @@ rockchip_thermal_register_sensor(struct platform_device *pdev,
|
|||
}
|
||||
|
||||
/**
|
||||
* Reset TSADC Controller, reset all tsadc registers.
|
||||
* rockchip_thermal_reset_controller - Reset TSADC Controller, reset all tsadc registers.
|
||||
* @reset: the reset controller of tsadc
|
||||
*/
|
||||
static void rockchip_thermal_reset_controller(struct reset_control *reset)
|
||||
|
@ -1354,7 +1354,6 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
|
|||
struct device_node *np = pdev->dev.of_node;
|
||||
struct rockchip_thermal_data *thermal;
|
||||
const struct of_device_id *match;
|
||||
struct resource *res;
|
||||
int irq;
|
||||
int i;
|
||||
int error;
|
||||
|
@ -1378,8 +1377,7 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
|
|||
if (!thermal->chip)
|
||||
return -EINVAL;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
thermal->regs = devm_ioremap_resource(&pdev->dev, res);
|
||||
thermal->regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
|
||||
if (IS_ERR(thermal->regs))
|
||||
return PTR_ERR(thermal->regs);
|
||||
|
||||
|
|
|
@ -91,7 +91,6 @@ static int spear_thermal_probe(struct platform_device *pdev)
|
|||
struct thermal_zone_device *spear_thermal = NULL;
|
||||
struct spear_thermal_dev *stdev;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct resource *res;
|
||||
int ret = 0, val;
|
||||
|
||||
if (!np || !of_property_read_u32(np, "st,thermal-flags", &val)) {
|
||||
|
@ -104,8 +103,7 @@ static int spear_thermal_probe(struct platform_device *pdev)
|
|||
return -ENOMEM;
|
||||
|
||||
/* Enable thermal sensor */
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
stdev->thermal_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
stdev->thermal_base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
|
||||
if (IS_ERR(stdev->thermal_base))
|
||||
return PTR_ERR(stdev->thermal_base);
|
||||
|
||||
|
|
|
@ -210,7 +210,7 @@ static int sun8i_h3_ths_calibrate(struct ths_device *tmdev,
|
|||
|
||||
regmap_update_bits(tmdev->regmap,
|
||||
SUN8I_THS_TEMP_CALIB + (4 * (i >> 1)),
|
||||
0xfff << offset,
|
||||
TEMP_CALIB_MASK << offset,
|
||||
caldata[i] << offset);
|
||||
}
|
||||
|
||||
|
@ -271,7 +271,7 @@ static int sun50i_h6_ths_calibrate(struct ths_device *tmdev,
|
|||
offset = (i % 2) * 16;
|
||||
regmap_update_bits(tmdev->regmap,
|
||||
SUN50I_H6_THS_TEMP_CALIB + (i / 2 * 4),
|
||||
0xfff << offset,
|
||||
TEMP_CALIB_MASK << offset,
|
||||
cdata << offset);
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,6 @@ static const struct thermal_zone_device_ops thermal_mmio_ops = {
|
|||
|
||||
static int thermal_mmio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *resource;
|
||||
struct thermal_mmio *sensor;
|
||||
int (*sensor_init_func)(struct platform_device *pdev,
|
||||
struct thermal_mmio *sensor);
|
||||
|
@ -51,8 +50,7 @@ static int thermal_mmio_probe(struct platform_device *pdev)
|
|||
if (!sensor)
|
||||
return -ENOMEM;
|
||||
|
||||
resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
sensor->mmio_base = devm_ioremap_resource(&pdev->dev, resource);
|
||||
sensor->mmio_base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
|
||||
if (IS_ERR(sensor->mmio_base))
|
||||
return PTR_ERR(sensor->mmio_base);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/**
|
||||
/*
|
||||
* uniphier_thermal.c - Socionext UniPhier thermal driver
|
||||
* Copyright 2014 Panasonic Corporation
|
||||
* Copyright 2016-2017 Socionext Inc.
|
||||
|
|
Загрузка…
Ссылка в новой задаче