xref: /linux/drivers/hwmon/sfctemp.c (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
17f2958e8SEmil Renner Berthing // SPDX-License-Identifier: GPL-2.0
27f2958e8SEmil Renner Berthing /*
37f2958e8SEmil Renner Berthing  * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
47f2958e8SEmil Renner Berthing  * Copyright (C) 2021 Samin Guo <samin.guo@starfivetech.com>
57f2958e8SEmil Renner Berthing  */
67f2958e8SEmil Renner Berthing 
77f2958e8SEmil Renner Berthing #include <linux/bits.h>
87f2958e8SEmil Renner Berthing #include <linux/clk.h>
97f2958e8SEmil Renner Berthing #include <linux/delay.h>
107f2958e8SEmil Renner Berthing #include <linux/hwmon.h>
117f2958e8SEmil Renner Berthing #include <linux/io.h>
127f2958e8SEmil Renner Berthing #include <linux/module.h>
137f2958e8SEmil Renner Berthing #include <linux/mutex.h>
147f2958e8SEmil Renner Berthing #include <linux/of.h>
157f2958e8SEmil Renner Berthing #include <linux/platform_device.h>
167f2958e8SEmil Renner Berthing #include <linux/reset.h>
177f2958e8SEmil Renner Berthing 
187f2958e8SEmil Renner Berthing /*
197f2958e8SEmil Renner Berthing  * TempSensor reset. The RSTN can be de-asserted once the analog core has
207f2958e8SEmil Renner Berthing  * powered up. Trst(min 100ns)
217f2958e8SEmil Renner Berthing  * 0:reset  1:de-assert
227f2958e8SEmil Renner Berthing  */
237f2958e8SEmil Renner Berthing #define SFCTEMP_RSTN	BIT(0)
247f2958e8SEmil Renner Berthing 
257f2958e8SEmil Renner Berthing /*
267f2958e8SEmil Renner Berthing  * TempSensor analog core power down. The analog core will be powered up
277f2958e8SEmil Renner Berthing  * Tpu(min 50us) after PD is de-asserted. RSTN should be held low until the
287f2958e8SEmil Renner Berthing  * analog core is powered up.
297f2958e8SEmil Renner Berthing  * 0:power up  1:power down
307f2958e8SEmil Renner Berthing  */
317f2958e8SEmil Renner Berthing #define SFCTEMP_PD	BIT(1)
327f2958e8SEmil Renner Berthing 
337f2958e8SEmil Renner Berthing /*
347f2958e8SEmil Renner Berthing  * TempSensor start conversion enable.
357f2958e8SEmil Renner Berthing  * 0:disable  1:enable
367f2958e8SEmil Renner Berthing  */
377f2958e8SEmil Renner Berthing #define SFCTEMP_RUN	BIT(2)
387f2958e8SEmil Renner Berthing 
397f2958e8SEmil Renner Berthing /*
407f2958e8SEmil Renner Berthing  * TempSensor conversion value output.
417f2958e8SEmil Renner Berthing  * Temp(C)=DOUT*Y/4094 - K
427f2958e8SEmil Renner Berthing  */
437f2958e8SEmil Renner Berthing #define SFCTEMP_DOUT_POS	16
447f2958e8SEmil Renner Berthing #define SFCTEMP_DOUT_MSK	GENMASK(27, 16)
457f2958e8SEmil Renner Berthing 
467f2958e8SEmil Renner Berthing /* DOUT to Celcius conversion constants */
477f2958e8SEmil Renner Berthing #define SFCTEMP_Y1000	237500L
487f2958e8SEmil Renner Berthing #define SFCTEMP_Z	4094L
497f2958e8SEmil Renner Berthing #define SFCTEMP_K1000	81100L
507f2958e8SEmil Renner Berthing 
517f2958e8SEmil Renner Berthing struct sfctemp {
527f2958e8SEmil Renner Berthing 	/* serialize access to hardware register and enabled below */
537f2958e8SEmil Renner Berthing 	struct mutex lock;
547f2958e8SEmil Renner Berthing 	void __iomem *regs;
557f2958e8SEmil Renner Berthing 	struct clk *clk_sense;
567f2958e8SEmil Renner Berthing 	struct clk *clk_bus;
577f2958e8SEmil Renner Berthing 	struct reset_control *rst_sense;
587f2958e8SEmil Renner Berthing 	struct reset_control *rst_bus;
597f2958e8SEmil Renner Berthing 	bool enabled;
607f2958e8SEmil Renner Berthing };
617f2958e8SEmil Renner Berthing 
sfctemp_power_up(struct sfctemp * sfctemp)627f2958e8SEmil Renner Berthing static void sfctemp_power_up(struct sfctemp *sfctemp)
637f2958e8SEmil Renner Berthing {
647f2958e8SEmil Renner Berthing 	/* make sure we're powered down first */
657f2958e8SEmil Renner Berthing 	writel(SFCTEMP_PD, sfctemp->regs);
667f2958e8SEmil Renner Berthing 	udelay(1);
677f2958e8SEmil Renner Berthing 
687f2958e8SEmil Renner Berthing 	writel(0, sfctemp->regs);
697f2958e8SEmil Renner Berthing 	/* wait t_pu(50us) + t_rst(100ns) */
707f2958e8SEmil Renner Berthing 	usleep_range(60, 200);
717f2958e8SEmil Renner Berthing 
727f2958e8SEmil Renner Berthing 	/* de-assert reset */
737f2958e8SEmil Renner Berthing 	writel(SFCTEMP_RSTN, sfctemp->regs);
747f2958e8SEmil Renner Berthing 	udelay(1); /* wait t_su(500ps) */
757f2958e8SEmil Renner Berthing }
767f2958e8SEmil Renner Berthing 
sfctemp_power_down(struct sfctemp * sfctemp)777f2958e8SEmil Renner Berthing static void sfctemp_power_down(struct sfctemp *sfctemp)
787f2958e8SEmil Renner Berthing {
797f2958e8SEmil Renner Berthing 	writel(SFCTEMP_PD, sfctemp->regs);
807f2958e8SEmil Renner Berthing }
817f2958e8SEmil Renner Berthing 
sfctemp_run(struct sfctemp * sfctemp)827f2958e8SEmil Renner Berthing static void sfctemp_run(struct sfctemp *sfctemp)
837f2958e8SEmil Renner Berthing {
847f2958e8SEmil Renner Berthing 	writel(SFCTEMP_RSTN | SFCTEMP_RUN, sfctemp->regs);
857f2958e8SEmil Renner Berthing 	udelay(1);
867f2958e8SEmil Renner Berthing }
877f2958e8SEmil Renner Berthing 
sfctemp_stop(struct sfctemp * sfctemp)887f2958e8SEmil Renner Berthing static void sfctemp_stop(struct sfctemp *sfctemp)
897f2958e8SEmil Renner Berthing {
907f2958e8SEmil Renner Berthing 	writel(SFCTEMP_RSTN, sfctemp->regs);
917f2958e8SEmil Renner Berthing }
927f2958e8SEmil Renner Berthing 
sfctemp_enable(struct sfctemp * sfctemp)937f2958e8SEmil Renner Berthing static int sfctemp_enable(struct sfctemp *sfctemp)
947f2958e8SEmil Renner Berthing {
957f2958e8SEmil Renner Berthing 	int ret = 0;
967f2958e8SEmil Renner Berthing 
977f2958e8SEmil Renner Berthing 	mutex_lock(&sfctemp->lock);
987f2958e8SEmil Renner Berthing 	if (sfctemp->enabled)
997f2958e8SEmil Renner Berthing 		goto done;
1007f2958e8SEmil Renner Berthing 
1017f2958e8SEmil Renner Berthing 	ret = clk_prepare_enable(sfctemp->clk_bus);
1027f2958e8SEmil Renner Berthing 	if (ret)
1037f2958e8SEmil Renner Berthing 		goto err;
1047f2958e8SEmil Renner Berthing 	ret = reset_control_deassert(sfctemp->rst_bus);
1057f2958e8SEmil Renner Berthing 	if (ret)
1067f2958e8SEmil Renner Berthing 		goto err_disable_bus;
1077f2958e8SEmil Renner Berthing 
1087f2958e8SEmil Renner Berthing 	ret = clk_prepare_enable(sfctemp->clk_sense);
1097f2958e8SEmil Renner Berthing 	if (ret)
1107f2958e8SEmil Renner Berthing 		goto err_assert_bus;
1117f2958e8SEmil Renner Berthing 	ret = reset_control_deassert(sfctemp->rst_sense);
1127f2958e8SEmil Renner Berthing 	if (ret)
1137f2958e8SEmil Renner Berthing 		goto err_disable_sense;
1147f2958e8SEmil Renner Berthing 
1157f2958e8SEmil Renner Berthing 	sfctemp_power_up(sfctemp);
1167f2958e8SEmil Renner Berthing 	sfctemp_run(sfctemp);
1177f2958e8SEmil Renner Berthing 	sfctemp->enabled = true;
1187f2958e8SEmil Renner Berthing done:
1197f2958e8SEmil Renner Berthing 	mutex_unlock(&sfctemp->lock);
1207f2958e8SEmil Renner Berthing 	return ret;
1217f2958e8SEmil Renner Berthing 
1227f2958e8SEmil Renner Berthing err_disable_sense:
1237f2958e8SEmil Renner Berthing 	clk_disable_unprepare(sfctemp->clk_sense);
1247f2958e8SEmil Renner Berthing err_assert_bus:
1257f2958e8SEmil Renner Berthing 	reset_control_assert(sfctemp->rst_bus);
1267f2958e8SEmil Renner Berthing err_disable_bus:
1277f2958e8SEmil Renner Berthing 	clk_disable_unprepare(sfctemp->clk_bus);
1287f2958e8SEmil Renner Berthing err:
1297f2958e8SEmil Renner Berthing 	mutex_unlock(&sfctemp->lock);
1307f2958e8SEmil Renner Berthing 	return ret;
1317f2958e8SEmil Renner Berthing }
1327f2958e8SEmil Renner Berthing 
sfctemp_disable(struct sfctemp * sfctemp)1337f2958e8SEmil Renner Berthing static int sfctemp_disable(struct sfctemp *sfctemp)
1347f2958e8SEmil Renner Berthing {
1357f2958e8SEmil Renner Berthing 	mutex_lock(&sfctemp->lock);
1367f2958e8SEmil Renner Berthing 	if (!sfctemp->enabled)
1377f2958e8SEmil Renner Berthing 		goto done;
1387f2958e8SEmil Renner Berthing 
1397f2958e8SEmil Renner Berthing 	sfctemp_stop(sfctemp);
1407f2958e8SEmil Renner Berthing 	sfctemp_power_down(sfctemp);
1417f2958e8SEmil Renner Berthing 	reset_control_assert(sfctemp->rst_sense);
1427f2958e8SEmil Renner Berthing 	clk_disable_unprepare(sfctemp->clk_sense);
1437f2958e8SEmil Renner Berthing 	reset_control_assert(sfctemp->rst_bus);
1447f2958e8SEmil Renner Berthing 	clk_disable_unprepare(sfctemp->clk_bus);
1457f2958e8SEmil Renner Berthing 	sfctemp->enabled = false;
1467f2958e8SEmil Renner Berthing done:
1477f2958e8SEmil Renner Berthing 	mutex_unlock(&sfctemp->lock);
1487f2958e8SEmil Renner Berthing 	return 0;
1497f2958e8SEmil Renner Berthing }
1507f2958e8SEmil Renner Berthing 
sfctemp_disable_action(void * data)1517f2958e8SEmil Renner Berthing static void sfctemp_disable_action(void *data)
1527f2958e8SEmil Renner Berthing {
1537f2958e8SEmil Renner Berthing 	sfctemp_disable(data);
1547f2958e8SEmil Renner Berthing }
1557f2958e8SEmil Renner Berthing 
sfctemp_convert(struct sfctemp * sfctemp,long * val)1567f2958e8SEmil Renner Berthing static int sfctemp_convert(struct sfctemp *sfctemp, long *val)
1577f2958e8SEmil Renner Berthing {
1587f2958e8SEmil Renner Berthing 	int ret;
1597f2958e8SEmil Renner Berthing 
1607f2958e8SEmil Renner Berthing 	mutex_lock(&sfctemp->lock);
1617f2958e8SEmil Renner Berthing 	if (!sfctemp->enabled) {
1627f2958e8SEmil Renner Berthing 		ret = -ENODATA;
1637f2958e8SEmil Renner Berthing 		goto out;
1647f2958e8SEmil Renner Berthing 	}
1657f2958e8SEmil Renner Berthing 
1667f2958e8SEmil Renner Berthing 	/* calculate temperature in milli Celcius */
1677f2958e8SEmil Renner Berthing 	*val = (long)((readl(sfctemp->regs) & SFCTEMP_DOUT_MSK) >> SFCTEMP_DOUT_POS)
1687f2958e8SEmil Renner Berthing 		* SFCTEMP_Y1000 / SFCTEMP_Z - SFCTEMP_K1000;
1697f2958e8SEmil Renner Berthing 
1707f2958e8SEmil Renner Berthing 	ret = 0;
1717f2958e8SEmil Renner Berthing out:
1727f2958e8SEmil Renner Berthing 	mutex_unlock(&sfctemp->lock);
1737f2958e8SEmil Renner Berthing 	return ret;
1747f2958e8SEmil Renner Berthing }
1757f2958e8SEmil Renner Berthing 
sfctemp_is_visible(const void * data,enum hwmon_sensor_types type,u32 attr,int channel)1767f2958e8SEmil Renner Berthing static umode_t sfctemp_is_visible(const void *data, enum hwmon_sensor_types type,
1777f2958e8SEmil Renner Berthing 				  u32 attr, int channel)
1787f2958e8SEmil Renner Berthing {
1797f2958e8SEmil Renner Berthing 	switch (type) {
1807f2958e8SEmil Renner Berthing 	case hwmon_temp:
1817f2958e8SEmil Renner Berthing 		switch (attr) {
1827f2958e8SEmil Renner Berthing 		case hwmon_temp_enable:
1837f2958e8SEmil Renner Berthing 			return 0644;
1847f2958e8SEmil Renner Berthing 		case hwmon_temp_input:
1857f2958e8SEmil Renner Berthing 			return 0444;
1867f2958e8SEmil Renner Berthing 		default:
1877f2958e8SEmil Renner Berthing 			return 0;
1887f2958e8SEmil Renner Berthing 		}
1897f2958e8SEmil Renner Berthing 	default:
1907f2958e8SEmil Renner Berthing 		return 0;
1917f2958e8SEmil Renner Berthing 	}
1927f2958e8SEmil Renner Berthing }
1937f2958e8SEmil Renner Berthing 
sfctemp_read(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,long * val)1947f2958e8SEmil Renner Berthing static int sfctemp_read(struct device *dev, enum hwmon_sensor_types type,
1957f2958e8SEmil Renner Berthing 			u32 attr, int channel, long *val)
1967f2958e8SEmil Renner Berthing {
1977f2958e8SEmil Renner Berthing 	struct sfctemp *sfctemp = dev_get_drvdata(dev);
1987f2958e8SEmil Renner Berthing 
1997f2958e8SEmil Renner Berthing 	switch (type) {
2007f2958e8SEmil Renner Berthing 	case hwmon_temp:
2017f2958e8SEmil Renner Berthing 		switch (attr) {
2027f2958e8SEmil Renner Berthing 		case hwmon_temp_enable:
2037f2958e8SEmil Renner Berthing 			*val = sfctemp->enabled;
2047f2958e8SEmil Renner Berthing 			return 0;
2057f2958e8SEmil Renner Berthing 		case hwmon_temp_input:
2067f2958e8SEmil Renner Berthing 			return sfctemp_convert(sfctemp, val);
2077f2958e8SEmil Renner Berthing 		default:
2087f2958e8SEmil Renner Berthing 			return -EINVAL;
2097f2958e8SEmil Renner Berthing 		}
2107f2958e8SEmil Renner Berthing 	default:
2117f2958e8SEmil Renner Berthing 		return -EINVAL;
2127f2958e8SEmil Renner Berthing 	}
2137f2958e8SEmil Renner Berthing }
2147f2958e8SEmil Renner Berthing 
sfctemp_write(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,long val)2157f2958e8SEmil Renner Berthing static int sfctemp_write(struct device *dev, enum hwmon_sensor_types type,
2167f2958e8SEmil Renner Berthing 			 u32 attr, int channel, long val)
2177f2958e8SEmil Renner Berthing {
2187f2958e8SEmil Renner Berthing 	struct sfctemp *sfctemp = dev_get_drvdata(dev);
2197f2958e8SEmil Renner Berthing 
2207f2958e8SEmil Renner Berthing 	switch (type) {
2217f2958e8SEmil Renner Berthing 	case hwmon_temp:
2227f2958e8SEmil Renner Berthing 		switch (attr) {
2237f2958e8SEmil Renner Berthing 		case hwmon_temp_enable:
2247f2958e8SEmil Renner Berthing 			if (val == 0)
2257f2958e8SEmil Renner Berthing 				return sfctemp_disable(sfctemp);
2267f2958e8SEmil Renner Berthing 			if (val == 1)
2277f2958e8SEmil Renner Berthing 				return sfctemp_enable(sfctemp);
2287f2958e8SEmil Renner Berthing 			return -EINVAL;
2297f2958e8SEmil Renner Berthing 		default:
2307f2958e8SEmil Renner Berthing 			return -EINVAL;
2317f2958e8SEmil Renner Berthing 		}
2327f2958e8SEmil Renner Berthing 	default:
2337f2958e8SEmil Renner Berthing 		return -EINVAL;
2347f2958e8SEmil Renner Berthing 	}
2357f2958e8SEmil Renner Berthing }
2367f2958e8SEmil Renner Berthing 
2377f2958e8SEmil Renner Berthing static const struct hwmon_channel_info *sfctemp_info[] = {
2387f2958e8SEmil Renner Berthing 	HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
2397f2958e8SEmil Renner Berthing 	HWMON_CHANNEL_INFO(temp, HWMON_T_ENABLE | HWMON_T_INPUT),
2407f2958e8SEmil Renner Berthing 	NULL
2417f2958e8SEmil Renner Berthing };
2427f2958e8SEmil Renner Berthing 
2437f2958e8SEmil Renner Berthing static const struct hwmon_ops sfctemp_hwmon_ops = {
2447f2958e8SEmil Renner Berthing 	.is_visible = sfctemp_is_visible,
2457f2958e8SEmil Renner Berthing 	.read = sfctemp_read,
2467f2958e8SEmil Renner Berthing 	.write = sfctemp_write,
2477f2958e8SEmil Renner Berthing };
2487f2958e8SEmil Renner Berthing 
2497f2958e8SEmil Renner Berthing static const struct hwmon_chip_info sfctemp_chip_info = {
2507f2958e8SEmil Renner Berthing 	.ops = &sfctemp_hwmon_ops,
2517f2958e8SEmil Renner Berthing 	.info = sfctemp_info,
2527f2958e8SEmil Renner Berthing };
2537f2958e8SEmil Renner Berthing 
sfctemp_probe(struct platform_device * pdev)2547f2958e8SEmil Renner Berthing static int sfctemp_probe(struct platform_device *pdev)
2557f2958e8SEmil Renner Berthing {
2567f2958e8SEmil Renner Berthing 	struct device *dev = &pdev->dev;
2577f2958e8SEmil Renner Berthing 	struct device *hwmon_dev;
2587f2958e8SEmil Renner Berthing 	struct sfctemp *sfctemp;
2597f2958e8SEmil Renner Berthing 	int ret;
2607f2958e8SEmil Renner Berthing 
2617f2958e8SEmil Renner Berthing 	sfctemp = devm_kzalloc(dev, sizeof(*sfctemp), GFP_KERNEL);
2627f2958e8SEmil Renner Berthing 	if (!sfctemp)
2637f2958e8SEmil Renner Berthing 		return -ENOMEM;
2647f2958e8SEmil Renner Berthing 
2657f2958e8SEmil Renner Berthing 	dev_set_drvdata(dev, sfctemp);
2667f2958e8SEmil Renner Berthing 	mutex_init(&sfctemp->lock);
2677f2958e8SEmil Renner Berthing 
2687f2958e8SEmil Renner Berthing 	sfctemp->regs = devm_platform_ioremap_resource(pdev, 0);
2697f2958e8SEmil Renner Berthing 	if (IS_ERR(sfctemp->regs))
2707f2958e8SEmil Renner Berthing 		return PTR_ERR(sfctemp->regs);
2717f2958e8SEmil Renner Berthing 
2727f2958e8SEmil Renner Berthing 	sfctemp->clk_sense = devm_clk_get(dev, "sense");
2737f2958e8SEmil Renner Berthing 	if (IS_ERR(sfctemp->clk_sense))
2747f2958e8SEmil Renner Berthing 		return dev_err_probe(dev, PTR_ERR(sfctemp->clk_sense),
2757f2958e8SEmil Renner Berthing 				     "error getting sense clock\n");
2767f2958e8SEmil Renner Berthing 
2777f2958e8SEmil Renner Berthing 	sfctemp->clk_bus = devm_clk_get(dev, "bus");
2787f2958e8SEmil Renner Berthing 	if (IS_ERR(sfctemp->clk_bus))
2797f2958e8SEmil Renner Berthing 		return dev_err_probe(dev, PTR_ERR(sfctemp->clk_bus),
2807f2958e8SEmil Renner Berthing 				     "error getting bus clock\n");
2817f2958e8SEmil Renner Berthing 
2827f2958e8SEmil Renner Berthing 	sfctemp->rst_sense = devm_reset_control_get_exclusive(dev, "sense");
2837f2958e8SEmil Renner Berthing 	if (IS_ERR(sfctemp->rst_sense))
2847f2958e8SEmil Renner Berthing 		return dev_err_probe(dev, PTR_ERR(sfctemp->rst_sense),
2857f2958e8SEmil Renner Berthing 				     "error getting sense reset\n");
2867f2958e8SEmil Renner Berthing 
2877f2958e8SEmil Renner Berthing 	sfctemp->rst_bus = devm_reset_control_get_exclusive(dev, "bus");
2887f2958e8SEmil Renner Berthing 	if (IS_ERR(sfctemp->rst_bus))
2897f2958e8SEmil Renner Berthing 		return dev_err_probe(dev, PTR_ERR(sfctemp->rst_bus),
2907f2958e8SEmil Renner Berthing 				     "error getting busreset\n");
2917f2958e8SEmil Renner Berthing 
2927f2958e8SEmil Renner Berthing 	ret = reset_control_assert(sfctemp->rst_sense);
2937f2958e8SEmil Renner Berthing 	if (ret)
2947f2958e8SEmil Renner Berthing 		return dev_err_probe(dev, ret, "error asserting sense reset\n");
2957f2958e8SEmil Renner Berthing 
2967f2958e8SEmil Renner Berthing 	ret = reset_control_assert(sfctemp->rst_bus);
2977f2958e8SEmil Renner Berthing 	if (ret)
2987f2958e8SEmil Renner Berthing 		return dev_err_probe(dev, ret, "error asserting bus reset\n");
2997f2958e8SEmil Renner Berthing 
3007f2958e8SEmil Renner Berthing 	ret = devm_add_action(dev, sfctemp_disable_action, sfctemp);
3017f2958e8SEmil Renner Berthing 	if (ret)
3027f2958e8SEmil Renner Berthing 		return ret;
3037f2958e8SEmil Renner Berthing 
3047f2958e8SEmil Renner Berthing 	ret = sfctemp_enable(sfctemp);
3057f2958e8SEmil Renner Berthing 	if (ret)
306*fb23f230SChristophe JAILLET 		return dev_err_probe(dev, ret, "error enabling temperature sensor\n");
3077f2958e8SEmil Renner Berthing 
3087f2958e8SEmil Renner Berthing 	hwmon_dev = devm_hwmon_device_register_with_info(dev, "sfctemp", sfctemp,
3097f2958e8SEmil Renner Berthing 							 &sfctemp_chip_info, NULL);
3107f2958e8SEmil Renner Berthing 	return PTR_ERR_OR_ZERO(hwmon_dev);
3117f2958e8SEmil Renner Berthing }
3127f2958e8SEmil Renner Berthing 
3137f2958e8SEmil Renner Berthing static const struct of_device_id sfctemp_of_match[] = {
3147f2958e8SEmil Renner Berthing 	{ .compatible = "starfive,jh7100-temp" },
3157f2958e8SEmil Renner Berthing 	{ .compatible = "starfive,jh7110-temp" },
3167f2958e8SEmil Renner Berthing 	{ /* sentinel */ }
3177f2958e8SEmil Renner Berthing };
3187f2958e8SEmil Renner Berthing MODULE_DEVICE_TABLE(of, sfctemp_of_match);
3197f2958e8SEmil Renner Berthing 
3207f2958e8SEmil Renner Berthing static struct platform_driver sfctemp_driver = {
3217f2958e8SEmil Renner Berthing 	.probe  = sfctemp_probe,
3227f2958e8SEmil Renner Berthing 	.driver = {
3237f2958e8SEmil Renner Berthing 		.name = "sfctemp",
3247f2958e8SEmil Renner Berthing 		.of_match_table = sfctemp_of_match,
3257f2958e8SEmil Renner Berthing 	},
3267f2958e8SEmil Renner Berthing };
3277f2958e8SEmil Renner Berthing module_platform_driver(sfctemp_driver);
3287f2958e8SEmil Renner Berthing 
3297f2958e8SEmil Renner Berthing MODULE_AUTHOR("Emil Renner Berthing");
3307f2958e8SEmil Renner Berthing MODULE_DESCRIPTION("StarFive JH71x0 temperature sensor driver");
3317f2958e8SEmil Renner Berthing MODULE_LICENSE("GPL");
332