99#include <linux/interrupt.h>
1010#include <linux/io.h>
1111#include <linux/module.h>
12+ #include <linux/nvmem-consumer.h>
1213#include <linux/of.h>
1314#include <linux/of_address.h>
1415#include <linux/of_irq.h>
@@ -69,23 +70,28 @@ struct chip_tsadc_table {
6970 * struct rockchip_tsadc_chip - hold the private data of tsadc chip
7071 * @chn_offset: the channel offset of the first channel
7172 * @chn_num: the channel number of tsadc chip
72- * @tshut_temp: the hardware-controlled shutdown temperature value
73+ * @trim_slope: used to convert the trim code to a temperature in millicelsius
74+ * @tshut_temp: the hardware-controlled shutdown temperature value, with no trim
7375 * @tshut_mode: the hardware-controlled shutdown mode (0:CRU 1:GPIO)
7476 * @tshut_polarity: the hardware-controlled active polarity (0:LOW 1:HIGH)
7577 * @initialize: SoC special initialize tsadc controller method
7678 * @irq_ack: clear the interrupt
7779 * @control: enable/disable method for the tsadc controller
78- * @get_temp: get the temperature
80+ * @get_temp: get the raw temperature, unadjusted by trim
7981 * @set_alarm_temp: set the high temperature interrupt
8082 * @set_tshut_temp: set the hardware-controlled shutdown temperature
8183 * @set_tshut_mode: set the hardware-controlled shutdown mode
84+ * @get_trim_code: convert a hardware temperature code to one adjusted for by trim
8285 * @table: the chip-specific conversion table
8386 */
8487struct rockchip_tsadc_chip {
8588 /* The sensor id of chip correspond to the ADC channel */
8689 int chn_offset ;
8790 int chn_num ;
8891
92+ /* Used to convert trim code to trim temp */
93+ int trim_slope ;
94+
8995 /* The hardware-controlled tshut property */
9096 int tshut_temp ;
9197 enum tshut_mode tshut_mode ;
@@ -105,6 +111,8 @@ struct rockchip_tsadc_chip {
105111 int (* set_tshut_temp )(const struct chip_tsadc_table * table ,
106112 int chn , void __iomem * reg , int temp );
107113 void (* set_tshut_mode )(int chn , void __iomem * reg , enum tshut_mode m );
114+ int (* get_trim_code )(const struct chip_tsadc_table * table ,
115+ int code , int trim_base , int trim_base_frac );
108116
109117 /* Per-table methods */
110118 struct chip_tsadc_table table ;
@@ -114,12 +122,16 @@ struct rockchip_tsadc_chip {
114122 * struct rockchip_thermal_sensor - hold the information of thermal sensor
115123 * @thermal: pointer to the platform/configuration data
116124 * @tzd: pointer to a thermal zone
125+ * @of_node: pointer to the device_node representing this sensor, if any
117126 * @id: identifier of the thermal sensor
127+ * @trim_temp: per-sensor trim temperature value
118128 */
119129struct rockchip_thermal_sensor {
120130 struct rockchip_thermal_data * thermal ;
121131 struct thermal_zone_device * tzd ;
132+ struct device_node * of_node ;
122133 int id ;
134+ int trim_temp ;
123135};
124136
125137/**
@@ -132,7 +144,11 @@ struct rockchip_thermal_sensor {
132144 * @pclk: the advanced peripherals bus clock
133145 * @grf: the general register file will be used to do static set by software
134146 * @regs: the base address of tsadc controller
135- * @tshut_temp: the hardware-controlled shutdown temperature value
147+ * @trim_base: major component of sensor trim value, in Celsius
148+ * @trim_base_frac: minor component of sensor trim value, in Decicelsius
149+ * @trim: fallback thermal trim value for each channel
150+ * @tshut_temp: the hardware-controlled shutdown temperature value, with no trim
151+ * @trim_temp: the fallback trim temperature for the whole sensor
136152 * @tshut_mode: the hardware-controlled shutdown mode (0:CRU 1:GPIO)
137153 * @tshut_polarity: the hardware-controlled active polarity (0:LOW 1:HIGH)
138154 */
@@ -149,7 +165,12 @@ struct rockchip_thermal_data {
149165 struct regmap * grf ;
150166 void __iomem * regs ;
151167
168+ int trim_base ;
169+ int trim_base_frac ;
170+ int trim ;
171+
152172 int tshut_temp ;
173+ int trim_temp ;
153174 enum tshut_mode tshut_mode ;
154175 enum tshut_polarity tshut_polarity ;
155176};
@@ -249,6 +270,9 @@ struct rockchip_thermal_data {
249270
250271#define GRF_CON_TSADC_CH_INV (0x10001 << 1)
251272
273+
274+ #define RK_MAX_TEMP (180000)
275+
252276/**
253277 * struct tsadc_table - code to temperature conversion table
254278 * @code: the value of adc channel
@@ -1061,6 +1085,15 @@ static void rk_tsadcv4_tshut_mode(int chn, void __iomem *regs,
10611085 writel_relaxed (val_cru , regs + TSADCV3_HSHUT_CRU_INT_EN );
10621086}
10631087
1088+ static int rk_tsadcv2_get_trim_code (const struct chip_tsadc_table * table ,
1089+ int code , int trim_base , int trim_base_frac )
1090+ {
1091+ int temp = trim_base * 1000 + trim_base_frac * 100 ;
1092+ u32 base_code = rk_tsadcv2_temp_to_code (table , temp );
1093+
1094+ return code - base_code ;
1095+ }
1096+
10641097static const struct rockchip_tsadc_chip px30_tsadc_data = {
10651098 /* cpu, gpu */
10661099 .chn_offset = 0 ,
@@ -1298,6 +1331,8 @@ static const struct rockchip_tsadc_chip rk3576_tsadc_data = {
12981331 .set_alarm_temp = rk_tsadcv3_alarm_temp ,
12991332 .set_tshut_temp = rk_tsadcv3_tshut_temp ,
13001333 .set_tshut_mode = rk_tsadcv4_tshut_mode ,
1334+ .get_trim_code = rk_tsadcv2_get_trim_code ,
1335+ .trim_slope = 923 ,
13011336 .table = {
13021337 .id = rk3588_code_table ,
13031338 .length = ARRAY_SIZE (rk3588_code_table ),
@@ -1413,7 +1448,7 @@ static int rockchip_thermal_set_trips(struct thermal_zone_device *tz, int low, i
14131448 __func__ , sensor -> id , low , high );
14141449
14151450 return tsadc -> set_alarm_temp (& tsadc -> table ,
1416- sensor -> id , thermal -> regs , high );
1451+ sensor -> id , thermal -> regs , high + sensor -> trim_temp );
14171452}
14181453
14191454static int rockchip_thermal_get_temp (struct thermal_zone_device * tz , int * out_temp )
@@ -1425,6 +1460,8 @@ static int rockchip_thermal_get_temp(struct thermal_zone_device *tz, int *out_te
14251460
14261461 retval = tsadc -> get_temp (& tsadc -> table ,
14271462 sensor -> id , thermal -> regs , out_temp );
1463+ * out_temp -= sensor -> trim_temp ;
1464+
14281465 return retval ;
14291466}
14301467
@@ -1433,6 +1470,104 @@ static const struct thermal_zone_device_ops rockchip_of_thermal_ops = {
14331470 .set_trips = rockchip_thermal_set_trips ,
14341471};
14351472
1473+ /**
1474+ * rockchip_get_efuse_value - read an OTP cell from a device node
1475+ * @np: pointer to the device node with the nvmem-cells property
1476+ * @cell_name: name of cell that should be read
1477+ * @value: pointer to where the read value will be placed
1478+ *
1479+ * Return: Negative errno on failure, during which *value will not be touched,
1480+ * or 0 on success.
1481+ */
1482+ static int rockchip_get_efuse_value (struct device_node * np , const char * cell_name ,
1483+ int * value )
1484+ {
1485+ struct nvmem_cell * cell ;
1486+ int ret = 0 ;
1487+ size_t len ;
1488+ u8 * buf ;
1489+ int i ;
1490+
1491+ cell = of_nvmem_cell_get (np , cell_name );
1492+ if (IS_ERR (cell ))
1493+ return PTR_ERR (cell );
1494+
1495+ buf = nvmem_cell_read (cell , & len );
1496+
1497+ nvmem_cell_put (cell );
1498+
1499+ if (IS_ERR (buf ))
1500+ return PTR_ERR (buf );
1501+
1502+ if (len > sizeof (* value )) {
1503+ ret = - ERANGE ;
1504+ goto exit ;
1505+ }
1506+
1507+ /* Copy with implicit endian conversion */
1508+ * value = 0 ;
1509+ for (i = 0 ; i < len ; i ++ )
1510+ * value |= (int ) buf [i ] << (8 * i );
1511+
1512+ exit :
1513+ kfree (buf );
1514+ return ret ;
1515+ }
1516+
1517+ static int rockchip_get_trim_configuration (struct device * dev , struct device_node * np ,
1518+ struct rockchip_thermal_data * thermal )
1519+ {
1520+ const struct rockchip_tsadc_chip * tsadc = thermal -> chip ;
1521+ int trim_base = 0 , trim_base_frac = 0 , trim = 0 ;
1522+ int trim_code ;
1523+ int ret ;
1524+
1525+ thermal -> trim_base = 0 ;
1526+ thermal -> trim_base_frac = 0 ;
1527+ thermal -> trim = 0 ;
1528+
1529+ if (!tsadc -> get_trim_code )
1530+ return 0 ;
1531+
1532+ ret = rockchip_get_efuse_value (np , "trim_base" , & trim_base );
1533+ if (ret < 0 ) {
1534+ if (ret == - ENOENT ) {
1535+ trim_base = 30 ;
1536+ dev_dbg (dev , "trim_base is absent, defaulting to 30\n" );
1537+ } else {
1538+ dev_err (dev , "failed reading nvmem value of trim_base: %pe\n" ,
1539+ ERR_PTR (ret ));
1540+ return ret ;
1541+ }
1542+ }
1543+ ret = rockchip_get_efuse_value (np , "trim_base_frac" , & trim_base_frac );
1544+ if (ret < 0 ) {
1545+ if (ret == - ENOENT ) {
1546+ dev_dbg (dev , "trim_base_frac is absent, defaulting to 0\n" );
1547+ } else {
1548+ dev_err (dev , "failed reading nvmem value of trim_base_frac: %pe\n" ,
1549+ ERR_PTR (ret ));
1550+ return ret ;
1551+ }
1552+ }
1553+ thermal -> trim_base = trim_base ;
1554+ thermal -> trim_base_frac = trim_base_frac ;
1555+
1556+ /*
1557+ * If the tsadc node contains the trim property, then it is used in the
1558+ * absence of per-channel trim values
1559+ */
1560+ if (!rockchip_get_efuse_value (np , "trim" , & trim ))
1561+ thermal -> trim = trim ;
1562+ if (trim ) {
1563+ trim_code = tsadc -> get_trim_code (& tsadc -> table , trim ,
1564+ trim_base , trim_base_frac );
1565+ thermal -> trim_temp = thermal -> chip -> trim_slope * trim_code ;
1566+ }
1567+
1568+ return 0 ;
1569+ }
1570+
14361571static int rockchip_configure_from_dt (struct device * dev ,
14371572 struct device_node * np ,
14381573 struct rockchip_thermal_data * thermal )
@@ -1493,6 +1628,8 @@ static int rockchip_configure_from_dt(struct device *dev,
14931628 if (IS_ERR (thermal -> grf ))
14941629 dev_warn (dev , "Missing rockchip,grf property\n" );
14951630
1631+ rockchip_get_trim_configuration (dev , np , thermal );
1632+
14961633 return 0 ;
14971634}
14981635
@@ -1503,23 +1640,50 @@ rockchip_thermal_register_sensor(struct platform_device *pdev,
15031640 int id )
15041641{
15051642 const struct rockchip_tsadc_chip * tsadc = thermal -> chip ;
1643+ struct device * dev = & pdev -> dev ;
1644+ int trim = thermal -> trim ;
1645+ int trim_code , tshut_temp ;
1646+ int trim_temp = 0 ;
15061647 int error ;
15071648
1649+ if (thermal -> trim_temp )
1650+ trim_temp = thermal -> trim_temp ;
1651+
1652+ if (tsadc -> get_trim_code && sensor -> of_node ) {
1653+ error = rockchip_get_efuse_value (sensor -> of_node , "trim" , & trim );
1654+ if (error < 0 && error != - ENOENT ) {
1655+ dev_err (dev , "failed reading trim of sensor %d: %pe\n" ,
1656+ id , ERR_PTR (error ));
1657+ return error ;
1658+ }
1659+ if (trim ) {
1660+ trim_code = tsadc -> get_trim_code (& tsadc -> table , trim ,
1661+ thermal -> trim_base ,
1662+ thermal -> trim_base_frac );
1663+ trim_temp = thermal -> chip -> trim_slope * trim_code ;
1664+ }
1665+ }
1666+
1667+ sensor -> trim_temp = trim_temp ;
1668+
1669+ dev_dbg (dev , "trim of sensor %d is %d\n" , id , sensor -> trim_temp );
1670+
1671+ tshut_temp = min (thermal -> tshut_temp + sensor -> trim_temp , RK_MAX_TEMP );
1672+
15081673 tsadc -> set_tshut_mode (id , thermal -> regs , thermal -> tshut_mode );
15091674
1510- error = tsadc -> set_tshut_temp (& tsadc -> table , id , thermal -> regs ,
1511- thermal -> tshut_temp );
1675+ error = tsadc -> set_tshut_temp (& tsadc -> table , id , thermal -> regs , tshut_temp );
15121676 if (error )
1513- dev_err (& pdev -> dev , "%s: invalid tshut=%d, error=%d\n" ,
1514- __func__ , thermal -> tshut_temp , error );
1677+ dev_err (dev , "%s: invalid tshut=%d, error=%d\n" ,
1678+ __func__ , tshut_temp , error );
15151679
15161680 sensor -> thermal = thermal ;
15171681 sensor -> id = id ;
1518- sensor -> tzd = devm_thermal_of_zone_register (& pdev -> dev , id , sensor ,
1682+ sensor -> tzd = devm_thermal_of_zone_register (dev , id , sensor ,
15191683 & rockchip_of_thermal_ops );
15201684 if (IS_ERR (sensor -> tzd )) {
15211685 error = PTR_ERR (sensor -> tzd );
1522- dev_err (& pdev -> dev , "failed to register sensor %d: %d\n" ,
1686+ dev_err (dev , "failed to register sensor %d: %d\n" ,
15231687 id , error );
15241688 return error ;
15251689 }
@@ -1542,9 +1706,11 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
15421706{
15431707 struct device_node * np = pdev -> dev .of_node ;
15441708 struct rockchip_thermal_data * thermal ;
1709+ struct device_node * child ;
15451710 int irq ;
15461711 int i ;
15471712 int error ;
1713+ u32 chn ;
15481714
15491715 irq = platform_get_irq (pdev , 0 );
15501716 if (irq < 0 )
@@ -1595,6 +1761,18 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
15951761 thermal -> chip -> initialize (thermal -> grf , thermal -> regs ,
15961762 thermal -> tshut_polarity );
15971763
1764+ for_each_available_child_of_node (np , child ) {
1765+ if (!of_property_read_u32 (child , "reg" , & chn )) {
1766+ if (chn < thermal -> chip -> chn_num )
1767+ thermal -> sensors [chn ].of_node = child ;
1768+ else
1769+ dev_warn (& pdev -> dev ,
1770+ "sensor address (%d) too large, ignoring its trim\n" ,
1771+ chn );
1772+ }
1773+
1774+ }
1775+
15981776 for (i = 0 ; i < thermal -> chip -> chn_num ; i ++ ) {
15991777 error = rockchip_thermal_register_sensor (pdev , thermal ,
16001778 & thermal -> sensors [i ],
@@ -1664,8 +1842,11 @@ static int __maybe_unused rockchip_thermal_suspend(struct device *dev)
16641842static int __maybe_unused rockchip_thermal_resume (struct device * dev )
16651843{
16661844 struct rockchip_thermal_data * thermal = dev_get_drvdata (dev );
1667- int i ;
1845+ const struct rockchip_tsadc_chip * tsadc = thermal -> chip ;
1846+ struct rockchip_thermal_sensor * sensor ;
1847+ int tshut_temp ;
16681848 int error ;
1849+ int i ;
16691850
16701851 error = clk_enable (thermal -> clk );
16711852 if (error )
@@ -1679,21 +1860,23 @@ static int __maybe_unused rockchip_thermal_resume(struct device *dev)
16791860
16801861 rockchip_thermal_reset_controller (thermal -> reset );
16811862
1682- thermal -> chip -> initialize (thermal -> grf , thermal -> regs ,
1683- thermal -> tshut_polarity );
1863+ tsadc -> initialize (thermal -> grf , thermal -> regs , thermal -> tshut_polarity );
16841864
16851865 for (i = 0 ; i < thermal -> chip -> chn_num ; i ++ ) {
1686- int id = thermal -> sensors [i ].id ;
1866+ sensor = & thermal -> sensors [i ];
1867+
1868+ tshut_temp = min (thermal -> tshut_temp + sensor -> trim_temp ,
1869+ RK_MAX_TEMP );
16871870
1688- thermal -> chip -> set_tshut_mode (id , thermal -> regs ,
1871+ tsadc -> set_tshut_mode (sensor -> id , thermal -> regs ,
16891872 thermal -> tshut_mode );
16901873
1691- error = thermal -> chip -> set_tshut_temp (& thermal -> chip -> table ,
1692- id , thermal -> regs ,
1693- thermal -> tshut_temp );
1874+ error = tsadc -> set_tshut_temp (& thermal -> chip -> table ,
1875+ sensor -> id , thermal -> regs ,
1876+ tshut_temp );
16941877 if (error )
16951878 dev_err (dev , "%s: invalid tshut=%d, error=%d\n" ,
1696- __func__ , thermal -> tshut_temp , error );
1879+ __func__ , tshut_temp , error );
16971880 }
16981881
16991882 thermal -> chip -> control (thermal -> regs , true);
0 commit comments