965 lines
26 KiB
C
965 lines
26 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (c) 2020 MediaTek Inc.
|
|
*/
|
|
#include <dt-bindings/iio/mt635x-auxadc.h>
|
|
#include <linux/bits.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/iio/consumer.h>
|
|
#include <linux/io.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/module.h>
|
|
#include <linux/nvmem-consumer.h>
|
|
#include <linux/of.h>
|
|
#include <linux/of_device.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/regmap.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/thermal.h>
|
|
#include <linux/types.h>
|
|
/*=============================================================
|
|
*Local variable definition
|
|
*=============================================================
|
|
*/
|
|
|
|
struct pmic_tz_cali_data {
|
|
int cali_factor;
|
|
int slope1;
|
|
int slope2;
|
|
int intercept;
|
|
int o_vts;
|
|
struct iio_channel *iio_chan;
|
|
char *iio_chan_name;
|
|
};
|
|
|
|
struct pmic_tz_data {
|
|
int degc_cali;
|
|
int adc_cali_en;
|
|
int o_slope;
|
|
int o_slope_sign;
|
|
int id;
|
|
int pullup_volt;
|
|
int sensor_num;
|
|
struct pmic_tz_cali_data *cali_data;
|
|
int (*get_cali_data)(struct device *dev,
|
|
struct pmic_tz_data *tz_data);
|
|
};
|
|
|
|
struct pmic_temp_info {
|
|
struct device *dev;
|
|
struct pmic_tz_data *efuse_data;
|
|
};
|
|
|
|
struct pmic_temp_tz {
|
|
int tz_id;
|
|
struct pmic_temp_info *pmic_tz_info;
|
|
};
|
|
|
|
/*=============================================================*/
|
|
|
|
static int pmic_raw_to_temp(struct pmic_tz_cali_data *cali_data, int tz_id,
|
|
int val)
|
|
{
|
|
int t_current;
|
|
int y_curr = val;
|
|
|
|
t_current = cali_data[tz_id].intercept +
|
|
((cali_data[tz_id].slope1 * y_curr) / (cali_data[tz_id].slope2));
|
|
|
|
return t_current;
|
|
}
|
|
static void pmic_get_temp_convert_params(struct pmic_temp_info *data)
|
|
{
|
|
int vbe_t;
|
|
int factor;
|
|
int i = 0;
|
|
struct pmic_temp_info *temp_info = data;
|
|
struct pmic_tz_data *tz_data = temp_info->efuse_data;
|
|
struct pmic_tz_cali_data *cali = tz_data->cali_data;
|
|
|
|
for (i = 0; i < tz_data->sensor_num; i++) {
|
|
|
|
factor = cali[i].cali_factor;
|
|
|
|
cali[i].slope1 = (100 * 1000 * 10); /* 1000 is for 0.001 degree */
|
|
|
|
if (tz_data->o_slope_sign == 0)
|
|
cali[i].slope2 = -(factor + tz_data->o_slope);
|
|
else
|
|
cali[i].slope2 = -(factor - tz_data->o_slope);
|
|
|
|
vbe_t = (-1) * ((((cali[i].o_vts) * tz_data->pullup_volt)) / 4096) * 1000;
|
|
|
|
if (tz_data->o_slope_sign == 0)
|
|
cali[i].intercept = (vbe_t * 1000) / (-(factor + tz_data->o_slope * 10));
|
|
/*0.001 degree */
|
|
else
|
|
cali[i].intercept = (vbe_t * 1000) / (-(factor - tz_data->o_slope * 10));
|
|
/*0.001 degree */
|
|
|
|
cali[i].intercept = cali[i].intercept + (tz_data->degc_cali * (1000 / 2));
|
|
/* 1000 is for 0.1 degree */
|
|
}
|
|
}
|
|
|
|
static int pmic_get_temp(void *data, int *temp)
|
|
{
|
|
int val = 0;
|
|
int ret;
|
|
struct pmic_temp_tz *pmic_tz = (struct pmic_temp_tz *)data;
|
|
struct pmic_temp_info *temp_info = pmic_tz->pmic_tz_info;
|
|
struct pmic_tz_data *tz_data = temp_info->efuse_data;
|
|
struct pmic_tz_cali_data *cali_data = tz_data->cali_data;
|
|
|
|
ret = iio_read_channel_processed(cali_data[pmic_tz->tz_id].iio_chan, &val);
|
|
if (ret < 0) {
|
|
pr_notice("pmic_chip_temp read fail, ret=%d\n", ret);
|
|
*temp = THERMAL_TEMP_INVALID;
|
|
dev_info(temp_info->dev, "temp = %d\n", *temp);
|
|
return -EINVAL;
|
|
}
|
|
|
|
*temp = pmic_raw_to_temp(cali_data, pmic_tz->tz_id, val);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static const struct thermal_zone_of_device_ops pmic_temp_ops = {
|
|
.get_temp = pmic_get_temp,
|
|
};
|
|
static int pmic_temp_parse_iio_channel(struct device *dev,
|
|
struct pmic_temp_info *pmic_info)
|
|
{
|
|
int ret;
|
|
struct pmic_tz_data *tz_data = pmic_info->efuse_data;
|
|
struct pmic_tz_cali_data *cali_data = tz_data->cali_data;
|
|
int i = 0;
|
|
|
|
for (i = 0; i < tz_data->sensor_num; i++) {
|
|
cali_data[i].iio_chan = devm_iio_channel_get(dev, cali_data[i].iio_chan_name);
|
|
ret = PTR_ERR_OR_ZERO(cali_data[i].iio_chan);
|
|
if (ret) {
|
|
if (ret != -EPROBE_DEFER)
|
|
pr_info("pmic_chip_temp auxadc get fail, ret=%d\n", ret);
|
|
return ret;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int pmic_register_thermal_zones(struct pmic_temp_info *pmic_info)
|
|
{
|
|
struct pmic_tz_data *tz_data = pmic_info->efuse_data;
|
|
struct thermal_zone_device *tzdev;
|
|
struct device *dev = pmic_info->dev;
|
|
struct pmic_temp_tz *pmic_tz;
|
|
int i, ret;
|
|
|
|
for (i = 0; i < tz_data->sensor_num; i++) {
|
|
pmic_tz = devm_kzalloc(dev, sizeof(*pmic_tz), GFP_KERNEL);
|
|
if (!pmic_tz)
|
|
return -ENOMEM;
|
|
|
|
pmic_tz->tz_id = i;
|
|
pmic_tz->pmic_tz_info = pmic_info;
|
|
tzdev = devm_thermal_zone_of_sensor_register(dev, pmic_tz->tz_id,
|
|
pmic_tz, &pmic_temp_ops);
|
|
|
|
if (IS_ERR(tzdev)) {
|
|
ret = PTR_ERR(tzdev);
|
|
dev_info(dev,
|
|
"Error: Failed to register pmic tz %d, ret = %d\n",
|
|
pmic_tz->tz_id, ret);
|
|
return ret;
|
|
}
|
|
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int pmic_temp_probe(struct platform_device *pdev)
|
|
{
|
|
struct pmic_temp_info *pmic_info;
|
|
int ret;
|
|
|
|
if (!pdev->dev.of_node) {
|
|
dev_info(&pdev->dev, "Only DT based supported\n");
|
|
return -ENODEV;
|
|
}
|
|
|
|
pmic_info = devm_kzalloc(&pdev->dev, sizeof(*pmic_info), GFP_KERNEL);
|
|
if (!pmic_info)
|
|
return -ENOMEM;
|
|
|
|
pmic_info->dev = &pdev->dev;
|
|
pmic_info->efuse_data = (struct pmic_tz_data *)
|
|
of_device_get_match_data(&pdev->dev);
|
|
ret = pmic_temp_parse_iio_channel(&pdev->dev, pmic_info);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
ret = pmic_info->efuse_data->get_cali_data(&pdev->dev, pmic_info->efuse_data);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
pmic_get_temp_convert_params(pmic_info);
|
|
|
|
platform_set_drvdata(pdev, pmic_info);
|
|
|
|
ret = pmic_register_thermal_zones(pmic_info);
|
|
if (ret)
|
|
return ret;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static int mt6359_get_cali_data(struct device *dev, struct pmic_tz_data *tz_data)
|
|
{
|
|
size_t len = 0;
|
|
unsigned short *efuse_buff;
|
|
struct nvmem_cell *cell_1;
|
|
int i = 0;
|
|
struct pmic_tz_cali_data *cali_data = tz_data->cali_data;
|
|
|
|
cell_1 = devm_nvmem_cell_get(dev, "e_data1");
|
|
if (IS_ERR(cell_1)) {
|
|
dev_info(dev, "Error: Failed to get nvmem cell %s\n",
|
|
"e_data1");
|
|
return PTR_ERR(cell_1);
|
|
}
|
|
efuse_buff = (unsigned short *)nvmem_cell_read(cell_1, &len);
|
|
nvmem_cell_put(cell_1);
|
|
|
|
if (IS_ERR(efuse_buff))
|
|
return PTR_ERR(efuse_buff);
|
|
if (len != 2 * (tz_data->sensor_num + 1))
|
|
return -EINVAL;
|
|
|
|
tz_data->adc_cali_en = ((efuse_buff[0] & BIT(14)) >> 14);
|
|
if (tz_data->adc_cali_en == 0)
|
|
goto out;
|
|
|
|
for (i = 0; i < tz_data->sensor_num; i++)
|
|
cali_data[i].o_vts = efuse_buff[i+1] & GENMASK(12, 0);
|
|
|
|
tz_data->degc_cali = ((efuse_buff[0] & GENMASK(13, 8)) >> 8);
|
|
tz_data->o_slope_sign = ((efuse_buff[0] & BIT(7)) >> 7);
|
|
tz_data->o_slope = ((efuse_buff[0] & GENMASK(6, 1)) >> 1);
|
|
tz_data->id = (efuse_buff[0] & BIT(0));
|
|
|
|
if (tz_data->id == 0)
|
|
tz_data->o_slope = 0;
|
|
|
|
if (tz_data->degc_cali < 38 || tz_data->degc_cali > 60)
|
|
tz_data->degc_cali = 50;
|
|
out:
|
|
for (i = 0; i < tz_data->sensor_num; i++)
|
|
dev_info(dev, "[pmic_debug] tz_id=%d, o_vts = 0x%x\n", i, cali_data[i].o_vts);
|
|
dev_info(dev, "[pmic_debug] degc_cali= 0x%x\n", tz_data->degc_cali);
|
|
dev_info(dev, "[pmic_debug] adc_cali_en = 0x%x\n", tz_data->adc_cali_en);
|
|
dev_info(dev, "[pmic_debug] o_slope = 0x%x\n", tz_data->o_slope);
|
|
dev_info(dev, "[pmic_debug] o_slope_sign = 0x%x\n", tz_data->o_slope_sign);
|
|
dev_info(dev, "[pmic_debug] id = 0x%x\n", tz_data->id);
|
|
kfree(efuse_buff);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int mt6363_get_cali_data(struct device *dev, struct pmic_tz_data *tz_data)
|
|
{
|
|
size_t len = 0;
|
|
unsigned short *efuse_buff;
|
|
struct nvmem_cell *cell_1;
|
|
int i = 0;
|
|
struct pmic_tz_cali_data *cali_data = tz_data->cali_data;
|
|
|
|
cell_1 = devm_nvmem_cell_get(dev, "mt6363_e_data");
|
|
if (IS_ERR(cell_1)) {
|
|
dev_info(dev, "Error: Failed to get nvmem cell %s\n",
|
|
"mt6363_e_data");
|
|
return PTR_ERR(cell_1);
|
|
}
|
|
efuse_buff = (unsigned short *)nvmem_cell_read(cell_1, &len);
|
|
nvmem_cell_put(cell_1);
|
|
|
|
if (IS_ERR(efuse_buff))
|
|
return PTR_ERR(efuse_buff);
|
|
if (len != 8)
|
|
return -EINVAL;
|
|
|
|
tz_data->adc_cali_en = (efuse_buff[0] & BIT(6)) >> 6;
|
|
if (tz_data->adc_cali_en == 0)
|
|
goto out;
|
|
|
|
cali_data[0].o_vts = ((efuse_buff[0] & GENMASK(15, 8)) >> 8)
|
|
| ((efuse_buff[1] & GENMASK(4, 0)) << 8);
|
|
cali_data[1].o_vts = ((efuse_buff[1] & GENMASK(15, 8)) >> 8)
|
|
| (((efuse_buff[1] & GENMASK(7, 5)) >> 5) << 8)
|
|
| (((efuse_buff[2] & GENMASK(14, 13)) >> 13) << 11);
|
|
cali_data[2].o_vts = efuse_buff[2] & GENMASK(12, 0);
|
|
cali_data[3].o_vts = efuse_buff[3] & GENMASK(12, 0);
|
|
|
|
tz_data->degc_cali = (efuse_buff[0] & GENMASK(5, 0));
|
|
|
|
if (tz_data->degc_cali < 38 || tz_data->degc_cali > 60)
|
|
tz_data->degc_cali = 53;
|
|
|
|
out:
|
|
for (i = 0; i < tz_data->sensor_num; i++)
|
|
dev_info(dev, "[pmic6363_debug] tz_id=%d, o_vts = 0x%x\n", i, cali_data[i].o_vts);
|
|
|
|
dev_info(dev, "[pmic6363_debug] degc_cali= 0x%x\n", tz_data->degc_cali);
|
|
dev_info(dev, "[pmic6363_debug] adc_cali_en = 0x%x\n", tz_data->adc_cali_en);
|
|
dev_info(dev, "[pmic6363_debug] o_slope = 0x%x\n", tz_data->o_slope);
|
|
dev_info(dev, "[pmic6363_debug] o_slope_sign = 0x%x\n", tz_data->o_slope_sign);
|
|
dev_info(dev, "[pmic6363_debug] id = 0x%x\n", tz_data->id);
|
|
kfree(efuse_buff);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int mt6366_get_cali_data(struct device *dev, struct pmic_tz_data *tz_data)
|
|
{
|
|
size_t len = 0;
|
|
unsigned short *efuse_buff;
|
|
struct nvmem_cell *cell_1;
|
|
int i = 0;
|
|
struct pmic_tz_cali_data *cali_data = tz_data->cali_data;
|
|
|
|
cell_1 = devm_nvmem_cell_get(dev, "mt6366_e_data");
|
|
if (IS_ERR(cell_1)) {
|
|
dev_info(dev, "Error: Failed to get nvmem cell %s\n",
|
|
"mt6366_e_data");
|
|
return PTR_ERR(cell_1);
|
|
}
|
|
efuse_buff = (unsigned short *)nvmem_cell_read(cell_1, &len);
|
|
nvmem_cell_put(cell_1);
|
|
|
|
if (IS_ERR(efuse_buff))
|
|
return PTR_ERR(efuse_buff);
|
|
if (len != 12)
|
|
return -EINVAL;
|
|
|
|
tz_data->adc_cali_en = (efuse_buff[0] & BIT(8)) >> 8;
|
|
if (tz_data->adc_cali_en == 0)
|
|
goto out;
|
|
|
|
cali_data[0].o_vts = (efuse_buff[1] & GENMASK(12, 0));
|
|
cali_data[1].o_vts = (efuse_buff[4] & GENMASK(12, 0));
|
|
cali_data[2].o_vts = (efuse_buff[5] & GENMASK(12, 0));
|
|
cali_data[3].o_vts = ((efuse_buff[3] & GENMASK(15, 5)) >> 5);
|
|
|
|
tz_data->degc_cali = (efuse_buff[0] & GENMASK(5, 0));
|
|
tz_data->o_slope_sign = ((efuse_buff[2] & BIT(8)) >> 8);
|
|
tz_data->o_slope = (efuse_buff[2] & GENMASK(5, 0));
|
|
tz_data->id = ((efuse_buff[3] & BIT(4)) >> 4);
|
|
|
|
if (tz_data->id == 0)
|
|
tz_data->o_slope = 0;
|
|
|
|
if (tz_data->degc_cali < 38 || tz_data->degc_cali > 60)
|
|
tz_data->degc_cali = 53;
|
|
|
|
out:
|
|
for (i = 0; i < tz_data->sensor_num; i++)
|
|
dev_info(dev, "[pmic6366_debug] tz_id=%d, o_vts = 0x%x\n", i, cali_data[i].o_vts);
|
|
|
|
dev_info(dev, "[pmic6366_debug] degc_cali= 0x%x\n", tz_data->degc_cali);
|
|
dev_info(dev, "[pmic6366_debug] adc_cali_en = 0x%x\n", tz_data->adc_cali_en);
|
|
dev_info(dev, "[pmic6366_debug] o_slope = 0x%x\n", tz_data->o_slope);
|
|
dev_info(dev, "[pmic6366_debug] o_slope_sign = 0x%x\n", tz_data->o_slope_sign);
|
|
dev_info(dev, "[pmic6366_debug] id = 0x%x\n", tz_data->id);
|
|
kfree(efuse_buff);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
static int mt6368_get_cali_data(struct device *dev, struct pmic_tz_data *tz_data)
|
|
{
|
|
size_t len = 0;
|
|
unsigned short *efuse_buff;
|
|
struct nvmem_cell *cell_1;
|
|
int i = 0;
|
|
struct pmic_tz_cali_data *cali_data = tz_data->cali_data;
|
|
|
|
cell_1 = devm_nvmem_cell_get(dev, "mt6368_e_data");
|
|
if (IS_ERR(cell_1)) {
|
|
dev_info(dev, "Error: Failed to get nvmem cell %s\n",
|
|
"mt6368_e_data");
|
|
return PTR_ERR(cell_1);
|
|
}
|
|
efuse_buff = (unsigned short *)nvmem_cell_read(cell_1, &len);
|
|
nvmem_cell_put(cell_1);
|
|
|
|
if (IS_ERR(efuse_buff))
|
|
return PTR_ERR(efuse_buff);
|
|
|
|
|
|
if (len != 10)
|
|
return -EINVAL;
|
|
|
|
tz_data->adc_cali_en = (efuse_buff[0] & BIT(14)) >> 14;
|
|
if (tz_data->adc_cali_en == 0)
|
|
goto out;
|
|
|
|
cali_data[0].o_vts = efuse_buff[1] & GENMASK(12, 0);
|
|
cali_data[1].o_vts = (efuse_buff[2] & GENMASK(7, 0))
|
|
| (((efuse_buff[1] & GENMASK(15, 13)) >> 13) << 8)
|
|
| (((efuse_buff[3] & GENMASK(6, 5)) >> 5) << 11);
|
|
cali_data[2].o_vts = ((efuse_buff[2] & GENMASK(15, 8)) >> 8)
|
|
| ((efuse_buff[3] & GENMASK(4, 0)) << 8);
|
|
cali_data[3].o_vts = ((efuse_buff[3] & GENMASK(15, 8)) >> 8)
|
|
| ((efuse_buff[4] & GENMASK(4, 0)) << 8);
|
|
tz_data->degc_cali = ((efuse_buff[0] & GENMASK(13, 8)) >> 8);
|
|
|
|
if (tz_data->degc_cali < 38 || tz_data->degc_cali > 60)
|
|
tz_data->degc_cali = 53;
|
|
|
|
out:
|
|
for (i = 0; i < tz_data->sensor_num; i++)
|
|
dev_info(dev, "[pmic6368_debug] tz_id=%d, o_vts = 0x%x\n", i, cali_data[i].o_vts);
|
|
|
|
dev_info(dev, "[pmic6368_debug] degc_cali= 0x%x\n", tz_data->degc_cali);
|
|
dev_info(dev, "[pmic6368_debug] adc_cali_en = 0x%x\n", tz_data->adc_cali_en);
|
|
dev_info(dev, "[pmic6368_debug] o_slope = 0x%x\n", tz_data->o_slope);
|
|
dev_info(dev, "[pmic6368_debug] o_slope_sign = 0x%x\n", tz_data->o_slope_sign);
|
|
dev_info(dev, "[pmic6368_debug] id = 0x%x\n", tz_data->id);
|
|
kfree(efuse_buff);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int mt6369_get_cali_data(struct device *dev, struct pmic_tz_data *tz_data)
|
|
{
|
|
size_t len = 0;
|
|
unsigned short *efuse_buff;
|
|
struct nvmem_cell *cell_1;
|
|
int i = 0;
|
|
struct pmic_tz_cali_data *cali_data = tz_data->cali_data;
|
|
|
|
cell_1 = devm_nvmem_cell_get(dev, "mt6369_e_data");
|
|
if (IS_ERR(cell_1)) {
|
|
dev_info(dev, "Error: Failed to get nvmem cell %s\n",
|
|
"mt6369_e_data");
|
|
return PTR_ERR(cell_1);
|
|
}
|
|
efuse_buff = (unsigned short *)nvmem_cell_read(cell_1, &len);
|
|
nvmem_cell_put(cell_1);
|
|
|
|
if (IS_ERR(efuse_buff))
|
|
return PTR_ERR(efuse_buff);
|
|
if (len != 10)
|
|
return -EINVAL;
|
|
|
|
tz_data->adc_cali_en = (efuse_buff[0] & BIT(6)) >> 6;
|
|
if (tz_data->adc_cali_en == 0)
|
|
goto out;
|
|
|
|
cali_data[0].o_vts = ((efuse_buff[0] & GENMASK(15, 8)) >> 8)
|
|
| ((efuse_buff[1] & GENMASK(4, 0)) << 8);
|
|
cali_data[1].o_vts = ((efuse_buff[1] & GENMASK(15, 8)) >> 8)
|
|
| ((efuse_buff[2] & GENMASK(4, 0)) << 8);
|
|
cali_data[2].o_vts = ((efuse_buff[2] & GENMASK(15, 8)) >> 8)
|
|
| ((efuse_buff[3] & GENMASK(4, 0)) << 8);
|
|
cali_data[3].o_vts = ((efuse_buff[3] & GENMASK(15, 8)) >> 8)
|
|
| ((efuse_buff[4] & GENMASK(4, 0)) << 8);
|
|
|
|
tz_data->degc_cali = (efuse_buff[0] & GENMASK(5, 0));
|
|
|
|
if (tz_data->degc_cali < 38 || tz_data->degc_cali > 60)
|
|
tz_data->degc_cali = 53;
|
|
|
|
out:
|
|
for (i = 0; i < tz_data->sensor_num; i++)
|
|
dev_info(dev, "[pmic6369_debug] tz_id=%d, o_vts = 0x%x\n", i, cali_data[i].o_vts);
|
|
|
|
dev_info(dev, "[pmic6369_debug] degc_cali= 0x%x\n", tz_data->degc_cali);
|
|
dev_info(dev, "[pmic6369_debug] adc_cali_en = 0x%x\n", tz_data->adc_cali_en);
|
|
dev_info(dev, "[pmic6369_debug] o_slope = 0x%x\n", tz_data->o_slope);
|
|
dev_info(dev, "[pmic6369_debug] o_slope_sign = 0x%x\n", tz_data->o_slope_sign);
|
|
dev_info(dev, "[pmic6369_debug] id = 0x%x\n", tz_data->id);
|
|
kfree(efuse_buff);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int mt6373_get_cali_data(struct device *dev, struct pmic_tz_data *tz_data)
|
|
{
|
|
int i = 0;
|
|
struct pmic_tz_cali_data *cali_data = tz_data->cali_data;
|
|
struct device_node *cell_np;
|
|
struct platform_device *pmic_pdev = NULL;
|
|
struct regmap *map = NULL;
|
|
unsigned int pmic_val = 0;
|
|
|
|
cell_np = of_parse_phandle(dev->of_node, "nvmem-cells", 0);
|
|
if (cell_np) {
|
|
pmic_pdev = of_find_device_by_node(cell_np->parent);
|
|
if (pmic_pdev)
|
|
map = dev_get_regmap(pmic_pdev->dev.parent, NULL);
|
|
}
|
|
|
|
if (map) {
|
|
regmap_read(map, 0x11de, &pmic_val);
|
|
tz_data->adc_cali_en = (pmic_val & BIT(6)) >> 6;
|
|
if (tz_data->adc_cali_en) {
|
|
tz_data->degc_cali = pmic_val & GENMASK(5, 0);
|
|
if (tz_data->degc_cali < 38 || tz_data->degc_cali > 60)
|
|
tz_data->degc_cali = 53;
|
|
|
|
regmap_read(map, 0x11df, &pmic_val);
|
|
cali_data[0].o_vts = pmic_val & GENMASK(7, 0);
|
|
regmap_read(map, 0x11e0, &pmic_val);
|
|
cali_data[0].o_vts |= ((pmic_val & GENMASK(4, 0)) << 8);
|
|
|
|
cali_data[1].o_vts = (pmic_val & GENMASK(7, 5)) << 3;
|
|
regmap_read(map, 0x11e1, &pmic_val);
|
|
cali_data[1].o_vts |= (pmic_val & GENMASK(7, 0));
|
|
regmap_read(map, 0x11e3, &pmic_val);
|
|
cali_data[1].o_vts |= ((pmic_val & GENMASK(6, 5)) << 6);
|
|
|
|
cali_data[2].o_vts = (pmic_val & GENMASK(4, 0)) << 8;
|
|
regmap_read(map, 0x11e2, &pmic_val);
|
|
cali_data[2].o_vts |= (pmic_val & GENMASK(7, 0));
|
|
|
|
regmap_read(map, 0x11e4, &pmic_val);
|
|
cali_data[3].o_vts = pmic_val & GENMASK(7, 0);
|
|
regmap_read(map, 0x11e5, &pmic_val);
|
|
cali_data[3].o_vts |= ((pmic_val & GENMASK(4, 0)) << 8);
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < tz_data->sensor_num; i++)
|
|
dev_info(dev, "[pmic6373_debug] tz_id=%d, o_vts = 0x%x\n", i, cali_data[i].o_vts);
|
|
|
|
dev_info(dev, "[pmic6373_debug] degc_cali= 0x%x\n", tz_data->degc_cali);
|
|
dev_info(dev, "[pmic6373_debug] adc_cali_en = 0x%x\n", tz_data->adc_cali_en);
|
|
dev_info(dev, "[pmic6373_debug] o_slope = 0x%x\n", tz_data->o_slope);
|
|
dev_info(dev, "[pmic6373_debug] o_slope_sign = 0x%x\n", tz_data->o_slope_sign);
|
|
dev_info(dev, "[pmic6373_debug] id = 0x%x\n", tz_data->id);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int mt6338_get_cali_data(struct device *dev, struct pmic_tz_data *tz_data)
|
|
{
|
|
unsigned short efuse_buff;
|
|
int i = 0;
|
|
struct pmic_tz_cali_data *cali_data = tz_data->cali_data;
|
|
struct nvmem_device *nvmem_dev;
|
|
|
|
nvmem_dev = devm_nvmem_device_get(dev, "mt6338_e_data");
|
|
if (IS_ERR(nvmem_dev)) {
|
|
dev_info(dev, "Error: Failed to get nvmem %s\n", "mt6338_e_data");
|
|
return PTR_ERR(nvmem_dev);
|
|
}
|
|
|
|
nvmem_device_read(nvmem_dev, 0x1c, 1, &efuse_buff);
|
|
tz_data->adc_cali_en = (efuse_buff & BIT(6)) >> 6;
|
|
if (tz_data->adc_cali_en == 0)
|
|
goto out;
|
|
|
|
tz_data->degc_cali = (efuse_buff & GENMASK(5, 0));
|
|
nvmem_device_read(nvmem_dev, 0x1e, 1, &efuse_buff);
|
|
cali_data[0].o_vts = efuse_buff;
|
|
nvmem_device_read(nvmem_dev, 0x1f, 1, &efuse_buff);
|
|
cali_data[0].o_vts |= ((efuse_buff & GENMASK(5, 0)) << 8);
|
|
|
|
if (tz_data->degc_cali < 38 || tz_data->degc_cali > 60)
|
|
tz_data->degc_cali = 53;
|
|
|
|
out:
|
|
for (i = 0; i < tz_data->sensor_num; i++)
|
|
dev_info(dev, "[pmic6338_debug] tz_id=%d, o_vts = 0x%x\n", i, cali_data[i].o_vts);
|
|
|
|
dev_info(dev, "[pmic6338_debug] degc_cali= 0x%x\n", tz_data->degc_cali);
|
|
dev_info(dev, "[pmic6338_debug] adc_cali_en = 0x%x\n", tz_data->adc_cali_en);
|
|
dev_info(dev, "[pmic6338_debug] o_slope = 0x%x\n", tz_data->o_slope);
|
|
dev_info(dev, "[pmic6338_debug] o_slope_sign = 0x%x\n", tz_data->o_slope_sign);
|
|
dev_info(dev, "[pmic6338_debug] id = 0x%x\n", tz_data->id);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int mt6377_get_cali_data(struct device *dev, struct pmic_tz_data *tz_data)
|
|
{
|
|
size_t len = 0;
|
|
unsigned short *efuse_buff;
|
|
struct nvmem_cell *cell_1;
|
|
int i = 0;
|
|
struct pmic_tz_cali_data *cali_data = tz_data->cali_data;
|
|
|
|
cell_1 = devm_nvmem_cell_get(dev, "mt6377_e_data");
|
|
if (IS_ERR(cell_1)) {
|
|
dev_info(dev, "Error: Failed to get nvmem cell %s\n",
|
|
"mt6377_e_data");
|
|
return PTR_ERR(cell_1);
|
|
}
|
|
efuse_buff = (unsigned short *)nvmem_cell_read(cell_1, &len);
|
|
nvmem_cell_put(cell_1);
|
|
|
|
if (IS_ERR(efuse_buff))
|
|
return PTR_ERR(efuse_buff);
|
|
if (len != 10)
|
|
return -EINVAL;
|
|
|
|
tz_data->adc_cali_en = (efuse_buff[0] & BIT(0));
|
|
if (tz_data->adc_cali_en == 0)
|
|
goto out;
|
|
|
|
cali_data[0].o_vts = (efuse_buff[1] & GENMASK(7, 0))
|
|
| (efuse_buff[1] & GENMASK(12, 8));
|
|
cali_data[1].o_vts = (efuse_buff[2] & GENMASK(7, 0))
|
|
| (efuse_buff[2] & GENMASK(12, 8));
|
|
cali_data[2].o_vts = (efuse_buff[3] & GENMASK(7, 0))
|
|
| (efuse_buff[3] & GENMASK(12, 8));
|
|
cali_data[3].o_vts = (efuse_buff[4] & GENMASK(7, 0))
|
|
| (efuse_buff[4] & GENMASK(12, 8));
|
|
|
|
tz_data->degc_cali = ((efuse_buff[0] & GENMASK(6, 1)) >> 1);
|
|
tz_data->o_slope_sign = ((efuse_buff[0] & BIT(8)) >> 8);
|
|
tz_data->o_slope = ((efuse_buff[0] & GENMASK(14, 9)) >> 9);
|
|
tz_data->id = ((efuse_buff[0] & BIT(15)) >> 15);
|
|
|
|
if (tz_data->id == 0)
|
|
tz_data->o_slope = 0;
|
|
|
|
if (tz_data->degc_cali < 38 || tz_data->degc_cali > 60)
|
|
tz_data->degc_cali = 53;
|
|
|
|
out:
|
|
for (i = 0; i < tz_data->sensor_num; i++)
|
|
dev_info(dev, "[pmic6377_debug] tz_id=%d, o_vts = 0x%x\n", i, cali_data[i].o_vts);
|
|
|
|
dev_info(dev, "[pmic6377_debug] degc_cali= 0x%x\n", tz_data->degc_cali);
|
|
dev_info(dev, "[pmic6377_debug] adc_cali_en = 0x%x\n", tz_data->adc_cali_en);
|
|
dev_info(dev, "[pmic6377_debug] o_slope = 0x%x\n", tz_data->o_slope);
|
|
dev_info(dev, "[pmic6377_debug] o_slope_sign = 0x%x\n", tz_data->o_slope_sign);
|
|
dev_info(dev, "[pmic6377_debug] id = 0x%x\n", tz_data->id);
|
|
kfree(efuse_buff);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static struct pmic_tz_cali_data mt6359_cali_data[] = {
|
|
[0] = {
|
|
.cali_factor = 1681,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic_chip_temp",
|
|
},
|
|
[1] = {
|
|
.cali_factor = 1863,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic_buck1_temp",
|
|
},
|
|
[2] = {
|
|
.cali_factor = 1863,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic_buck2_temp",
|
|
},
|
|
[3] = {
|
|
.cali_factor = 1863,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic_buck3_temp",
|
|
}
|
|
};
|
|
|
|
static struct pmic_tz_cali_data mt6363_cali_data[] = {
|
|
[0] = {
|
|
.cali_factor = 1863,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic6363_ts1",
|
|
},
|
|
[1] = {
|
|
.cali_factor = 1863,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic6363_ts2",
|
|
},
|
|
[2] = {
|
|
.cali_factor = 1863,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic6363_ts3",
|
|
},
|
|
[3] = {
|
|
.cali_factor = 1863,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic6363_ts4",
|
|
}
|
|
};
|
|
|
|
static struct pmic_tz_cali_data mt6366_cali_data[] = {
|
|
[0] = {
|
|
.cali_factor = 1681,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic6366_ts1",
|
|
},
|
|
[1] = {
|
|
.cali_factor = 1863,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic6366_ts2",
|
|
},
|
|
[2] = {
|
|
.cali_factor = 1863,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic6366_ts3",
|
|
},
|
|
[3] = {
|
|
.cali_factor = 1863,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic6366_ts4",
|
|
}
|
|
};
|
|
|
|
static struct pmic_tz_cali_data mt6368_cali_data[] = {
|
|
[0] = {
|
|
.cali_factor = 1863,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic6368_ts1",
|
|
},
|
|
[1] = {
|
|
.cali_factor = 1863,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic6368_ts2",
|
|
},
|
|
[2] = {
|
|
.cali_factor = 1863,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic6368_ts3",
|
|
},
|
|
[3] = {
|
|
.cali_factor = 1863,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic6368_ts4",
|
|
}
|
|
};
|
|
|
|
static struct pmic_tz_cali_data mt6369_cali_data[] = {
|
|
[0] = {
|
|
.cali_factor = 1863,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic6369_ts1",
|
|
},
|
|
[1] = {
|
|
.cali_factor = 1863,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic6369_ts2",
|
|
},
|
|
[2] = {
|
|
.cali_factor = 1863,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic6369_ts3",
|
|
},
|
|
[3] = {
|
|
.cali_factor = 1863,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic6369_ts4",
|
|
}
|
|
};
|
|
|
|
static struct pmic_tz_cali_data mt6373_cali_data[] = {
|
|
[0] = {
|
|
.cali_factor = 1863,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic6373_ts1",
|
|
},
|
|
[1] = {
|
|
.cali_factor = 1863,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic6373_ts2",
|
|
},
|
|
[2] = {
|
|
.cali_factor = 1863,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic6373_ts3",
|
|
},
|
|
[3] = {
|
|
.cali_factor = 1863,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic6373_ts4",
|
|
}
|
|
};
|
|
|
|
static struct pmic_tz_cali_data mt6338_cali_data[] = {
|
|
[0] = {
|
|
.cali_factor = 1773,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic6338_ts",
|
|
}
|
|
};
|
|
|
|
static struct pmic_tz_cali_data mt6377_cali_data[] = {
|
|
[0] = {
|
|
.cali_factor = 1863,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic6377_ts1",
|
|
},
|
|
[1] = {
|
|
.cali_factor = 1863,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic6377_ts2",
|
|
},
|
|
[2] = {
|
|
.cali_factor = 1863,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic6377_ts3",
|
|
},
|
|
[3] = {
|
|
.cali_factor = 1863,
|
|
.o_vts = 1600,
|
|
.iio_chan_name = "pmic6377_ts4",
|
|
}
|
|
};
|
|
|
|
static struct pmic_tz_data mt6359_pmic_tz_data = {
|
|
.degc_cali = 50,
|
|
.adc_cali_en = 0,
|
|
.o_slope = 0,
|
|
.o_slope_sign = 0,
|
|
.id = 0,
|
|
.sensor_num = 4,
|
|
.pullup_volt = 1800,
|
|
.cali_data = mt6359_cali_data,
|
|
.get_cali_data = mt6359_get_cali_data,
|
|
};
|
|
|
|
static struct pmic_tz_data mt6363_pmic_tz_data = {
|
|
.degc_cali = 50,
|
|
.adc_cali_en = 0,
|
|
.o_slope = 0,
|
|
.o_slope_sign = 0,
|
|
.id = 0,
|
|
.sensor_num = 4,
|
|
.pullup_volt = 1840,
|
|
.cali_data = mt6363_cali_data,
|
|
.get_cali_data = mt6363_get_cali_data,
|
|
};
|
|
|
|
static struct pmic_tz_data mt6366_pmic_tz_data = {
|
|
.degc_cali = 50,
|
|
.adc_cali_en = 0,
|
|
.o_slope = 0,
|
|
.o_slope_sign = 0,
|
|
.id = 0,
|
|
.sensor_num = 4,
|
|
.pullup_volt = 1800,
|
|
.cali_data = mt6366_cali_data,
|
|
.get_cali_data = mt6366_get_cali_data,
|
|
};
|
|
|
|
static struct pmic_tz_data mt6368_pmic_tz_data = {
|
|
.degc_cali = 50,
|
|
.adc_cali_en = 0,
|
|
.o_slope = 0,
|
|
.o_slope_sign = 0,
|
|
.id = 0,
|
|
.sensor_num = 4,
|
|
.pullup_volt = 1840,
|
|
.cali_data = mt6368_cali_data,
|
|
.get_cali_data = mt6368_get_cali_data,
|
|
};
|
|
|
|
static struct pmic_tz_data mt6369_pmic_tz_data = {
|
|
.degc_cali = 50,
|
|
.adc_cali_en = 0,
|
|
.o_slope = 0,
|
|
.o_slope_sign = 0,
|
|
.id = 0,
|
|
.sensor_num = 4,
|
|
.pullup_volt = 1840,
|
|
.cali_data = mt6369_cali_data,
|
|
.get_cali_data = mt6369_get_cali_data,
|
|
};
|
|
|
|
static struct pmic_tz_data mt6373_pmic_tz_data = {
|
|
.degc_cali = 50,
|
|
.adc_cali_en = 0,
|
|
.o_slope = 0,
|
|
.o_slope_sign = 0,
|
|
.id = 0,
|
|
.sensor_num = 4,
|
|
.pullup_volt = 1840,
|
|
.cali_data = mt6373_cali_data,
|
|
.get_cali_data = mt6373_get_cali_data,
|
|
};
|
|
|
|
static struct pmic_tz_data mt6338_pmic_tz_data = {
|
|
.degc_cali = 50,
|
|
.adc_cali_en = 0,
|
|
.o_slope = 0,
|
|
.o_slope_sign = 0,
|
|
.id = 0,
|
|
.sensor_num = 1,
|
|
.pullup_volt = 1800,
|
|
.cali_data = mt6338_cali_data,
|
|
.get_cali_data = mt6338_get_cali_data,
|
|
};
|
|
|
|
static struct pmic_tz_data mt6377_pmic_tz_data = {
|
|
.degc_cali = 50,
|
|
.adc_cali_en = 0,
|
|
.o_slope = 0,
|
|
.o_slope_sign = 0,
|
|
.id = 0,
|
|
.sensor_num = 4,
|
|
.pullup_volt = 1840,
|
|
.cali_data = mt6377_cali_data,
|
|
.get_cali_data = mt6377_get_cali_data,
|
|
};
|
|
|
|
/*==================================================
|
|
* Support chips
|
|
*==================================================
|
|
*/
|
|
|
|
static const struct of_device_id pmic_temp_of_match[] = {
|
|
{
|
|
.compatible = "mediatek,mt6359-pmic-temp",
|
|
.data = (void *)&mt6359_pmic_tz_data,
|
|
},
|
|
{
|
|
.compatible = "mediatek,mt6363-pmic-temp",
|
|
.data = (void *)&mt6363_pmic_tz_data,
|
|
},
|
|
{
|
|
.compatible = "mediatek,mt6366-pmic-temp",
|
|
.data = (void *)&mt6366_pmic_tz_data,
|
|
},
|
|
{
|
|
.compatible = "mediatek,mt6368-pmic-temp",
|
|
.data = (void *)&mt6368_pmic_tz_data,
|
|
},
|
|
{
|
|
.compatible = "mediatek,mt6369-pmic-temp",
|
|
.data = (void *)&mt6369_pmic_tz_data,
|
|
},
|
|
{
|
|
.compatible = "mediatek,mt6373-pmic-temp",
|
|
.data = (void *)&mt6373_pmic_tz_data,
|
|
},
|
|
{
|
|
.compatible = "mediatek,mt6338-pmic-temp",
|
|
.data = (void *)&mt6338_pmic_tz_data,
|
|
},
|
|
{
|
|
.compatible = "mediatek,mt6377-pmic-temp",
|
|
.data = (void *)&mt6377_pmic_tz_data,
|
|
},
|
|
{},
|
|
};
|
|
MODULE_DEVICE_TABLE(of, pmic_temp_of_match);
|
|
|
|
static struct platform_driver pmic_temp_driver = {
|
|
.probe = pmic_temp_probe,
|
|
.driver = {
|
|
.name = "mtk-pmic-temp",
|
|
.of_match_table = pmic_temp_of_match,
|
|
},
|
|
};
|
|
|
|
module_platform_driver(pmic_temp_driver);
|
|
|
|
MODULE_AUTHOR("Henry Huang <henry.huang@mediatek.com>");
|
|
MODULE_DESCRIPTION("Mediatek pmic temp sensor driver");
|
|
MODULE_LICENSE("GPL v2");
|