brintos

brintos / linux-shallow public Read only

0
0
Text · 45.2 KiB · 086ed42 Raw
1701 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2014-2016, Fuzhou Rockchip Electronics Co., Ltd4 * Caesar Wang <wxt@rock-chips.com>5 */6 7#include <linux/clk.h>8#include <linux/delay.h>9#include <linux/interrupt.h>10#include <linux/io.h>11#include <linux/module.h>12#include <linux/of.h>13#include <linux/of_address.h>14#include <linux/of_irq.h>15#include <linux/platform_device.h>16#include <linux/regmap.h>17#include <linux/reset.h>18#include <linux/thermal.h>19#include <linux/mfd/syscon.h>20#include <linux/pinctrl/consumer.h>21 22/*23 * If the temperature over a period of time High,24 * the resulting TSHUT gave CRU module,let it reset the entire chip,25 * or via GPIO give PMIC.26 */27enum tshut_mode {28	TSHUT_MODE_CRU = 0,29	TSHUT_MODE_GPIO,30};31 32/*33 * The system Temperature Sensors tshut(tshut) polarity34 * the bit 8 is tshut polarity.35 * 0: low active, 1: high active36 */37enum tshut_polarity {38	TSHUT_LOW_ACTIVE = 0,39	TSHUT_HIGH_ACTIVE,40};41 42/*43 * The conversion table has the adc value and temperature.44 * ADC_DECREMENT: the adc value is of diminishing.(e.g. rk3288_code_table)45 * ADC_INCREMENT: the adc value is incremental.(e.g. rk3368_code_table)46 */47enum adc_sort_mode {48	ADC_DECREMENT = 0,49	ADC_INCREMENT,50};51 52#include "thermal_hwmon.h"53 54/**55 * struct chip_tsadc_table - hold information about chip-specific differences56 * @id: conversion table57 * @length: size of conversion table58 * @data_mask: mask to apply on data inputs59 * @mode: sort mode of this adc variant (incrementing or decrementing)60 */61struct chip_tsadc_table {62	const struct tsadc_table *id;63	unsigned int length;64	u32 data_mask;65	enum adc_sort_mode mode;66};67 68/**69 * struct rockchip_tsadc_chip - hold the private data of tsadc chip70 * @chn_offset: the channel offset of the first channel71 * @chn_num: the channel number of tsadc chip72 * @tshut_temp: the hardware-controlled shutdown temperature value73 * @tshut_mode: the hardware-controlled shutdown mode (0:CRU 1:GPIO)74 * @tshut_polarity: the hardware-controlled active polarity (0:LOW 1:HIGH)75 * @initialize: SoC special initialize tsadc controller method76 * @irq_ack: clear the interrupt77 * @control: enable/disable method for the tsadc controller78 * @get_temp: get the temperature79 * @set_alarm_temp: set the high temperature interrupt80 * @set_tshut_temp: set the hardware-controlled shutdown temperature81 * @set_tshut_mode: set the hardware-controlled shutdown mode82 * @table: the chip-specific conversion table83 */84struct rockchip_tsadc_chip {85	/* The sensor id of chip correspond to the ADC channel */86	int chn_offset;87	int chn_num;88 89	/* The hardware-controlled tshut property */90	int tshut_temp;91	enum tshut_mode tshut_mode;92	enum tshut_polarity tshut_polarity;93 94	/* Chip-wide methods */95	void (*initialize)(struct regmap *grf,96			   void __iomem *reg, enum tshut_polarity p);97	void (*irq_ack)(void __iomem *reg);98	void (*control)(void __iomem *reg, bool on);99 100	/* Per-sensor methods */101	int (*get_temp)(const struct chip_tsadc_table *table,102			int chn, void __iomem *reg, int *temp);103	int (*set_alarm_temp)(const struct chip_tsadc_table *table,104			      int chn, void __iomem *reg, int temp);105	int (*set_tshut_temp)(const struct chip_tsadc_table *table,106			      int chn, void __iomem *reg, int temp);107	void (*set_tshut_mode)(int chn, void __iomem *reg, enum tshut_mode m);108 109	/* Per-table methods */110	struct chip_tsadc_table table;111};112 113/**114 * struct rockchip_thermal_sensor - hold the information of thermal sensor115 * @thermal:  pointer to the platform/configuration data116 * @tzd: pointer to a thermal zone117 * @id: identifier of the thermal sensor118 */119struct rockchip_thermal_sensor {120	struct rockchip_thermal_data *thermal;121	struct thermal_zone_device *tzd;122	int id;123};124 125/**126 * struct rockchip_thermal_data - hold the private data of thermal driver127 * @chip: pointer to the platform/configuration data128 * @pdev: platform device of thermal129 * @reset: the reset controller of tsadc130 * @sensors: array of thermal sensors131 * @clk: the controller clock is divided by the exteral 24MHz132 * @pclk: the advanced peripherals bus clock133 * @grf: the general register file will be used to do static set by software134 * @regs: the base address of tsadc controller135 * @tshut_temp: the hardware-controlled shutdown temperature value136 * @tshut_mode: the hardware-controlled shutdown mode (0:CRU 1:GPIO)137 * @tshut_polarity: the hardware-controlled active polarity (0:LOW 1:HIGH)138 */139struct rockchip_thermal_data {140	const struct rockchip_tsadc_chip *chip;141	struct platform_device *pdev;142	struct reset_control *reset;143 144	struct rockchip_thermal_sensor *sensors;145 146	struct clk *clk;147	struct clk *pclk;148 149	struct regmap *grf;150	void __iomem *regs;151 152	int tshut_temp;153	enum tshut_mode tshut_mode;154	enum tshut_polarity tshut_polarity;155};156 157/*158 * TSADC Sensor Register description:159 *160 * TSADCV2_* are used for RK3288 SoCs, the other chips can reuse it.161 * TSADCV3_* are used for newer SoCs than RK3288. (e.g: RK3228, RK3399)162 *163 */164#define TSADCV2_USER_CON			0x00165#define TSADCV2_AUTO_CON			0x04166#define TSADCV2_INT_EN				0x08167#define TSADCV2_INT_PD				0x0c168#define TSADCV3_AUTO_SRC_CON			0x0c169#define TSADCV3_HT_INT_EN			0x14170#define TSADCV3_HSHUT_GPIO_INT_EN		0x18171#define TSADCV3_HSHUT_CRU_INT_EN		0x1c172#define TSADCV3_INT_PD				0x24173#define TSADCV3_HSHUT_PD			0x28174#define TSADCV2_DATA(chn)			(0x20 + (chn) * 0x04)175#define TSADCV2_COMP_INT(chn)		        (0x30 + (chn) * 0x04)176#define TSADCV2_COMP_SHUT(chn)		        (0x40 + (chn) * 0x04)177#define TSADCV3_DATA(chn)			(0x2c + (chn) * 0x04)178#define TSADCV3_COMP_INT(chn)		        (0x6c + (chn) * 0x04)179#define TSADCV3_COMP_SHUT(chn)		        (0x10c + (chn) * 0x04)180#define TSADCV2_HIGHT_INT_DEBOUNCE		0x60181#define TSADCV2_HIGHT_TSHUT_DEBOUNCE		0x64182#define TSADCV3_HIGHT_INT_DEBOUNCE		0x14c183#define TSADCV3_HIGHT_TSHUT_DEBOUNCE		0x150184#define TSADCV2_AUTO_PERIOD			0x68185#define TSADCV2_AUTO_PERIOD_HT			0x6c186#define TSADCV3_AUTO_PERIOD			0x154187#define TSADCV3_AUTO_PERIOD_HT			0x158188 189#define TSADCV2_AUTO_EN				BIT(0)190#define TSADCV2_AUTO_EN_MASK			BIT(16)191#define TSADCV2_AUTO_SRC_EN(chn)		BIT(4 + (chn))192#define TSADCV3_AUTO_SRC_EN(chn)		BIT(chn)193#define TSADCV3_AUTO_SRC_EN_MASK(chn)		BIT(16 + chn)194#define TSADCV2_AUTO_TSHUT_POLARITY_HIGH	BIT(8)195#define TSADCV2_AUTO_TSHUT_POLARITY_MASK	BIT(24)196 197#define TSADCV3_AUTO_Q_SEL_EN			BIT(1)198 199#define TSADCV2_INT_SRC_EN(chn)			BIT(chn)200#define TSADCV2_INT_SRC_EN_MASK(chn)		BIT(16 + (chn))201#define TSADCV2_SHUT_2GPIO_SRC_EN(chn)		BIT(4 + (chn))202#define TSADCV2_SHUT_2CRU_SRC_EN(chn)		BIT(8 + (chn))203 204#define TSADCV2_INT_PD_CLEAR_MASK		~BIT(8)205#define TSADCV3_INT_PD_CLEAR_MASK		~BIT(16)206#define TSADCV4_INT_PD_CLEAR_MASK		0xffffffff207 208#define TSADCV2_DATA_MASK			0xfff209#define TSADCV3_DATA_MASK			0x3ff210#define TSADCV4_DATA_MASK			0x1ff211 212#define TSADCV2_HIGHT_INT_DEBOUNCE_COUNT	4213#define TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT	4214#define TSADCV2_AUTO_PERIOD_TIME		250 /* 250ms */215#define TSADCV2_AUTO_PERIOD_HT_TIME		50  /* 50ms */216#define TSADCV3_AUTO_PERIOD_TIME		1875 /* 2.5ms */217#define TSADCV3_AUTO_PERIOD_HT_TIME		1875 /* 2.5ms */218 219#define TSADCV5_AUTO_PERIOD_TIME		1622 /* 2.5ms */220#define TSADCV5_AUTO_PERIOD_HT_TIME		1622 /* 2.5ms */221#define TSADCV6_AUTO_PERIOD_TIME		5000 /* 2.5ms */222#define TSADCV6_AUTO_PERIOD_HT_TIME		5000 /* 2.5ms */223 224#define TSADCV2_USER_INTER_PD_SOC		0x340 /* 13 clocks */225#define TSADCV5_USER_INTER_PD_SOC		0xfc0 /* 97us, at least 90us */226 227#define GRF_SARADC_TESTBIT			0x0e644228#define GRF_TSADC_TESTBIT_L			0x0e648229#define GRF_TSADC_TESTBIT_H			0x0e64c230 231#define PX30_GRF_SOC_CON2			0x0408232 233#define RK3568_GRF_TSADC_CON			0x0600234#define RK3568_GRF_TSADC_ANA_REG0		(0x10001 << 0)235#define RK3568_GRF_TSADC_ANA_REG1		(0x10001 << 1)236#define RK3568_GRF_TSADC_ANA_REG2		(0x10001 << 2)237#define RK3568_GRF_TSADC_TSEN			(0x10001 << 8)238 239#define RK3588_GRF0_TSADC_CON			0x0100240 241#define RK3588_GRF0_TSADC_TRM			(0xff0077 << 0)242#define RK3588_GRF0_TSADC_SHUT_2CRU		(0x30003 << 10)243#define RK3588_GRF0_TSADC_SHUT_2GPIO		(0x70007 << 12)244 245#define GRF_SARADC_TESTBIT_ON			(0x10001 << 2)246#define GRF_TSADC_TESTBIT_H_ON			(0x10001 << 2)247#define GRF_TSADC_VCM_EN_L			(0x10001 << 7)248#define GRF_TSADC_VCM_EN_H			(0x10001 << 7)249 250#define GRF_CON_TSADC_CH_INV			(0x10001 << 1)251 252/**253 * struct tsadc_table - code to temperature conversion table254 * @code: the value of adc channel255 * @temp: the temperature256 * Note:257 * code to temperature mapping of the temperature sensor is a piece wise linear258 * curve.Any temperature, code faling between to 2 give temperatures can be259 * linearly interpolated.260 * Code to Temperature mapping should be updated based on manufacturer results.261 */262struct tsadc_table {263	u32 code;264	int temp;265};266 267static const struct tsadc_table rv1108_table[] = {268	{0, -40000},269	{374, -40000},270	{382, -35000},271	{389, -30000},272	{397, -25000},273	{405, -20000},274	{413, -15000},275	{421, -10000},276	{429, -5000},277	{436, 0},278	{444, 5000},279	{452, 10000},280	{460, 15000},281	{468, 20000},282	{476, 25000},283	{483, 30000},284	{491, 35000},285	{499, 40000},286	{507, 45000},287	{515, 50000},288	{523, 55000},289	{531, 60000},290	{539, 65000},291	{547, 70000},292	{555, 75000},293	{562, 80000},294	{570, 85000},295	{578, 90000},296	{586, 95000},297	{594, 100000},298	{602, 105000},299	{610, 110000},300	{618, 115000},301	{626, 120000},302	{634, 125000},303	{TSADCV2_DATA_MASK, 125000},304};305 306static const struct tsadc_table rk3228_code_table[] = {307	{0, -40000},308	{588, -40000},309	{593, -35000},310	{598, -30000},311	{603, -25000},312	{608, -20000},313	{613, -15000},314	{618, -10000},315	{623, -5000},316	{629, 0},317	{634, 5000},318	{639, 10000},319	{644, 15000},320	{649, 20000},321	{654, 25000},322	{660, 30000},323	{665, 35000},324	{670, 40000},325	{675, 45000},326	{681, 50000},327	{686, 55000},328	{691, 60000},329	{696, 65000},330	{702, 70000},331	{707, 75000},332	{712, 80000},333	{717, 85000},334	{723, 90000},335	{728, 95000},336	{733, 100000},337	{738, 105000},338	{744, 110000},339	{749, 115000},340	{754, 120000},341	{760, 125000},342	{TSADCV2_DATA_MASK, 125000},343};344 345static const struct tsadc_table rk3288_code_table[] = {346	{TSADCV2_DATA_MASK, -40000},347	{3800, -40000},348	{3792, -35000},349	{3783, -30000},350	{3774, -25000},351	{3765, -20000},352	{3756, -15000},353	{3747, -10000},354	{3737, -5000},355	{3728, 0},356	{3718, 5000},357	{3708, 10000},358	{3698, 15000},359	{3688, 20000},360	{3678, 25000},361	{3667, 30000},362	{3656, 35000},363	{3645, 40000},364	{3634, 45000},365	{3623, 50000},366	{3611, 55000},367	{3600, 60000},368	{3588, 65000},369	{3575, 70000},370	{3563, 75000},371	{3550, 80000},372	{3537, 85000},373	{3524, 90000},374	{3510, 95000},375	{3496, 100000},376	{3482, 105000},377	{3467, 110000},378	{3452, 115000},379	{3437, 120000},380	{3421, 125000},381	{0, 125000},382};383 384static const struct tsadc_table rk3328_code_table[] = {385	{0, -40000},386	{296, -40000},387	{304, -35000},388	{313, -30000},389	{331, -20000},390	{340, -15000},391	{349, -10000},392	{359, -5000},393	{368, 0},394	{378, 5000},395	{388, 10000},396	{398, 15000},397	{408, 20000},398	{418, 25000},399	{429, 30000},400	{440, 35000},401	{451, 40000},402	{462, 45000},403	{473, 50000},404	{485, 55000},405	{496, 60000},406	{508, 65000},407	{521, 70000},408	{533, 75000},409	{546, 80000},410	{559, 85000},411	{572, 90000},412	{586, 95000},413	{600, 100000},414	{614, 105000},415	{629, 110000},416	{644, 115000},417	{659, 120000},418	{675, 125000},419	{TSADCV2_DATA_MASK, 125000},420};421 422static const struct tsadc_table rk3368_code_table[] = {423	{0, -40000},424	{106, -40000},425	{108, -35000},426	{110, -30000},427	{112, -25000},428	{114, -20000},429	{116, -15000},430	{118, -10000},431	{120, -5000},432	{122, 0},433	{124, 5000},434	{126, 10000},435	{128, 15000},436	{130, 20000},437	{132, 25000},438	{134, 30000},439	{136, 35000},440	{138, 40000},441	{140, 45000},442	{142, 50000},443	{144, 55000},444	{146, 60000},445	{148, 65000},446	{150, 70000},447	{152, 75000},448	{154, 80000},449	{156, 85000},450	{158, 90000},451	{160, 95000},452	{162, 100000},453	{163, 105000},454	{165, 110000},455	{167, 115000},456	{169, 120000},457	{171, 125000},458	{TSADCV3_DATA_MASK, 125000},459};460 461static const struct tsadc_table rk3399_code_table[] = {462	{0, -40000},463	{402, -40000},464	{410, -35000},465	{419, -30000},466	{427, -25000},467	{436, -20000},468	{444, -15000},469	{453, -10000},470	{461, -5000},471	{470, 0},472	{478, 5000},473	{487, 10000},474	{496, 15000},475	{504, 20000},476	{513, 25000},477	{521, 30000},478	{530, 35000},479	{538, 40000},480	{547, 45000},481	{555, 50000},482	{564, 55000},483	{573, 60000},484	{581, 65000},485	{590, 70000},486	{599, 75000},487	{607, 80000},488	{616, 85000},489	{624, 90000},490	{633, 95000},491	{642, 100000},492	{650, 105000},493	{659, 110000},494	{668, 115000},495	{677, 120000},496	{685, 125000},497	{TSADCV3_DATA_MASK, 125000},498};499 500static const struct tsadc_table rk3568_code_table[] = {501	{0, -40000},502	{1584, -40000},503	{1620, -35000},504	{1652, -30000},505	{1688, -25000},506	{1720, -20000},507	{1756, -15000},508	{1788, -10000},509	{1824, -5000},510	{1856, 0},511	{1892, 5000},512	{1924, 10000},513	{1956, 15000},514	{1992, 20000},515	{2024, 25000},516	{2060, 30000},517	{2092, 35000},518	{2128, 40000},519	{2160, 45000},520	{2196, 50000},521	{2228, 55000},522	{2264, 60000},523	{2300, 65000},524	{2332, 70000},525	{2368, 75000},526	{2400, 80000},527	{2436, 85000},528	{2468, 90000},529	{2500, 95000},530	{2536, 100000},531	{2572, 105000},532	{2604, 110000},533	{2636, 115000},534	{2672, 120000},535	{2704, 125000},536	{TSADCV2_DATA_MASK, 125000},537};538 539static const struct tsadc_table rk3588_code_table[] = {540	{0, -40000},541	{215, -40000},542	{285, 25000},543	{350, 85000},544	{395, 125000},545	{TSADCV4_DATA_MASK, 125000},546};547 548static u32 rk_tsadcv2_temp_to_code(const struct chip_tsadc_table *table,549				   int temp)550{551	int high, low, mid;552	unsigned long num;553	unsigned int denom;554	u32 error = table->data_mask;555 556	low = 0;557	high = (table->length - 1) - 1; /* ignore the last check for table */558	mid = (high + low) / 2;559 560	/* Return mask code data when the temp is over table range */561	if (temp < table->id[low].temp || temp > table->id[high].temp)562		goto exit;563 564	while (low <= high) {565		if (temp == table->id[mid].temp)566			return table->id[mid].code;567		else if (temp < table->id[mid].temp)568			high = mid - 1;569		else570			low = mid + 1;571		mid = (low + high) / 2;572	}573 574	/*575	 * The conversion code granularity provided by the table. Let's576	 * assume that the relationship between temperature and577	 * analog value between 2 table entries is linear and interpolate578	 * to produce less granular result.579	 */580	num = abs(table->id[mid + 1].code - table->id[mid].code);581	num *= temp - table->id[mid].temp;582	denom = table->id[mid + 1].temp - table->id[mid].temp;583 584	switch (table->mode) {585	case ADC_DECREMENT:586		return table->id[mid].code - (num / denom);587	case ADC_INCREMENT:588		return table->id[mid].code + (num / denom);589	default:590		pr_err("%s: unknown table mode: %d\n", __func__, table->mode);591		return error;592	}593 594exit:595	pr_err("%s: invalid temperature, temp=%d error=%d\n",596	       __func__, temp, error);597	return error;598}599 600static int rk_tsadcv2_code_to_temp(const struct chip_tsadc_table *table,601				   u32 code, int *temp)602{603	unsigned int low = 1;604	unsigned int high = table->length - 1;605	unsigned int mid = (low + high) / 2;606	unsigned int num;607	unsigned long denom;608 609	WARN_ON(table->length < 2);610 611	switch (table->mode) {612	case ADC_DECREMENT:613		code &= table->data_mask;614		if (code <= table->id[high].code)615			return -EAGAIN;		/* Incorrect reading */616 617		while (low <= high) {618			if (code >= table->id[mid].code &&619			    code < table->id[mid - 1].code)620				break;621			else if (code < table->id[mid].code)622				low = mid + 1;623			else624				high = mid - 1;625 626			mid = (low + high) / 2;627		}628		break;629	case ADC_INCREMENT:630		code &= table->data_mask;631		if (code < table->id[low].code)632			return -EAGAIN;		/* Incorrect reading */633 634		while (low <= high) {635			if (code <= table->id[mid].code &&636			    code > table->id[mid - 1].code)637				break;638			else if (code > table->id[mid].code)639				low = mid + 1;640			else641				high = mid - 1;642 643			mid = (low + high) / 2;644		}645		break;646	default:647		pr_err("%s: unknown table mode: %d\n", __func__, table->mode);648		return -EINVAL;649	}650 651	/*652	 * The 5C granularity provided by the table is too much. Let's653	 * assume that the relationship between sensor readings and654	 * temperature between 2 table entries is linear and interpolate655	 * to produce less granular result.656	 */657	num = table->id[mid].temp - table->id[mid - 1].temp;658	num *= abs(table->id[mid - 1].code - code);659	denom = abs(table->id[mid - 1].code - table->id[mid].code);660	*temp = table->id[mid - 1].temp + (num / denom);661 662	return 0;663}664 665/**666 * rk_tsadcv2_initialize - initialize TASDC Controller.667 * @grf: the general register file will be used to do static set by software668 * @regs: the base address of tsadc controller669 * @tshut_polarity: the hardware-controlled active polarity (0:LOW 1:HIGH)670 *671 * (1) Set TSADC_V2_AUTO_PERIOD:672 *     Configure the interleave between every two accessing of673 *     TSADC in normal operation.674 *675 * (2) Set TSADCV2_AUTO_PERIOD_HT:676 *     Configure the interleave between every two accessing of677 *     TSADC after the temperature is higher than COM_SHUT or COM_INT.678 *679 * (3) Set TSADCV2_HIGH_INT_DEBOUNCE and TSADC_HIGHT_TSHUT_DEBOUNCE:680 *     If the temperature is higher than COMP_INT or COMP_SHUT for681 *     "debounce" times, TSADC controller will generate interrupt or TSHUT.682 */683static void rk_tsadcv2_initialize(struct regmap *grf, void __iomem *regs,684				  enum tshut_polarity tshut_polarity)685{686	if (tshut_polarity == TSHUT_HIGH_ACTIVE)687		writel_relaxed(0U | TSADCV2_AUTO_TSHUT_POLARITY_HIGH,688			       regs + TSADCV2_AUTO_CON);689	else690		writel_relaxed(0U & ~TSADCV2_AUTO_TSHUT_POLARITY_HIGH,691			       regs + TSADCV2_AUTO_CON);692 693	writel_relaxed(TSADCV2_AUTO_PERIOD_TIME, regs + TSADCV2_AUTO_PERIOD);694	writel_relaxed(TSADCV2_HIGHT_INT_DEBOUNCE_COUNT,695		       regs + TSADCV2_HIGHT_INT_DEBOUNCE);696	writel_relaxed(TSADCV2_AUTO_PERIOD_HT_TIME,697		       regs + TSADCV2_AUTO_PERIOD_HT);698	writel_relaxed(TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT,699		       regs + TSADCV2_HIGHT_TSHUT_DEBOUNCE);700}701 702/**703 * rk_tsadcv3_initialize - initialize TASDC Controller.704 * @grf: the general register file will be used to do static set by software705 * @regs: the base address of tsadc controller706 * @tshut_polarity: the hardware-controlled active polarity (0:LOW 1:HIGH)707 *708 * (1) The tsadc control power sequence.709 *710 * (2) Set TSADC_V2_AUTO_PERIOD:711 *     Configure the interleave between every two accessing of712 *     TSADC in normal operation.713 *714 * (2) Set TSADCV2_AUTO_PERIOD_HT:715 *     Configure the interleave between every two accessing of716 *     TSADC after the temperature is higher than COM_SHUT or COM_INT.717 *718 * (3) Set TSADCV2_HIGH_INT_DEBOUNCE and TSADC_HIGHT_TSHUT_DEBOUNCE:719 *     If the temperature is higher than COMP_INT or COMP_SHUT for720 *     "debounce" times, TSADC controller will generate interrupt or TSHUT.721 */722static void rk_tsadcv3_initialize(struct regmap *grf, void __iomem *regs,723				  enum tshut_polarity tshut_polarity)724{725	/* The tsadc control power sequence */726	if (IS_ERR(grf)) {727		/* Set interleave value to workround ic time sync issue */728		writel_relaxed(TSADCV2_USER_INTER_PD_SOC, regs +729			       TSADCV2_USER_CON);730 731		writel_relaxed(TSADCV2_AUTO_PERIOD_TIME,732			       regs + TSADCV2_AUTO_PERIOD);733		writel_relaxed(TSADCV2_HIGHT_INT_DEBOUNCE_COUNT,734			       regs + TSADCV2_HIGHT_INT_DEBOUNCE);735		writel_relaxed(TSADCV2_AUTO_PERIOD_HT_TIME,736			       regs + TSADCV2_AUTO_PERIOD_HT);737		writel_relaxed(TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT,738			       regs + TSADCV2_HIGHT_TSHUT_DEBOUNCE);739 740	} else {741		/* Enable the voltage common mode feature */742		regmap_write(grf, GRF_TSADC_TESTBIT_L, GRF_TSADC_VCM_EN_L);743		regmap_write(grf, GRF_TSADC_TESTBIT_H, GRF_TSADC_VCM_EN_H);744 745		usleep_range(15, 100); /* The spec note says at least 15 us */746		regmap_write(grf, GRF_SARADC_TESTBIT, GRF_SARADC_TESTBIT_ON);747		regmap_write(grf, GRF_TSADC_TESTBIT_H, GRF_TSADC_TESTBIT_H_ON);748		usleep_range(90, 200); /* The spec note says at least 90 us */749 750		writel_relaxed(TSADCV3_AUTO_PERIOD_TIME,751			       regs + TSADCV2_AUTO_PERIOD);752		writel_relaxed(TSADCV2_HIGHT_INT_DEBOUNCE_COUNT,753			       regs + TSADCV2_HIGHT_INT_DEBOUNCE);754		writel_relaxed(TSADCV3_AUTO_PERIOD_HT_TIME,755			       regs + TSADCV2_AUTO_PERIOD_HT);756		writel_relaxed(TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT,757			       regs + TSADCV2_HIGHT_TSHUT_DEBOUNCE);758	}759 760	if (tshut_polarity == TSHUT_HIGH_ACTIVE)761		writel_relaxed(0U | TSADCV2_AUTO_TSHUT_POLARITY_HIGH,762			       regs + TSADCV2_AUTO_CON);763	else764		writel_relaxed(0U & ~TSADCV2_AUTO_TSHUT_POLARITY_HIGH,765			       regs + TSADCV2_AUTO_CON);766}767 768static void rk_tsadcv4_initialize(struct regmap *grf, void __iomem *regs,769				  enum tshut_polarity tshut_polarity)770{771	rk_tsadcv2_initialize(grf, regs, tshut_polarity);772	regmap_write(grf, PX30_GRF_SOC_CON2, GRF_CON_TSADC_CH_INV);773}774 775static void rk_tsadcv7_initialize(struct regmap *grf, void __iomem *regs,776				  enum tshut_polarity tshut_polarity)777{778	writel_relaxed(TSADCV5_USER_INTER_PD_SOC, regs + TSADCV2_USER_CON);779	writel_relaxed(TSADCV5_AUTO_PERIOD_TIME, regs + TSADCV2_AUTO_PERIOD);780	writel_relaxed(TSADCV2_HIGHT_INT_DEBOUNCE_COUNT,781		       regs + TSADCV2_HIGHT_INT_DEBOUNCE);782	writel_relaxed(TSADCV5_AUTO_PERIOD_HT_TIME,783		       regs + TSADCV2_AUTO_PERIOD_HT);784	writel_relaxed(TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT,785		       regs + TSADCV2_HIGHT_TSHUT_DEBOUNCE);786 787	if (tshut_polarity == TSHUT_HIGH_ACTIVE)788		writel_relaxed(0U | TSADCV2_AUTO_TSHUT_POLARITY_HIGH,789			       regs + TSADCV2_AUTO_CON);790	else791		writel_relaxed(0U & ~TSADCV2_AUTO_TSHUT_POLARITY_HIGH,792			       regs + TSADCV2_AUTO_CON);793 794	/*795	 * The general register file will is optional796	 * and might not be available.797	 */798	if (!IS_ERR(grf)) {799		regmap_write(grf, RK3568_GRF_TSADC_CON, RK3568_GRF_TSADC_TSEN);800		/*801		 * RK3568 TRM, section 18.5. requires a delay no less802		 * than 10us between the rising edge of tsadc_tsen_en803		 * and the rising edge of tsadc_ana_reg_0/1/2.804		 */805		udelay(15);806		regmap_write(grf, RK3568_GRF_TSADC_CON, RK3568_GRF_TSADC_ANA_REG0);807		regmap_write(grf, RK3568_GRF_TSADC_CON, RK3568_GRF_TSADC_ANA_REG1);808		regmap_write(grf, RK3568_GRF_TSADC_CON, RK3568_GRF_TSADC_ANA_REG2);809 810		/*811		 * RK3568 TRM, section 18.5. requires a delay no less812		 * than 90us after the rising edge of tsadc_ana_reg_0/1/2.813		 */814		usleep_range(100, 200);815	}816}817 818static void rk_tsadcv8_initialize(struct regmap *grf, void __iomem *regs,819				  enum tshut_polarity tshut_polarity)820{821	writel_relaxed(TSADCV6_AUTO_PERIOD_TIME, regs + TSADCV3_AUTO_PERIOD);822	writel_relaxed(TSADCV6_AUTO_PERIOD_HT_TIME,823		       regs + TSADCV3_AUTO_PERIOD_HT);824	writel_relaxed(TSADCV2_HIGHT_INT_DEBOUNCE_COUNT,825		       regs + TSADCV3_HIGHT_INT_DEBOUNCE);826	writel_relaxed(TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT,827		       regs + TSADCV3_HIGHT_TSHUT_DEBOUNCE);828	if (tshut_polarity == TSHUT_HIGH_ACTIVE)829		writel_relaxed(TSADCV2_AUTO_TSHUT_POLARITY_HIGH |830			       TSADCV2_AUTO_TSHUT_POLARITY_MASK,831			       regs + TSADCV2_AUTO_CON);832	else833		writel_relaxed(TSADCV2_AUTO_TSHUT_POLARITY_MASK,834			       regs + TSADCV2_AUTO_CON);835}836 837static void rk_tsadcv2_irq_ack(void __iomem *regs)838{839	u32 val;840 841	val = readl_relaxed(regs + TSADCV2_INT_PD);842	writel_relaxed(val & TSADCV2_INT_PD_CLEAR_MASK, regs + TSADCV2_INT_PD);843}844 845static void rk_tsadcv3_irq_ack(void __iomem *regs)846{847	u32 val;848 849	val = readl_relaxed(regs + TSADCV2_INT_PD);850	writel_relaxed(val & TSADCV3_INT_PD_CLEAR_MASK, regs + TSADCV2_INT_PD);851}852 853static void rk_tsadcv4_irq_ack(void __iomem *regs)854{855	u32 val;856 857	val = readl_relaxed(regs + TSADCV3_INT_PD);858	writel_relaxed(val & TSADCV4_INT_PD_CLEAR_MASK, regs + TSADCV3_INT_PD);859	val = readl_relaxed(regs + TSADCV3_HSHUT_PD);860	writel_relaxed(val & TSADCV3_INT_PD_CLEAR_MASK,861		       regs + TSADCV3_HSHUT_PD);862}863 864static void rk_tsadcv2_control(void __iomem *regs, bool enable)865{866	u32 val;867 868	val = readl_relaxed(regs + TSADCV2_AUTO_CON);869	if (enable)870		val |= TSADCV2_AUTO_EN;871	else872		val &= ~TSADCV2_AUTO_EN;873 874	writel_relaxed(val, regs + TSADCV2_AUTO_CON);875}876 877/**878 * rk_tsadcv3_control - the tsadc controller is enabled or disabled.879 * @regs: the base address of tsadc controller880 * @enable: boolean flag to enable the controller881 *882 * NOTE: TSADC controller works at auto mode, and some SoCs need set the883 * tsadc_q_sel bit on TSADCV2_AUTO_CON[1]. The (1024 - tsadc_q) as output884 * adc value if setting this bit to enable.885 */886static void rk_tsadcv3_control(void __iomem *regs, bool enable)887{888	u32 val;889 890	val = readl_relaxed(regs + TSADCV2_AUTO_CON);891	if (enable)892		val |= TSADCV2_AUTO_EN | TSADCV3_AUTO_Q_SEL_EN;893	else894		val &= ~TSADCV2_AUTO_EN;895 896	writel_relaxed(val, regs + TSADCV2_AUTO_CON);897}898 899static void rk_tsadcv4_control(void __iomem *regs, bool enable)900{901	u32 val;902 903	if (enable)904		val = TSADCV2_AUTO_EN | TSADCV2_AUTO_EN_MASK;905	else906		val = TSADCV2_AUTO_EN_MASK;907 908	writel_relaxed(val, regs + TSADCV2_AUTO_CON);909}910 911static int rk_tsadcv2_get_temp(const struct chip_tsadc_table *table,912			       int chn, void __iomem *regs, int *temp)913{914	u32 val;915 916	val = readl_relaxed(regs + TSADCV2_DATA(chn));917 918	return rk_tsadcv2_code_to_temp(table, val, temp);919}920 921static int rk_tsadcv4_get_temp(const struct chip_tsadc_table *table,922			       int chn, void __iomem *regs, int *temp)923{924	u32 val;925 926	val = readl_relaxed(regs + TSADCV3_DATA(chn));927 928	return rk_tsadcv2_code_to_temp(table, val, temp);929}930 931static int rk_tsadcv2_alarm_temp(const struct chip_tsadc_table *table,932				 int chn, void __iomem *regs, int temp)933{934	u32 alarm_value;935	u32 int_en, int_clr;936 937	/*938	 * In some cases, some sensors didn't need the trip points, the939	 * set_trips will pass {-INT_MAX, INT_MAX} to trigger tsadc alarm940	 * in the end, ignore this case and disable the high temperature941	 * interrupt.942	 */943	if (temp == INT_MAX) {944		int_clr = readl_relaxed(regs + TSADCV2_INT_EN);945		int_clr &= ~TSADCV2_INT_SRC_EN(chn);946		writel_relaxed(int_clr, regs + TSADCV2_INT_EN);947		return 0;948	}949 950	/* Make sure the value is valid */951	alarm_value = rk_tsadcv2_temp_to_code(table, temp);952	if (alarm_value == table->data_mask)953		return -ERANGE;954 955	writel_relaxed(alarm_value & table->data_mask,956		       regs + TSADCV2_COMP_INT(chn));957 958	int_en = readl_relaxed(regs + TSADCV2_INT_EN);959	int_en |= TSADCV2_INT_SRC_EN(chn);960	writel_relaxed(int_en, regs + TSADCV2_INT_EN);961 962	return 0;963}964 965static int rk_tsadcv3_alarm_temp(const struct chip_tsadc_table *table,966				 int chn, void __iomem *regs, int temp)967{968	u32 alarm_value;969 970	/*971	 * In some cases, some sensors didn't need the trip points, the972	 * set_trips will pass {-INT_MAX, INT_MAX} to trigger tsadc alarm973	 * in the end, ignore this case and disable the high temperature974	 * interrupt.975	 */976	if (temp == INT_MAX) {977		writel_relaxed(TSADCV2_INT_SRC_EN_MASK(chn),978			       regs + TSADCV3_HT_INT_EN);979		return 0;980	}981	/* Make sure the value is valid */982	alarm_value = rk_tsadcv2_temp_to_code(table, temp);983	if (alarm_value == table->data_mask)984		return -ERANGE;985	writel_relaxed(alarm_value & table->data_mask,986		       regs + TSADCV3_COMP_INT(chn));987	writel_relaxed(TSADCV2_INT_SRC_EN(chn) | TSADCV2_INT_SRC_EN_MASK(chn),988		       regs + TSADCV3_HT_INT_EN);989	return 0;990}991 992static int rk_tsadcv2_tshut_temp(const struct chip_tsadc_table *table,993				 int chn, void __iomem *regs, int temp)994{995	u32 tshut_value, val;996 997	/* Make sure the value is valid */998	tshut_value = rk_tsadcv2_temp_to_code(table, temp);999	if (tshut_value == table->data_mask)1000		return -ERANGE;1001 1002	writel_relaxed(tshut_value, regs + TSADCV2_COMP_SHUT(chn));1003 1004	/* TSHUT will be valid */1005	val = readl_relaxed(regs + TSADCV2_AUTO_CON);1006	writel_relaxed(val | TSADCV2_AUTO_SRC_EN(chn), regs + TSADCV2_AUTO_CON);1007 1008	return 0;1009}1010 1011static int rk_tsadcv3_tshut_temp(const struct chip_tsadc_table *table,1012				 int chn, void __iomem *regs, int temp)1013{1014	u32 tshut_value;1015 1016	/* Make sure the value is valid */1017	tshut_value = rk_tsadcv2_temp_to_code(table, temp);1018	if (tshut_value == table->data_mask)1019		return -ERANGE;1020 1021	writel_relaxed(tshut_value, regs + TSADCV3_COMP_SHUT(chn));1022 1023	/* TSHUT will be valid */1024	writel_relaxed(TSADCV3_AUTO_SRC_EN(chn) | TSADCV3_AUTO_SRC_EN_MASK(chn),1025		       regs + TSADCV3_AUTO_SRC_CON);1026 1027	return 0;1028}1029 1030static void rk_tsadcv2_tshut_mode(int chn, void __iomem *regs,1031				  enum tshut_mode mode)1032{1033	u32 val;1034 1035	val = readl_relaxed(regs + TSADCV2_INT_EN);1036	if (mode == TSHUT_MODE_GPIO) {1037		val &= ~TSADCV2_SHUT_2CRU_SRC_EN(chn);1038		val |= TSADCV2_SHUT_2GPIO_SRC_EN(chn);1039	} else {1040		val &= ~TSADCV2_SHUT_2GPIO_SRC_EN(chn);1041		val |= TSADCV2_SHUT_2CRU_SRC_EN(chn);1042	}1043 1044	writel_relaxed(val, regs + TSADCV2_INT_EN);1045}1046 1047static void rk_tsadcv3_tshut_mode(int chn, void __iomem *regs,1048				  enum tshut_mode mode)1049{1050	u32 val_gpio, val_cru;1051 1052	if (mode == TSHUT_MODE_GPIO) {1053		val_gpio = TSADCV2_INT_SRC_EN(chn) | TSADCV2_INT_SRC_EN_MASK(chn);1054		val_cru = TSADCV2_INT_SRC_EN_MASK(chn);1055	} else {1056		val_cru = TSADCV2_INT_SRC_EN(chn) | TSADCV2_INT_SRC_EN_MASK(chn);1057		val_gpio = TSADCV2_INT_SRC_EN_MASK(chn);1058	}1059	writel_relaxed(val_gpio, regs + TSADCV3_HSHUT_GPIO_INT_EN);1060	writel_relaxed(val_cru, regs + TSADCV3_HSHUT_CRU_INT_EN);1061}1062 1063static const struct rockchip_tsadc_chip px30_tsadc_data = {1064	/* cpu, gpu */1065	.chn_offset = 0,1066	.chn_num = 2, /* 2 channels for tsadc */1067 1068	.tshut_mode = TSHUT_MODE_CRU, /* default TSHUT via CRU */1069	.tshut_temp = 95000,1070 1071	.initialize = rk_tsadcv4_initialize,1072	.irq_ack = rk_tsadcv3_irq_ack,1073	.control = rk_tsadcv3_control,1074	.get_temp = rk_tsadcv2_get_temp,1075	.set_alarm_temp = rk_tsadcv2_alarm_temp,1076	.set_tshut_temp = rk_tsadcv2_tshut_temp,1077	.set_tshut_mode = rk_tsadcv2_tshut_mode,1078 1079	.table = {1080		.id = rk3328_code_table,1081		.length = ARRAY_SIZE(rk3328_code_table),1082		.data_mask = TSADCV2_DATA_MASK,1083		.mode = ADC_INCREMENT,1084	},1085};1086 1087static const struct rockchip_tsadc_chip rv1108_tsadc_data = {1088	/* cpu */1089	.chn_offset = 0,1090	.chn_num = 1, /* one channel for tsadc */1091 1092	.tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */1093	.tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */1094	.tshut_temp = 95000,1095 1096	.initialize = rk_tsadcv2_initialize,1097	.irq_ack = rk_tsadcv3_irq_ack,1098	.control = rk_tsadcv3_control,1099	.get_temp = rk_tsadcv2_get_temp,1100	.set_alarm_temp = rk_tsadcv2_alarm_temp,1101	.set_tshut_temp = rk_tsadcv2_tshut_temp,1102	.set_tshut_mode = rk_tsadcv2_tshut_mode,1103 1104	.table = {1105		.id = rv1108_table,1106		.length = ARRAY_SIZE(rv1108_table),1107		.data_mask = TSADCV2_DATA_MASK,1108		.mode = ADC_INCREMENT,1109	},1110};1111 1112static const struct rockchip_tsadc_chip rk3228_tsadc_data = {1113	/* cpu */1114	.chn_offset = 0,1115	.chn_num = 1, /* one channel for tsadc */1116 1117	.tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */1118	.tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */1119	.tshut_temp = 95000,1120 1121	.initialize = rk_tsadcv2_initialize,1122	.irq_ack = rk_tsadcv3_irq_ack,1123	.control = rk_tsadcv3_control,1124	.get_temp = rk_tsadcv2_get_temp,1125	.set_alarm_temp = rk_tsadcv2_alarm_temp,1126	.set_tshut_temp = rk_tsadcv2_tshut_temp,1127	.set_tshut_mode = rk_tsadcv2_tshut_mode,1128 1129	.table = {1130		.id = rk3228_code_table,1131		.length = ARRAY_SIZE(rk3228_code_table),1132		.data_mask = TSADCV3_DATA_MASK,1133		.mode = ADC_INCREMENT,1134	},1135};1136 1137static const struct rockchip_tsadc_chip rk3288_tsadc_data = {1138	/* cpu, gpu */1139	.chn_offset = 1,1140	.chn_num = 2, /* two channels for tsadc */1141 1142	.tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */1143	.tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */1144	.tshut_temp = 95000,1145 1146	.initialize = rk_tsadcv2_initialize,1147	.irq_ack = rk_tsadcv2_irq_ack,1148	.control = rk_tsadcv2_control,1149	.get_temp = rk_tsadcv2_get_temp,1150	.set_alarm_temp = rk_tsadcv2_alarm_temp,1151	.set_tshut_temp = rk_tsadcv2_tshut_temp,1152	.set_tshut_mode = rk_tsadcv2_tshut_mode,1153 1154	.table = {1155		.id = rk3288_code_table,1156		.length = ARRAY_SIZE(rk3288_code_table),1157		.data_mask = TSADCV2_DATA_MASK,1158		.mode = ADC_DECREMENT,1159	},1160};1161 1162static const struct rockchip_tsadc_chip rk3328_tsadc_data = {1163	/* cpu */1164	.chn_offset = 0,1165	.chn_num = 1, /* one channels for tsadc */1166 1167	.tshut_mode = TSHUT_MODE_CRU, /* default TSHUT via CRU */1168	.tshut_temp = 95000,1169 1170	.initialize = rk_tsadcv2_initialize,1171	.irq_ack = rk_tsadcv3_irq_ack,1172	.control = rk_tsadcv3_control,1173	.get_temp = rk_tsadcv2_get_temp,1174	.set_alarm_temp = rk_tsadcv2_alarm_temp,1175	.set_tshut_temp = rk_tsadcv2_tshut_temp,1176	.set_tshut_mode = rk_tsadcv2_tshut_mode,1177 1178	.table = {1179		.id = rk3328_code_table,1180		.length = ARRAY_SIZE(rk3328_code_table),1181		.data_mask = TSADCV2_DATA_MASK,1182		.mode = ADC_INCREMENT,1183	},1184};1185 1186static const struct rockchip_tsadc_chip rk3366_tsadc_data = {1187	/* cpu, gpu */1188	.chn_offset = 0,1189	.chn_num = 2, /* two channels for tsadc */1190 1191	.tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */1192	.tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */1193	.tshut_temp = 95000,1194 1195	.initialize = rk_tsadcv3_initialize,1196	.irq_ack = rk_tsadcv3_irq_ack,1197	.control = rk_tsadcv3_control,1198	.get_temp = rk_tsadcv2_get_temp,1199	.set_alarm_temp = rk_tsadcv2_alarm_temp,1200	.set_tshut_temp = rk_tsadcv2_tshut_temp,1201	.set_tshut_mode = rk_tsadcv2_tshut_mode,1202 1203	.table = {1204		.id = rk3228_code_table,1205		.length = ARRAY_SIZE(rk3228_code_table),1206		.data_mask = TSADCV3_DATA_MASK,1207		.mode = ADC_INCREMENT,1208	},1209};1210 1211static const struct rockchip_tsadc_chip rk3368_tsadc_data = {1212	/* cpu, gpu */1213	.chn_offset = 0,1214	.chn_num = 2, /* two channels for tsadc */1215 1216	.tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */1217	.tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */1218	.tshut_temp = 95000,1219 1220	.initialize = rk_tsadcv2_initialize,1221	.irq_ack = rk_tsadcv2_irq_ack,1222	.control = rk_tsadcv2_control,1223	.get_temp = rk_tsadcv2_get_temp,1224	.set_alarm_temp = rk_tsadcv2_alarm_temp,1225	.set_tshut_temp = rk_tsadcv2_tshut_temp,1226	.set_tshut_mode = rk_tsadcv2_tshut_mode,1227 1228	.table = {1229		.id = rk3368_code_table,1230		.length = ARRAY_SIZE(rk3368_code_table),1231		.data_mask = TSADCV3_DATA_MASK,1232		.mode = ADC_INCREMENT,1233	},1234};1235 1236static const struct rockchip_tsadc_chip rk3399_tsadc_data = {1237	/* cpu, gpu */1238	.chn_offset = 0,1239	.chn_num = 2, /* two channels for tsadc */1240 1241	.tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */1242	.tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */1243	.tshut_temp = 95000,1244 1245	.initialize = rk_tsadcv3_initialize,1246	.irq_ack = rk_tsadcv3_irq_ack,1247	.control = rk_tsadcv3_control,1248	.get_temp = rk_tsadcv2_get_temp,1249	.set_alarm_temp = rk_tsadcv2_alarm_temp,1250	.set_tshut_temp = rk_tsadcv2_tshut_temp,1251	.set_tshut_mode = rk_tsadcv2_tshut_mode,1252 1253	.table = {1254		.id = rk3399_code_table,1255		.length = ARRAY_SIZE(rk3399_code_table),1256		.data_mask = TSADCV3_DATA_MASK,1257		.mode = ADC_INCREMENT,1258	},1259};1260 1261static const struct rockchip_tsadc_chip rk3568_tsadc_data = {1262	/* cpu, gpu */1263	.chn_offset = 0,1264	.chn_num = 2, /* two channels for tsadc */1265 1266	.tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */1267	.tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */1268	.tshut_temp = 95000,1269 1270	.initialize = rk_tsadcv7_initialize,1271	.irq_ack = rk_tsadcv3_irq_ack,1272	.control = rk_tsadcv3_control,1273	.get_temp = rk_tsadcv2_get_temp,1274	.set_alarm_temp = rk_tsadcv2_alarm_temp,1275	.set_tshut_temp = rk_tsadcv2_tshut_temp,1276	.set_tshut_mode = rk_tsadcv2_tshut_mode,1277 1278	.table = {1279		.id = rk3568_code_table,1280		.length = ARRAY_SIZE(rk3568_code_table),1281		.data_mask = TSADCV2_DATA_MASK,1282		.mode = ADC_INCREMENT,1283	},1284};1285 1286static const struct rockchip_tsadc_chip rk3588_tsadc_data = {1287	/* top, big_core0, big_core1, little_core, center, gpu, npu */1288	.chn_offset = 0,1289	.chn_num = 7, /* seven channels for tsadc */1290	.tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */1291	.tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */1292	.tshut_temp = 95000,1293	.initialize = rk_tsadcv8_initialize,1294	.irq_ack = rk_tsadcv4_irq_ack,1295	.control = rk_tsadcv4_control,1296	.get_temp = rk_tsadcv4_get_temp,1297	.set_alarm_temp = rk_tsadcv3_alarm_temp,1298	.set_tshut_temp = rk_tsadcv3_tshut_temp,1299	.set_tshut_mode = rk_tsadcv3_tshut_mode,1300	.table = {1301		.id = rk3588_code_table,1302		.length = ARRAY_SIZE(rk3588_code_table),1303		.data_mask = TSADCV4_DATA_MASK,1304		.mode = ADC_INCREMENT,1305	},1306};1307 1308static const struct of_device_id of_rockchip_thermal_match[] = {1309	{	.compatible = "rockchip,px30-tsadc",1310		.data = (void *)&px30_tsadc_data,1311	},1312	{1313		.compatible = "rockchip,rv1108-tsadc",1314		.data = (void *)&rv1108_tsadc_data,1315	},1316	{1317		.compatible = "rockchip,rk3228-tsadc",1318		.data = (void *)&rk3228_tsadc_data,1319	},1320	{1321		.compatible = "rockchip,rk3288-tsadc",1322		.data = (void *)&rk3288_tsadc_data,1323	},1324	{1325		.compatible = "rockchip,rk3328-tsadc",1326		.data = (void *)&rk3328_tsadc_data,1327	},1328	{1329		.compatible = "rockchip,rk3366-tsadc",1330		.data = (void *)&rk3366_tsadc_data,1331	},1332	{1333		.compatible = "rockchip,rk3368-tsadc",1334		.data = (void *)&rk3368_tsadc_data,1335	},1336	{1337		.compatible = "rockchip,rk3399-tsadc",1338		.data = (void *)&rk3399_tsadc_data,1339	},1340	{1341		.compatible = "rockchip,rk3568-tsadc",1342		.data = (void *)&rk3568_tsadc_data,1343	},1344	{1345		.compatible = "rockchip,rk3588-tsadc",1346		.data = (void *)&rk3588_tsadc_data,1347	},1348	{ /* end */ },1349};1350MODULE_DEVICE_TABLE(of, of_rockchip_thermal_match);1351 1352static void1353rockchip_thermal_toggle_sensor(struct rockchip_thermal_sensor *sensor, bool on)1354{1355	struct thermal_zone_device *tzd = sensor->tzd;1356 1357	if (on)1358		thermal_zone_device_enable(tzd);1359	else1360		thermal_zone_device_disable(tzd);1361}1362 1363static irqreturn_t rockchip_thermal_alarm_irq_thread(int irq, void *dev)1364{1365	struct rockchip_thermal_data *thermal = dev;1366	int i;1367 1368	dev_dbg(&thermal->pdev->dev, "thermal alarm\n");1369 1370	thermal->chip->irq_ack(thermal->regs);1371 1372	for (i = 0; i < thermal->chip->chn_num; i++)1373		thermal_zone_device_update(thermal->sensors[i].tzd,1374					   THERMAL_EVENT_UNSPECIFIED);1375 1376	return IRQ_HANDLED;1377}1378 1379static int rockchip_thermal_set_trips(struct thermal_zone_device *tz, int low, int high)1380{1381	struct rockchip_thermal_sensor *sensor = thermal_zone_device_priv(tz);1382	struct rockchip_thermal_data *thermal = sensor->thermal;1383	const struct rockchip_tsadc_chip *tsadc = thermal->chip;1384 1385	dev_dbg(&thermal->pdev->dev, "%s: sensor %d: low: %d, high %d\n",1386		__func__, sensor->id, low, high);1387 1388	return tsadc->set_alarm_temp(&tsadc->table,1389				     sensor->id, thermal->regs, high);1390}1391 1392static int rockchip_thermal_get_temp(struct thermal_zone_device *tz, int *out_temp)1393{1394	struct rockchip_thermal_sensor *sensor = thermal_zone_device_priv(tz);1395	struct rockchip_thermal_data *thermal = sensor->thermal;1396	const struct rockchip_tsadc_chip *tsadc = sensor->thermal->chip;1397	int retval;1398 1399	retval = tsadc->get_temp(&tsadc->table,1400				 sensor->id, thermal->regs, out_temp);1401	return retval;1402}1403 1404static const struct thermal_zone_device_ops rockchip_of_thermal_ops = {1405	.get_temp = rockchip_thermal_get_temp,1406	.set_trips = rockchip_thermal_set_trips,1407};1408 1409static int rockchip_configure_from_dt(struct device *dev,1410				      struct device_node *np,1411				      struct rockchip_thermal_data *thermal)1412{1413	u32 shut_temp, tshut_mode, tshut_polarity;1414 1415	if (of_property_read_u32(np, "rockchip,hw-tshut-temp", &shut_temp)) {1416		dev_warn(dev,1417			 "Missing tshut temp property, using default %d\n",1418			 thermal->chip->tshut_temp);1419		thermal->tshut_temp = thermal->chip->tshut_temp;1420	} else {1421		if (shut_temp > INT_MAX) {1422			dev_err(dev, "Invalid tshut temperature specified: %d\n",1423				shut_temp);1424			return -ERANGE;1425		}1426		thermal->tshut_temp = shut_temp;1427	}1428 1429	if (of_property_read_u32(np, "rockchip,hw-tshut-mode", &tshut_mode)) {1430		dev_warn(dev,1431			 "Missing tshut mode property, using default (%s)\n",1432			 thermal->chip->tshut_mode == TSHUT_MODE_GPIO ?1433				"gpio" : "cru");1434		thermal->tshut_mode = thermal->chip->tshut_mode;1435	} else {1436		thermal->tshut_mode = tshut_mode;1437	}1438 1439	if (thermal->tshut_mode > 1) {1440		dev_err(dev, "Invalid tshut mode specified: %d\n",1441			thermal->tshut_mode);1442		return -EINVAL;1443	}1444 1445	if (of_property_read_u32(np, "rockchip,hw-tshut-polarity",1446				 &tshut_polarity)) {1447		dev_warn(dev,1448			 "Missing tshut-polarity property, using default (%s)\n",1449			 thermal->chip->tshut_polarity == TSHUT_LOW_ACTIVE ?1450				"low" : "high");1451		thermal->tshut_polarity = thermal->chip->tshut_polarity;1452	} else {1453		thermal->tshut_polarity = tshut_polarity;1454	}1455 1456	if (thermal->tshut_polarity > 1) {1457		dev_err(dev, "Invalid tshut-polarity specified: %d\n",1458			thermal->tshut_polarity);1459		return -EINVAL;1460	}1461 1462	/* The tsadc wont to handle the error in here since some SoCs didn't1463	 * need this property.1464	 */1465	thermal->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");1466	if (IS_ERR(thermal->grf))1467		dev_warn(dev, "Missing rockchip,grf property\n");1468 1469	return 0;1470}1471 1472static int1473rockchip_thermal_register_sensor(struct platform_device *pdev,1474				 struct rockchip_thermal_data *thermal,1475				 struct rockchip_thermal_sensor *sensor,1476				 int id)1477{1478	const struct rockchip_tsadc_chip *tsadc = thermal->chip;1479	int error;1480 1481	tsadc->set_tshut_mode(id, thermal->regs, thermal->tshut_mode);1482 1483	error = tsadc->set_tshut_temp(&tsadc->table, id, thermal->regs,1484			      thermal->tshut_temp);1485	if (error)1486		dev_err(&pdev->dev, "%s: invalid tshut=%d, error=%d\n",1487			__func__, thermal->tshut_temp, error);1488 1489	sensor->thermal = thermal;1490	sensor->id = id;1491	sensor->tzd = devm_thermal_of_zone_register(&pdev->dev, id, sensor,1492						    &rockchip_of_thermal_ops);1493	if (IS_ERR(sensor->tzd)) {1494		error = PTR_ERR(sensor->tzd);1495		dev_err(&pdev->dev, "failed to register sensor %d: %d\n",1496			id, error);1497		return error;1498	}1499 1500	return 0;1501}1502 1503/**1504 * rockchip_thermal_reset_controller - Reset TSADC Controller, reset all tsadc registers.1505 * @reset: the reset controller of tsadc1506 */1507static void rockchip_thermal_reset_controller(struct reset_control *reset)1508{1509	reset_control_assert(reset);1510	usleep_range(10, 20);1511	reset_control_deassert(reset);1512}1513 1514static int rockchip_thermal_probe(struct platform_device *pdev)1515{1516	struct device_node *np = pdev->dev.of_node;1517	struct rockchip_thermal_data *thermal;1518	int irq;1519	int i;1520	int error;1521 1522	irq = platform_get_irq(pdev, 0);1523	if (irq < 0)1524		return -EINVAL;1525 1526	thermal = devm_kzalloc(&pdev->dev, sizeof(struct rockchip_thermal_data),1527			       GFP_KERNEL);1528	if (!thermal)1529		return -ENOMEM;1530 1531	thermal->pdev = pdev;1532 1533	thermal->chip = device_get_match_data(&pdev->dev);1534	if (!thermal->chip)1535		return -EINVAL;1536 1537	thermal->sensors = devm_kcalloc(&pdev->dev, thermal->chip->chn_num,1538					sizeof(*thermal->sensors), GFP_KERNEL);1539	if (!thermal->sensors)1540		return -ENOMEM;1541 1542	thermal->regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);1543	if (IS_ERR(thermal->regs))1544		return PTR_ERR(thermal->regs);1545 1546	thermal->reset = devm_reset_control_array_get_exclusive(&pdev->dev);1547	if (IS_ERR(thermal->reset))1548		return dev_err_probe(&pdev->dev, PTR_ERR(thermal->reset),1549				     "failed to get tsadc reset.\n");1550 1551	thermal->clk = devm_clk_get_enabled(&pdev->dev, "tsadc");1552	if (IS_ERR(thermal->clk))1553		return dev_err_probe(&pdev->dev, PTR_ERR(thermal->clk),1554				     "failed to get tsadc clock.\n");1555 1556	thermal->pclk = devm_clk_get_enabled(&pdev->dev, "apb_pclk");1557	if (IS_ERR(thermal->pclk))1558		return dev_err_probe(&pdev->dev, PTR_ERR(thermal->pclk),1559				     "failed to get apb_pclk clock.\n");1560 1561	rockchip_thermal_reset_controller(thermal->reset);1562 1563	error = rockchip_configure_from_dt(&pdev->dev, np, thermal);1564	if (error)1565		return dev_err_probe(&pdev->dev, error,1566				"failed to parse device tree data\n");1567 1568	thermal->chip->initialize(thermal->grf, thermal->regs,1569				  thermal->tshut_polarity);1570 1571	for (i = 0; i < thermal->chip->chn_num; i++) {1572		error = rockchip_thermal_register_sensor(pdev, thermal,1573						&thermal->sensors[i],1574						thermal->chip->chn_offset + i);1575		if (error)1576			return dev_err_probe(&pdev->dev, error,1577				"failed to register sensor[%d].\n", i);1578	}1579 1580	error = devm_request_threaded_irq(&pdev->dev, irq, NULL,1581					  &rockchip_thermal_alarm_irq_thread,1582					  IRQF_ONESHOT,1583					  "rockchip_thermal", thermal);1584	if (error)1585		return dev_err_probe(&pdev->dev, error,1586				     "failed to request tsadc irq.\n");1587 1588	thermal->chip->control(thermal->regs, true);1589 1590	for (i = 0; i < thermal->chip->chn_num; i++) {1591		rockchip_thermal_toggle_sensor(&thermal->sensors[i], true);1592		error = thermal_add_hwmon_sysfs(thermal->sensors[i].tzd);1593		if (error)1594			dev_warn(&pdev->dev,1595				 "failed to register sensor %d with hwmon: %d\n",1596				 i, error);1597	}1598 1599	platform_set_drvdata(pdev, thermal);1600 1601	return 0;1602}1603 1604static void rockchip_thermal_remove(struct platform_device *pdev)1605{1606	struct rockchip_thermal_data *thermal = platform_get_drvdata(pdev);1607	int i;1608 1609	for (i = 0; i < thermal->chip->chn_num; i++) {1610		struct rockchip_thermal_sensor *sensor = &thermal->sensors[i];1611 1612		thermal_remove_hwmon_sysfs(sensor->tzd);1613		rockchip_thermal_toggle_sensor(sensor, false);1614	}1615 1616	thermal->chip->control(thermal->regs, false);1617}1618 1619static int __maybe_unused rockchip_thermal_suspend(struct device *dev)1620{1621	struct rockchip_thermal_data *thermal = dev_get_drvdata(dev);1622	int i;1623 1624	for (i = 0; i < thermal->chip->chn_num; i++)1625		rockchip_thermal_toggle_sensor(&thermal->sensors[i], false);1626 1627	thermal->chip->control(thermal->regs, false);1628 1629	clk_disable(thermal->pclk);1630	clk_disable(thermal->clk);1631 1632	pinctrl_pm_select_sleep_state(dev);1633 1634	return 0;1635}1636 1637static int __maybe_unused rockchip_thermal_resume(struct device *dev)1638{1639	struct rockchip_thermal_data *thermal = dev_get_drvdata(dev);1640	int i;1641	int error;1642 1643	error = clk_enable(thermal->clk);1644	if (error)1645		return error;1646 1647	error = clk_enable(thermal->pclk);1648	if (error) {1649		clk_disable(thermal->clk);1650		return error;1651	}1652 1653	rockchip_thermal_reset_controller(thermal->reset);1654 1655	thermal->chip->initialize(thermal->grf, thermal->regs,1656				  thermal->tshut_polarity);1657 1658	for (i = 0; i < thermal->chip->chn_num; i++) {1659		int id = thermal->sensors[i].id;1660 1661		thermal->chip->set_tshut_mode(id, thermal->regs,1662					      thermal->tshut_mode);1663 1664		error = thermal->chip->set_tshut_temp(&thermal->chip->table,1665					      id, thermal->regs,1666					      thermal->tshut_temp);1667		if (error)1668			dev_err(dev, "%s: invalid tshut=%d, error=%d\n",1669				__func__, thermal->tshut_temp, error);1670	}1671 1672	thermal->chip->control(thermal->regs, true);1673 1674	for (i = 0; i < thermal->chip->chn_num; i++)1675		rockchip_thermal_toggle_sensor(&thermal->sensors[i], true);1676 1677	pinctrl_pm_select_default_state(dev);1678 1679	return 0;1680}1681 1682static SIMPLE_DEV_PM_OPS(rockchip_thermal_pm_ops,1683			 rockchip_thermal_suspend, rockchip_thermal_resume);1684 1685static struct platform_driver rockchip_thermal_driver = {1686	.driver = {1687		.name = "rockchip-thermal",1688		.pm = &rockchip_thermal_pm_ops,1689		.of_match_table = of_rockchip_thermal_match,1690	},1691	.probe = rockchip_thermal_probe,1692	.remove_new = rockchip_thermal_remove,1693};1694 1695module_platform_driver(rockchip_thermal_driver);1696 1697MODULE_DESCRIPTION("ROCKCHIP THERMAL Driver");1698MODULE_AUTHOR("Rockchip, Inc.");1699MODULE_LICENSE("GPL v2");1700MODULE_ALIAS("platform:rockchip-thermal");1701