brintos

brintos / linux-shallow public Read only

0
0
Text · 5.6 KiB · dc1c4ae Raw
190 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (c) 2019, Linaro Limited4 */5 6#include <linux/bitops.h>7#include <linux/regmap.h>8#include <linux/delay.h>9#include <linux/slab.h>10#include "tsens.h"11 12/* ----- SROT ------ */13#define SROT_HW_VER_OFF	0x000014#define SROT_CTRL_OFF		0x000415 16/* ----- TM ------ */17#define TM_INT_EN_OFF				0x000018#define TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF	0x000419#define TM_Sn_STATUS_OFF			0x004420#define TM_TRDY_OFF				0x008421#define TM_HIGH_LOW_INT_STATUS_OFF		0x008822#define TM_HIGH_LOW_Sn_INT_THRESHOLD_OFF	0x009023 24static struct tsens_legacy_calibration_format tsens_qcs404_nvmem = {25	.base_len = 8,26	.base_shift = 2,27	.sp_len = 6,28	.mode = { 4, 0 },29	.invalid = { 4, 2 },30	.base = { { 4, 3 }, { 4, 11 } },31	.sp = {32		{ { 0, 0 }, { 0, 6 } },33		{ { 0, 12 }, { 0, 18 } },34		{ { 0, 24 }, { 0, 30 } },35		{ { 1, 4 },  { 1, 10 } },36		{ { 1, 16 }, { 1, 22 } },37		{ { 2, 0 },  { 2, 6 } },38		{ { 2, 12 }, { 2, 18 } },39		{ { 2, 24 }, { 2, 30 } },40		{ { 3, 4 },  { 3, 10 } },41		{ { 3, 16 }, { 3, 22 } },42	},43};44 45static int calibrate_v1(struct tsens_priv *priv)46{47	u32 p1[10], p2[10];48	u32 *qfprom_cdata;49	int mode, ret;50 51	ret = tsens_calibrate_common(priv);52	if (!ret)53		return 0;54 55	qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");56	if (IS_ERR(qfprom_cdata))57		return PTR_ERR(qfprom_cdata);58 59	mode = tsens_read_calibration_legacy(priv, &tsens_qcs404_nvmem,60					     p1, p2,61					     qfprom_cdata, NULL);62 63	compute_intercept_slope(priv, p1, p2, mode);64	kfree(qfprom_cdata);65 66	return 0;67}68 69/* v1.x: msm8956,8976,qcs404,405 */70 71static struct tsens_features tsens_v1_feat = {72	.ver_major	= VER_1_X,73	.crit_int	= 0,74	.combo_int	= 0,75	.adc		= 1,76	.srot_split	= 1,77	.max_sensors	= 11,78	.trip_min_temp	= -40000,79	.trip_max_temp	= 120000,80};81 82static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = {83	/* ----- SROT ------ */84	/* VERSION */85	[VER_MAJOR] = REG_FIELD(SROT_HW_VER_OFF, 28, 31),86	[VER_MINOR] = REG_FIELD(SROT_HW_VER_OFF, 16, 27),87	[VER_STEP]  = REG_FIELD(SROT_HW_VER_OFF,  0, 15),88	/* CTRL_OFFSET */89	[TSENS_EN]     = REG_FIELD(SROT_CTRL_OFF, 0,  0),90	[TSENS_SW_RST] = REG_FIELD(SROT_CTRL_OFF, 1,  1),91	[SENSOR_EN]    = REG_FIELD(SROT_CTRL_OFF, 3, 13),92 93	/* ----- TM ------ */94	/* INTERRUPT ENABLE */95	[INT_EN]     = REG_FIELD(TM_INT_EN_OFF, 0, 0),96 97	/* UPPER/LOWER TEMPERATURE THRESHOLDS */98	REG_FIELD_FOR_EACH_SENSOR11(LOW_THRESH,    TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF,  0,  9),99	REG_FIELD_FOR_EACH_SENSOR11(UP_THRESH,     TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 10, 19),100 101	/* UPPER/LOWER INTERRUPTS [CLEAR/STATUS] */102	REG_FIELD_FOR_EACH_SENSOR11(LOW_INT_CLEAR, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 20, 20),103	REG_FIELD_FOR_EACH_SENSOR11(UP_INT_CLEAR,  TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 21, 21),104	[LOW_INT_STATUS_0] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  0,  0),105	[LOW_INT_STATUS_1] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  1,  1),106	[LOW_INT_STATUS_2] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  2,  2),107	[LOW_INT_STATUS_3] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  3,  3),108	[LOW_INT_STATUS_4] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  4,  4),109	[LOW_INT_STATUS_5] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  5,  5),110	[LOW_INT_STATUS_6] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  6,  6),111	[LOW_INT_STATUS_7] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  7,  7),112	[UP_INT_STATUS_0]  = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  8,  8),113	[UP_INT_STATUS_1]  = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  9,  9),114	[UP_INT_STATUS_2]  = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 10, 10),115	[UP_INT_STATUS_3]  = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 11, 11),116	[UP_INT_STATUS_4]  = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 12, 12),117	[UP_INT_STATUS_5]  = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 13, 13),118	[UP_INT_STATUS_6]  = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 14, 14),119	[UP_INT_STATUS_7]  = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 15, 15),120 121	/* NO CRITICAL INTERRUPT SUPPORT on v1 */122 123	/* Sn_STATUS */124	REG_FIELD_FOR_EACH_SENSOR11(LAST_TEMP,    TM_Sn_STATUS_OFF,  0,  9),125	REG_FIELD_FOR_EACH_SENSOR11(VALID,        TM_Sn_STATUS_OFF, 14, 14),126	/* xxx_STATUS bits: 1 == threshold violated */127	REG_FIELD_FOR_EACH_SENSOR11(MIN_STATUS,   TM_Sn_STATUS_OFF, 10, 10),128	REG_FIELD_FOR_EACH_SENSOR11(LOWER_STATUS, TM_Sn_STATUS_OFF, 11, 11),129	REG_FIELD_FOR_EACH_SENSOR11(UPPER_STATUS, TM_Sn_STATUS_OFF, 12, 12),130	/* No CRITICAL field on v1.x */131	REG_FIELD_FOR_EACH_SENSOR11(MAX_STATUS,   TM_Sn_STATUS_OFF, 13, 13),132 133	/* TRDY: 1=ready, 0=in progress */134	[TRDY] = REG_FIELD(TM_TRDY_OFF, 0, 0),135};136 137static int __init init_8956(struct tsens_priv *priv) {138	priv->sensor[0].slope = 3313;139	priv->sensor[1].slope = 3275;140	priv->sensor[2].slope = 3320;141	priv->sensor[3].slope = 3246;142	priv->sensor[4].slope = 3279;143	priv->sensor[5].slope = 3257;144	priv->sensor[6].slope = 3234;145	priv->sensor[7].slope = 3269;146	priv->sensor[8].slope = 3255;147	priv->sensor[9].slope = 3239;148	priv->sensor[10].slope = 3286;149 150	return init_common(priv);151}152 153static const struct tsens_ops ops_generic_v1 = {154	.init		= init_common,155	.calibrate	= calibrate_v1,156	.get_temp	= get_temp_tsens_valid,157};158 159struct tsens_plat_data data_tsens_v1 = {160	.ops		= &ops_generic_v1,161	.feat		= &tsens_v1_feat,162	.fields	= tsens_v1_regfields,163};164 165static const struct tsens_ops ops_8956 = {166	.init		= init_8956,167	.calibrate	= tsens_calibrate_common,168	.get_temp	= get_temp_tsens_valid,169};170 171struct tsens_plat_data data_8956 = {172	.num_sensors	= 11,173	.ops		= &ops_8956,174	.feat		= &tsens_v1_feat,175	.fields		= tsens_v1_regfields,176};177 178static const struct tsens_ops ops_8976 = {179	.init		= init_common,180	.calibrate	= tsens_calibrate_common,181	.get_temp	= get_temp_tsens_valid,182};183 184struct tsens_plat_data data_8976 = {185	.num_sensors	= 11,186	.ops		= &ops_8976,187	.feat		= &tsens_v1_feat,188	.fields		= tsens_v1_regfields,189};190