airoha_thermal.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. #include <linux/module.h>
  3. #include <linux/bitfield.h>
  4. #include <linux/delay.h>
  5. #include <linux/interrupt.h>
  6. #include <linux/mfd/syscon.h>
  7. #include <linux/of.h>
  8. #include <linux/of_address.h>
  9. #include <linux/platform_device.h>
  10. #include <linux/regmap.h>
  11. #include <linux/thermal.h>
  12. /* SCU regs */
  13. #define EN7581_PLLRG_PROTECT 0x268
  14. #define EN7581_PWD_TADC 0x2ec
  15. #define EN7581_MUX_TADC GENMASK(3, 1)
  16. #define EN7581_DOUT_TADC 0x2f8
  17. #define EN7581_DOUT_TADC_MASK GENMASK(15, 0)
  18. /* PTP_THERMAL regs */
  19. #define EN7581_TEMPMONCTL0 0x800
  20. #define EN7581_SENSE3_EN BIT(3)
  21. #define EN7581_SENSE2_EN BIT(2)
  22. #define EN7581_SENSE1_EN BIT(1)
  23. #define EN7581_SENSE0_EN BIT(0)
  24. #define EN7581_TEMPMONCTL1 0x804
  25. /* period unit calculated in BUS clock * 256 scaling-up */
  26. #define EN7581_PERIOD_UNIT GENMASK(9, 0)
  27. #define EN7581_TEMPMONCTL2 0x808
  28. #define EN7581_FILT_INTERVAL GENMASK(25, 16)
  29. #define EN7581_SEN_INTERVAL GENMASK(9, 0)
  30. #define EN7581_TEMPMONINT 0x80C
  31. #define EN7581_STAGE3_INT_EN BIT(31)
  32. #define EN7581_STAGE2_INT_EN BIT(30)
  33. #define EN7581_STAGE1_INT_EN BIT(29)
  34. #define EN7581_FILTER_INT_EN_3 BIT(28)
  35. #define EN7581_IMMD_INT_EN3 BIT(27)
  36. #define EN7581_NOHOTINTEN3 BIT(26)
  37. #define EN7581_HOFSINTEN3 BIT(25)
  38. #define EN7581_LOFSINTEN3 BIT(24)
  39. #define EN7581_HINTEN3 BIT(23)
  40. #define EN7581_CINTEN3 BIT(22)
  41. #define EN7581_FILTER_INT_EN_2 BIT(21)
  42. #define EN7581_FILTER_INT_EN_1 BIT(20)
  43. #define EN7581_FILTER_INT_EN_0 BIT(19)
  44. #define EN7581_IMMD_INT_EN2 BIT(18)
  45. #define EN7581_IMMD_INT_EN1 BIT(17)
  46. #define EN7581_IMMD_INT_EN0 BIT(16)
  47. #define EN7581_TIME_OUT_INT_EN BIT(15)
  48. #define EN7581_NOHOTINTEN2 BIT(14)
  49. #define EN7581_HOFSINTEN2 BIT(13)
  50. #define EN7581_LOFSINTEN2 BIT(12)
  51. #define EN7581_HINTEN2 BIT(11)
  52. #define EN7581_CINTEN2 BIT(10)
  53. #define EN7581_NOHOTINTEN1 BIT(9)
  54. #define EN7581_HOFSINTEN1 BIT(8)
  55. #define EN7581_LOFSINTEN1 BIT(7)
  56. #define EN7581_HINTEN1 BIT(6)
  57. #define EN7581_CINTEN1 BIT(5)
  58. #define EN7581_NOHOTINTEN0 BIT(4)
  59. /* Similar to COLD and HOT also these seems to be swapped in documentation */
  60. #define EN7581_LOFSINTEN0 BIT(3) /* In documentation: BIT(2) */
  61. #define EN7581_HOFSINTEN0 BIT(2) /* In documentation: BIT(3) */
  62. /* It seems documentation have these swapped as the HW
  63. * - Fire BIT(1) when lower than EN7581_COLD_THRE
  64. * - Fire BIT(0) and BIT(5) when higher than EN7581_HOT2NORMAL_THRE or
  65. * EN7581_HOT_THRE
  66. */
  67. #define EN7581_CINTEN0 BIT(1) /* In documentation: BIT(0) */
  68. #define EN7581_HINTEN0 BIT(0) /* In documentation: BIT(1) */
  69. #define EN7581_TEMPMONINTSTS 0x810
  70. #define EN7581_STAGE3_INT_STAT BIT(31)
  71. #define EN7581_STAGE2_INT_STAT BIT(30)
  72. #define EN7581_STAGE1_INT_STAT BIT(29)
  73. #define EN7581_FILTER_INT_STAT_3 BIT(28)
  74. #define EN7581_IMMD_INT_STS3 BIT(27)
  75. #define EN7581_NOHOTINTSTS3 BIT(26)
  76. #define EN7581_HOFSINTSTS3 BIT(25)
  77. #define EN7581_LOFSINTSTS3 BIT(24)
  78. #define EN7581_HINTSTS3 BIT(23)
  79. #define EN7581_CINTSTS3 BIT(22)
  80. #define EN7581_FILTER_INT_STAT_2 BIT(21)
  81. #define EN7581_FILTER_INT_STAT_1 BIT(20)
  82. #define EN7581_FILTER_INT_STAT_0 BIT(19)
  83. #define EN7581_IMMD_INT_STS2 BIT(18)
  84. #define EN7581_IMMD_INT_STS1 BIT(17)
  85. #define EN7581_IMMD_INT_STS0 BIT(16)
  86. #define EN7581_TIME_OUT_INT_STAT BIT(15)
  87. #define EN7581_NOHOTINTSTS2 BIT(14)
  88. #define EN7581_HOFSINTSTS2 BIT(13)
  89. #define EN7581_LOFSINTSTS2 BIT(12)
  90. #define EN7581_HINTSTS2 BIT(11)
  91. #define EN7581_CINTSTS2 BIT(10)
  92. #define EN7581_NOHOTINTSTS1 BIT(9)
  93. #define EN7581_HOFSINTSTS1 BIT(8)
  94. #define EN7581_LOFSINTSTS1 BIT(7)
  95. #define EN7581_HINTSTS1 BIT(6)
  96. #define EN7581_CINTSTS1 BIT(5)
  97. #define EN7581_NOHOTINTSTS0 BIT(4)
  98. /* Similar to COLD and HOT also these seems to be swapped in documentation */
  99. #define EN7581_LOFSINTSTS0 BIT(3) /* In documentation: BIT(2) */
  100. #define EN7581_HOFSINTSTS0 BIT(2) /* In documentation: BIT(3) */
  101. /* It seems documentation have these swapped as the HW
  102. * - Fire BIT(1) when lower than EN7581_COLD_THRE
  103. * - Fire BIT(0) and BIT(5) when higher than EN7581_HOT2NORMAL_THRE or
  104. * EN7581_HOT_THRE
  105. *
  106. * To clear things, we swap the define but we keep them documented here.
  107. */
  108. #define EN7581_CINTSTS0 BIT(1) /* In documentation: BIT(0) */
  109. #define EN7581_HINTSTS0 BIT(0) /* In documentation: BIT(1)*/
  110. /* Monitor will take the bigger threshold between HOT2NORMAL and HOT
  111. * and will fire both HOT2NORMAL and HOT interrupt when higher than the 2
  112. *
  113. * It has also been observed that not setting HOT2NORMAL makes the monitor
  114. * treat COLD threshold as HOT2NORMAL.
  115. */
  116. #define EN7581_TEMPH2NTHRE 0x824
  117. /* It seems HOT2NORMAL is actually NORMAL2HOT */
  118. #define EN7581_HOT2NORMAL_THRE GENMASK(11, 0)
  119. #define EN7581_TEMPHTHRE 0x828
  120. #define EN7581_HOT_THRE GENMASK(11, 0)
  121. /* Monitor will use this as HOT2NORMAL (fire interrupt when lower than...)*/
  122. #define EN7581_TEMPCTHRE 0x82c
  123. #define EN7581_COLD_THRE GENMASK(11, 0)
  124. /* Also LOW and HIGH offset register are swapped */
  125. #define EN7581_TEMPOFFSETL 0x830 /* In documentation: 0x834 */
  126. #define EN7581_LOW_OFFSET GENMASK(11, 0)
  127. #define EN7581_TEMPOFFSETH 0x834 /* In documentation: 0x830 */
  128. #define EN7581_HIGH_OFFSET GENMASK(11, 0)
  129. #define EN7581_TEMPMSRCTL0 0x838
  130. #define EN7581_MSRCTL3 GENMASK(11, 9)
  131. #define EN7581_MSRCTL2 GENMASK(8, 6)
  132. #define EN7581_MSRCTL1 GENMASK(5, 3)
  133. #define EN7581_MSRCTL0 GENMASK(2, 0)
  134. #define EN7581_TEMPADCVALIDADDR 0x878
  135. #define EN7581_ADC_VALID_ADDR GENMASK(31, 0)
  136. #define EN7581_TEMPADCVOLTADDR 0x87c
  137. #define EN7581_ADC_VOLT_ADDR GENMASK(31, 0)
  138. #define EN7581_TEMPRDCTRL 0x880
  139. /*
  140. * NOTICE: AHB have this set to 0 by default. Means that
  141. * the same addr is used for ADC volt and valid reading.
  142. * In such case, VALID ADDR is used and volt addr is ignored.
  143. */
  144. #define EN7581_RD_CTRL_DIFF BIT(0)
  145. #define EN7581_TEMPADCVALIDMASK 0x884
  146. #define EN7581_ADV_RD_VALID_POLARITY BIT(5)
  147. #define EN7581_ADV_RD_VALID_POS GENMASK(4, 0)
  148. #define EN7581_TEMPADCVOLTAGESHIFT 0x888
  149. #define EN7581_ADC_VOLTAGE_SHIFT GENMASK(4, 0)
  150. /*
  151. * Same values for each CTL.
  152. * Can operate in:
  153. * - 1 sample
  154. * - 2 sample and make average of them
  155. * - 4,6,10,16 sample, drop max and min and make average of them
  156. */
  157. #define EN7581_MSRCTL_1SAMPLE 0x0
  158. #define EN7581_MSRCTL_AVG2SAMPLE 0x1
  159. #define EN7581_MSRCTL_4SAMPLE_MAX_MIX_AVG2 0x2
  160. #define EN7581_MSRCTL_6SAMPLE_MAX_MIX_AVG4 0x3
  161. #define EN7581_MSRCTL_10SAMPLE_MAX_MIX_AVG8 0x4
  162. #define EN7581_MSRCTL_18SAMPLE_MAX_MIX_AVG16 0x5
  163. #define EN7581_TEMPAHBPOLL 0x840
  164. #define EN7581_ADC_POLL_INTVL GENMASK(31, 0)
  165. /* PTPSPARE0,2 reg are used to store efuse info for calibrated temp offset */
  166. #define EN7581_EFUSE_TEMP_OFFSET_REG 0xf20 /* PTPSPARE0 */
  167. #define EN7581_EFUSE_TEMP_OFFSET GENMASK(31, 16)
  168. #define EN7581_PTPSPARE1 0xf24 /* PTPSPARE1 */
  169. #define EN7581_EFUSE_TEMP_CPU_SENSOR_REG 0xf28 /* PTPSPARE2 */
  170. #define EN7581_SLOPE_X100_DIO_DEFAULT 5645
  171. #define EN7581_SLOPE_X100_DIO_AVS 5645
  172. #define EN7581_INIT_TEMP_CPK_X10 300
  173. #define EN7581_INIT_TEMP_FTK_X10 620
  174. #define EN7581_INIT_TEMP_NONK_X10 550
  175. #define EN7581_SCU_THERMAL_PROTECT_KEY 0x12
  176. #define EN7581_SCU_THERMAL_MUX_DIODE1 0x7
  177. /* Convert temp to raw value as read from ADC ((((temp / 100) - init) * slope) / 1000) + offset */
  178. #define TEMP_TO_RAW(priv, temp) ((((((temp) / 100) - (priv)->init_temp) * \
  179. (priv)->default_slope) / 1000) + \
  180. (priv)->default_offset)
  181. /* Convert raw to temp ((((temp - offset) * 1000) / slope + init) * 100) */
  182. #define RAW_TO_TEMP(priv, raw) (((((raw) - (priv)->default_offset) * 1000) / \
  183. (priv)->default_slope + \
  184. (priv)->init_temp) * 100)
  185. #define AIROHA_MAX_SAMPLES 6
  186. struct airoha_thermal_priv {
  187. void __iomem *base;
  188. struct regmap *chip_scu;
  189. struct resource scu_adc_res;
  190. struct thermal_zone_device *tz;
  191. int init_temp;
  192. int default_slope;
  193. int default_offset;
  194. };
  195. static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv)
  196. {
  197. u32 val;
  198. regmap_read(priv->chip_scu, EN7581_DOUT_TADC, &val);
  199. return FIELD_GET(EN7581_DOUT_TADC_MASK, val);
  200. }
  201. static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv)
  202. {
  203. u32 adc_mux, pllrg;
  204. /* Save PLLRG current value */
  205. regmap_read(priv->chip_scu, EN7581_PLLRG_PROTECT, &pllrg);
  206. /* Give access to thermal regs */
  207. regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, EN7581_SCU_THERMAL_PROTECT_KEY);
  208. adc_mux = FIELD_PREP(EN7581_MUX_TADC, EN7581_SCU_THERMAL_MUX_DIODE1);
  209. regmap_write(priv->chip_scu, EN7581_PWD_TADC, adc_mux);
  210. /* Restore PLLRG value on exit */
  211. regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, pllrg);
  212. }
  213. static int airoha_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
  214. {
  215. struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz);
  216. int min_value, max_value, avg_value, value;
  217. int i;
  218. avg_value = 0;
  219. min_value = INT_MAX;
  220. max_value = INT_MIN;
  221. for (i = 0; i < AIROHA_MAX_SAMPLES; i++) {
  222. value = airoha_get_thermal_ADC(priv);
  223. min_value = min(value, min_value);
  224. max_value = max(value, max_value);
  225. avg_value += value;
  226. }
  227. /* Drop min and max and average for the remaining sample */
  228. avg_value -= (min_value + max_value);
  229. avg_value /= AIROHA_MAX_SAMPLES - 2;
  230. *temp = RAW_TO_TEMP(priv, avg_value);
  231. return 0;
  232. }
  233. static int airoha_thermal_set_trips(struct thermal_zone_device *tz, int low,
  234. int high)
  235. {
  236. struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz);
  237. bool enable_monitor = false;
  238. if (high != INT_MAX) {
  239. /* Validate high and clamp it a supported value */
  240. high = clamp_t(int, high, RAW_TO_TEMP(priv, 0),
  241. RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK)));
  242. /* We offset the high temp of 1°C to trigger correct event */
  243. writel(TEMP_TO_RAW(priv, high) >> 4,
  244. priv->base + EN7581_TEMPOFFSETH);
  245. enable_monitor = true;
  246. }
  247. if (low != -INT_MAX) {
  248. /* Validate low and clamp it to a supported value */
  249. low = clamp_t(int, high, RAW_TO_TEMP(priv, 0),
  250. RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK)));
  251. /* We offset the low temp of 1°C to trigger correct event */
  252. writel(TEMP_TO_RAW(priv, low) >> 4,
  253. priv->base + EN7581_TEMPOFFSETL);
  254. enable_monitor = true;
  255. }
  256. /* Enable sensor 0 monitor after trip are set */
  257. if (enable_monitor)
  258. writel(EN7581_SENSE0_EN, priv->base + EN7581_TEMPMONCTL0);
  259. return 0;
  260. }
  261. static const struct thermal_zone_device_ops thdev_ops = {
  262. .get_temp = airoha_thermal_get_temp,
  263. .set_trips = airoha_thermal_set_trips,
  264. };
  265. static irqreturn_t airoha_thermal_irq(int irq, void *data)
  266. {
  267. struct airoha_thermal_priv *priv = data;
  268. enum thermal_notify_event event;
  269. bool update = false;
  270. u32 status;
  271. status = readl(priv->base + EN7581_TEMPMONINTSTS);
  272. switch (status & (EN7581_HOFSINTSTS0 | EN7581_LOFSINTSTS0)) {
  273. case EN7581_HOFSINTSTS0:
  274. event = THERMAL_TRIP_VIOLATED;
  275. update = true;
  276. break;
  277. case EN7581_LOFSINTSTS0:
  278. event = THERMAL_EVENT_UNSPECIFIED;
  279. update = true;
  280. break;
  281. default:
  282. /* Should be impossible as we enable only these Interrupt */
  283. break;
  284. }
  285. /* Reset Interrupt */
  286. writel(status, priv->base + EN7581_TEMPMONINTSTS);
  287. if (update)
  288. thermal_zone_device_update(priv->tz, event);
  289. return IRQ_HANDLED;
  290. }
  291. static void airoha_thermal_setup_adc_val(struct device *dev,
  292. struct airoha_thermal_priv *priv)
  293. {
  294. u32 efuse_calib_info, cpu_sensor;
  295. /* Setup thermal sensor to ADC mode and setup the mux to DIODE1 */
  296. airoha_init_thermal_ADC_mode(priv);
  297. /* sleep 10 ms for ADC to enable */
  298. usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC);
  299. efuse_calib_info = readl(priv->base + EN7581_EFUSE_TEMP_OFFSET_REG);
  300. if (efuse_calib_info) {
  301. priv->default_offset = FIELD_GET(EN7581_EFUSE_TEMP_OFFSET, efuse_calib_info);
  302. /* Different slope are applied if the sensor is used for CPU or for package */
  303. cpu_sensor = readl(priv->base + EN7581_EFUSE_TEMP_CPU_SENSOR_REG);
  304. if (cpu_sensor) {
  305. priv->default_slope = EN7581_SLOPE_X100_DIO_DEFAULT;
  306. priv->init_temp = EN7581_INIT_TEMP_FTK_X10;
  307. } else {
  308. priv->default_slope = EN7581_SLOPE_X100_DIO_AVS;
  309. priv->init_temp = EN7581_INIT_TEMP_CPK_X10;
  310. }
  311. } else {
  312. priv->default_offset = airoha_get_thermal_ADC(priv);
  313. priv->default_slope = EN7581_SLOPE_X100_DIO_DEFAULT;
  314. priv->init_temp = EN7581_INIT_TEMP_NONK_X10;
  315. dev_info(dev, "missing thermal calibration EFUSE, using non calibrated value\n");
  316. }
  317. }
  318. static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv)
  319. {
  320. /* Set measure mode */
  321. writel(FIELD_PREP(EN7581_MSRCTL0, EN7581_MSRCTL_6SAMPLE_MAX_MIX_AVG4),
  322. priv->base + EN7581_TEMPMSRCTL0);
  323. /*
  324. * Configure ADC valid reading addr
  325. * The AHB temp monitor system doesn't have direct access to the
  326. * thermal sensor. It does instead work by providing various
  327. * addresses to configure how to access and setup an ADC for the
  328. * sensor. EN7581 supports only one sensor hence the
  329. * implementation is greatly simplified but the AHB supports
  330. * up to 4 different sensors from the same ADC that can be
  331. * switched by tuning the ADC mux or writing address.
  332. *
  333. * We set valid instead of volt as we don't enable valid/volt
  334. * split reading and AHB read valid addr in such case.
  335. */
  336. writel(priv->scu_adc_res.start + EN7581_DOUT_TADC,
  337. priv->base + EN7581_TEMPADCVALIDADDR);
  338. /*
  339. * Configure valid bit on a fake value of bit 16. The ADC outputs
  340. * max of 2 bytes for voltage.
  341. */
  342. writel(FIELD_PREP(EN7581_ADV_RD_VALID_POS, 16),
  343. priv->base + EN7581_TEMPADCVALIDMASK);
  344. /*
  345. * AHB supports max 12 bytes for ADC voltage. Shift the read
  346. * value 4 bit to the right. Precision lost by this is minimal
  347. * in the order of half a °C and is acceptable in the context
  348. * of triggering interrupt in critical condition.
  349. */
  350. writel(FIELD_PREP(EN7581_ADC_VOLTAGE_SHIFT, 4),
  351. priv->base + EN7581_TEMPADCVOLTAGESHIFT);
  352. /* BUS clock is 300MHz counting unit is 3 * 68.64 * 256 = 52.715us */
  353. writel(FIELD_PREP(EN7581_PERIOD_UNIT, 3),
  354. priv->base + EN7581_TEMPMONCTL1);
  355. /*
  356. * filt interval is 1 * 52.715us = 52.715us,
  357. * sen interval is 379 * 52.715us = 19.97ms
  358. */
  359. writel(FIELD_PREP(EN7581_FILT_INTERVAL, 1) |
  360. FIELD_PREP(EN7581_FILT_INTERVAL, 379),
  361. priv->base + EN7581_TEMPMONCTL2);
  362. /* AHB poll is set to 146 * 68.64 = 10.02us */
  363. writel(FIELD_PREP(EN7581_ADC_POLL_INTVL, 146),
  364. priv->base + EN7581_TEMPAHBPOLL);
  365. }
  366. static int airoha_thermal_probe(struct platform_device *pdev)
  367. {
  368. struct airoha_thermal_priv *priv;
  369. struct device_node *chip_scu_np;
  370. struct device *dev = &pdev->dev;
  371. int irq, ret;
  372. priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
  373. if (!priv)
  374. return -ENOMEM;
  375. priv->base = devm_platform_ioremap_resource(pdev, 0);
  376. if (IS_ERR(priv->base))
  377. return PTR_ERR(priv->base);
  378. chip_scu_np = of_parse_phandle(dev->of_node, "airoha,chip-scu", 0);
  379. if (!chip_scu_np)
  380. return -EINVAL;
  381. priv->chip_scu = syscon_node_to_regmap(chip_scu_np);
  382. if (IS_ERR(priv->chip_scu))
  383. return PTR_ERR(priv->chip_scu);
  384. of_address_to_resource(chip_scu_np, 0, &priv->scu_adc_res);
  385. of_node_put(chip_scu_np);
  386. irq = platform_get_irq(pdev, 0);
  387. if (irq < 0)
  388. return irq;
  389. ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
  390. airoha_thermal_irq, IRQF_ONESHOT,
  391. pdev->name, priv);
  392. if (ret) {
  393. dev_err(dev, "Can't get interrupt working.\n");
  394. return ret;
  395. }
  396. airoha_thermal_setup_monitor(priv);
  397. airoha_thermal_setup_adc_val(dev, priv);
  398. /* register of thermal sensor and get info from DT */
  399. priv->tz = devm_thermal_of_zone_register(dev, 0, priv, &thdev_ops);
  400. if (IS_ERR(priv->tz)) {
  401. dev_err(dev, "register thermal zone sensor failed\n");
  402. return PTR_ERR(priv->tz);
  403. }
  404. platform_set_drvdata(pdev, priv);
  405. /* Enable LOW and HIGH interrupt */
  406. writel(EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0,
  407. priv->base + EN7581_TEMPMONINT);
  408. return 0;
  409. }
  410. static const struct of_device_id airoha_thermal_match[] = {
  411. { .compatible = "airoha,en7581-thermal" },
  412. {},
  413. };
  414. MODULE_DEVICE_TABLE(of, airoha_thermal_match);
  415. static struct platform_driver airoha_thermal_driver = {
  416. .driver = {
  417. .name = "airoha-thermal",
  418. .of_match_table = airoha_thermal_match,
  419. },
  420. .probe = airoha_thermal_probe,
  421. };
  422. module_platform_driver(airoha_thermal_driver);
  423. MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
  424. MODULE_DESCRIPTION("Airoha thermal driver");
  425. MODULE_LICENSE("GPL");