xref: /openbmc/linux/drivers/hwmon/sfctemp.c (revision 7f2958e845d2c8bf1100dc088dbdc31af2a80fd0)
1*7f2958e8SEmil Renner Berthing // SPDX-License-Identifier: GPL-2.0
2*7f2958e8SEmil Renner Berthing /*
3*7f2958e8SEmil Renner Berthing  * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
4*7f2958e8SEmil Renner Berthing  * Copyright (C) 2021 Samin Guo <samin.guo@starfivetech.com>
5*7f2958e8SEmil Renner Berthing  */
6*7f2958e8SEmil Renner Berthing 
7*7f2958e8SEmil Renner Berthing #include <linux/bits.h>
8*7f2958e8SEmil Renner Berthing #include <linux/clk.h>
9*7f2958e8SEmil Renner Berthing #include <linux/delay.h>
10*7f2958e8SEmil Renner Berthing #include <linux/hwmon.h>
11*7f2958e8SEmil Renner Berthing #include <linux/io.h>
12*7f2958e8SEmil Renner Berthing #include <linux/module.h>
13*7f2958e8SEmil Renner Berthing #include <linux/mutex.h>
14*7f2958e8SEmil Renner Berthing #include <linux/of.h>
15*7f2958e8SEmil Renner Berthing #include <linux/platform_device.h>
16*7f2958e8SEmil Renner Berthing #include <linux/reset.h>
17*7f2958e8SEmil Renner Berthing 
18*7f2958e8SEmil Renner Berthing /*
19*7f2958e8SEmil Renner Berthing  * TempSensor reset. The RSTN can be de-asserted once the analog core has
20*7f2958e8SEmil Renner Berthing  * powered up. Trst(min 100ns)
21*7f2958e8SEmil Renner Berthing  * 0:reset  1:de-assert
22*7f2958e8SEmil Renner Berthing  */
23*7f2958e8SEmil Renner Berthing #define SFCTEMP_RSTN	BIT(0)
24*7f2958e8SEmil Renner Berthing 
25*7f2958e8SEmil Renner Berthing /*
26*7f2958e8SEmil Renner Berthing  * TempSensor analog core power down. The analog core will be powered up
27*7f2958e8SEmil Renner Berthing  * Tpu(min 50us) after PD is de-asserted. RSTN should be held low until the
28*7f2958e8SEmil Renner Berthing  * analog core is powered up.
29*7f2958e8SEmil Renner Berthing  * 0:power up  1:power down
30*7f2958e8SEmil Renner Berthing  */
31*7f2958e8SEmil Renner Berthing #define SFCTEMP_PD	BIT(1)
32*7f2958e8SEmil Renner Berthing 
33*7f2958e8SEmil Renner Berthing /*
34*7f2958e8SEmil Renner Berthing  * TempSensor start conversion enable.
35*7f2958e8SEmil Renner Berthing  * 0:disable  1:enable
36*7f2958e8SEmil Renner Berthing  */
37*7f2958e8SEmil Renner Berthing #define SFCTEMP_RUN	BIT(2)
38*7f2958e8SEmil Renner Berthing 
39*7f2958e8SEmil Renner Berthing /*
40*7f2958e8SEmil Renner Berthing  * TempSensor conversion value output.
41*7f2958e8SEmil Renner Berthing  * Temp(C)=DOUT*Y/4094 - K
42*7f2958e8SEmil Renner Berthing  */
43*7f2958e8SEmil Renner Berthing #define SFCTEMP_DOUT_POS	16
44*7f2958e8SEmil Renner Berthing #define SFCTEMP_DOUT_MSK	GENMASK(27, 16)
45*7f2958e8SEmil Renner Berthing 
46*7f2958e8SEmil Renner Berthing /* DOUT to Celcius conversion constants */
47*7f2958e8SEmil Renner Berthing #define SFCTEMP_Y1000	237500L
48*7f2958e8SEmil Renner Berthing #define SFCTEMP_Z	4094L
49*7f2958e8SEmil Renner Berthing #define SFCTEMP_K1000	81100L
50*7f2958e8SEmil Renner Berthing 
51*7f2958e8SEmil Renner Berthing struct sfctemp {
52*7f2958e8SEmil Renner Berthing 	/* serialize access to hardware register and enabled below */
53*7f2958e8SEmil Renner Berthing 	struct mutex lock;
54*7f2958e8SEmil Renner Berthing 	void __iomem *regs;
55*7f2958e8SEmil Renner Berthing 	struct clk *clk_sense;
56*7f2958e8SEmil Renner Berthing 	struct clk *clk_bus;
57*7f2958e8SEmil Renner Berthing 	struct reset_control *rst_sense;
58*7f2958e8SEmil Renner Berthing 	struct reset_control *rst_bus;
59*7f2958e8SEmil Renner Berthing 	bool enabled;
60*7f2958e8SEmil Renner Berthing };
61*7f2958e8SEmil Renner Berthing 
62*7f2958e8SEmil Renner Berthing static void sfctemp_power_up(struct sfctemp *sfctemp)
63*7f2958e8SEmil Renner Berthing {
64*7f2958e8SEmil Renner Berthing 	/* make sure we're powered down first */
65*7f2958e8SEmil Renner Berthing 	writel(SFCTEMP_PD, sfctemp->regs);
66*7f2958e8SEmil Renner Berthing 	udelay(1);
67*7f2958e8SEmil Renner Berthing 
68*7f2958e8SEmil Renner Berthing 	writel(0, sfctemp->regs);
69*7f2958e8SEmil Renner Berthing 	/* wait t_pu(50us) + t_rst(100ns) */
70*7f2958e8SEmil Renner Berthing 	usleep_range(60, 200);
71*7f2958e8SEmil Renner Berthing 
72*7f2958e8SEmil Renner Berthing 	/* de-assert reset */
73*7f2958e8SEmil Renner Berthing 	writel(SFCTEMP_RSTN, sfctemp->regs);
74*7f2958e8SEmil Renner Berthing 	udelay(1); /* wait t_su(500ps) */
75*7f2958e8SEmil Renner Berthing }
76*7f2958e8SEmil Renner Berthing 
77*7f2958e8SEmil Renner Berthing static void sfctemp_power_down(struct sfctemp *sfctemp)
78*7f2958e8SEmil Renner Berthing {
79*7f2958e8SEmil Renner Berthing 	writel(SFCTEMP_PD, sfctemp->regs);
80*7f2958e8SEmil Renner Berthing }
81*7f2958e8SEmil Renner Berthing 
82*7f2958e8SEmil Renner Berthing static void sfctemp_run(struct sfctemp *sfctemp)
83*7f2958e8SEmil Renner Berthing {
84*7f2958e8SEmil Renner Berthing 	writel(SFCTEMP_RSTN | SFCTEMP_RUN, sfctemp->regs);
85*7f2958e8SEmil Renner Berthing 	udelay(1);
86*7f2958e8SEmil Renner Berthing }
87*7f2958e8SEmil Renner Berthing 
88*7f2958e8SEmil Renner Berthing static void sfctemp_stop(struct sfctemp *sfctemp)
89*7f2958e8SEmil Renner Berthing {
90*7f2958e8SEmil Renner Berthing 	writel(SFCTEMP_RSTN, sfctemp->regs);
91*7f2958e8SEmil Renner Berthing }
92*7f2958e8SEmil Renner Berthing 
93*7f2958e8SEmil Renner Berthing static int sfctemp_enable(struct sfctemp *sfctemp)
94*7f2958e8SEmil Renner Berthing {
95*7f2958e8SEmil Renner Berthing 	int ret = 0;
96*7f2958e8SEmil Renner Berthing 
97*7f2958e8SEmil Renner Berthing 	mutex_lock(&sfctemp->lock);
98*7f2958e8SEmil Renner Berthing 	if (sfctemp->enabled)
99*7f2958e8SEmil Renner Berthing 		goto done;
100*7f2958e8SEmil Renner Berthing 
101*7f2958e8SEmil Renner Berthing 	ret = clk_prepare_enable(sfctemp->clk_bus);
102*7f2958e8SEmil Renner Berthing 	if (ret)
103*7f2958e8SEmil Renner Berthing 		goto err;
104*7f2958e8SEmil Renner Berthing 	ret = reset_control_deassert(sfctemp->rst_bus);
105*7f2958e8SEmil Renner Berthing 	if (ret)
106*7f2958e8SEmil Renner Berthing 		goto err_disable_bus;
107*7f2958e8SEmil Renner Berthing 
108*7f2958e8SEmil Renner Berthing 	ret = clk_prepare_enable(sfctemp->clk_sense);
109*7f2958e8SEmil Renner Berthing 	if (ret)
110*7f2958e8SEmil Renner Berthing 		goto err_assert_bus;
111*7f2958e8SEmil Renner Berthing 	ret = reset_control_deassert(sfctemp->rst_sense);
112*7f2958e8SEmil Renner Berthing 	if (ret)
113*7f2958e8SEmil Renner Berthing 		goto err_disable_sense;
114*7f2958e8SEmil Renner Berthing 
115*7f2958e8SEmil Renner Berthing 	sfctemp_power_up(sfctemp);
116*7f2958e8SEmil Renner Berthing 	sfctemp_run(sfctemp);
117*7f2958e8SEmil Renner Berthing 	sfctemp->enabled = true;
118*7f2958e8SEmil Renner Berthing done:
119*7f2958e8SEmil Renner Berthing 	mutex_unlock(&sfctemp->lock);
120*7f2958e8SEmil Renner Berthing 	return ret;
121*7f2958e8SEmil Renner Berthing 
122*7f2958e8SEmil Renner Berthing err_disable_sense:
123*7f2958e8SEmil Renner Berthing 	clk_disable_unprepare(sfctemp->clk_sense);
124*7f2958e8SEmil Renner Berthing err_assert_bus:
125*7f2958e8SEmil Renner Berthing 	reset_control_assert(sfctemp->rst_bus);
126*7f2958e8SEmil Renner Berthing err_disable_bus:
127*7f2958e8SEmil Renner Berthing 	clk_disable_unprepare(sfctemp->clk_bus);
128*7f2958e8SEmil Renner Berthing err:
129*7f2958e8SEmil Renner Berthing 	mutex_unlock(&sfctemp->lock);
130*7f2958e8SEmil Renner Berthing 	return ret;
131*7f2958e8SEmil Renner Berthing }
132*7f2958e8SEmil Renner Berthing 
133*7f2958e8SEmil Renner Berthing static int sfctemp_disable(struct sfctemp *sfctemp)
134*7f2958e8SEmil Renner Berthing {
135*7f2958e8SEmil Renner Berthing 	mutex_lock(&sfctemp->lock);
136*7f2958e8SEmil Renner Berthing 	if (!sfctemp->enabled)
137*7f2958e8SEmil Renner Berthing 		goto done;
138*7f2958e8SEmil Renner Berthing 
139*7f2958e8SEmil Renner Berthing 	sfctemp_stop(sfctemp);
140*7f2958e8SEmil Renner Berthing 	sfctemp_power_down(sfctemp);
141*7f2958e8SEmil Renner Berthing 	reset_control_assert(sfctemp->rst_sense);
142*7f2958e8SEmil Renner Berthing 	clk_disable_unprepare(sfctemp->clk_sense);
143*7f2958e8SEmil Renner Berthing 	reset_control_assert(sfctemp->rst_bus);
144*7f2958e8SEmil Renner Berthing 	clk_disable_unprepare(sfctemp->clk_bus);
145*7f2958e8SEmil Renner Berthing 	sfctemp->enabled = false;
146*7f2958e8SEmil Renner Berthing done:
147*7f2958e8SEmil Renner Berthing 	mutex_unlock(&sfctemp->lock);
148*7f2958e8SEmil Renner Berthing 	return 0;
149*7f2958e8SEmil Renner Berthing }
150*7f2958e8SEmil Renner Berthing 
151*7f2958e8SEmil Renner Berthing static void sfctemp_disable_action(void *data)
152*7f2958e8SEmil Renner Berthing {
153*7f2958e8SEmil Renner Berthing 	sfctemp_disable(data);
154*7f2958e8SEmil Renner Berthing }
155*7f2958e8SEmil Renner Berthing 
156*7f2958e8SEmil Renner Berthing static int sfctemp_convert(struct sfctemp *sfctemp, long *val)
157*7f2958e8SEmil Renner Berthing {
158*7f2958e8SEmil Renner Berthing 	int ret;
159*7f2958e8SEmil Renner Berthing 
160*7f2958e8SEmil Renner Berthing 	mutex_lock(&sfctemp->lock);
161*7f2958e8SEmil Renner Berthing 	if (!sfctemp->enabled) {
162*7f2958e8SEmil Renner Berthing 		ret = -ENODATA;
163*7f2958e8SEmil Renner Berthing 		goto out;
164*7f2958e8SEmil Renner Berthing 	}
165*7f2958e8SEmil Renner Berthing 
166*7f2958e8SEmil Renner Berthing 	/* calculate temperature in milli Celcius */
167*7f2958e8SEmil Renner Berthing 	*val = (long)((readl(sfctemp->regs) & SFCTEMP_DOUT_MSK) >> SFCTEMP_DOUT_POS)
168*7f2958e8SEmil Renner Berthing 		* SFCTEMP_Y1000 / SFCTEMP_Z - SFCTEMP_K1000;
169*7f2958e8SEmil Renner Berthing 
170*7f2958e8SEmil Renner Berthing 	ret = 0;
171*7f2958e8SEmil Renner Berthing out:
172*7f2958e8SEmil Renner Berthing 	mutex_unlock(&sfctemp->lock);
173*7f2958e8SEmil Renner Berthing 	return ret;
174*7f2958e8SEmil Renner Berthing }
175*7f2958e8SEmil Renner Berthing 
176*7f2958e8SEmil Renner Berthing static umode_t sfctemp_is_visible(const void *data, enum hwmon_sensor_types type,
177*7f2958e8SEmil Renner Berthing 				  u32 attr, int channel)
178*7f2958e8SEmil Renner Berthing {
179*7f2958e8SEmil Renner Berthing 	switch (type) {
180*7f2958e8SEmil Renner Berthing 	case hwmon_temp:
181*7f2958e8SEmil Renner Berthing 		switch (attr) {
182*7f2958e8SEmil Renner Berthing 		case hwmon_temp_enable:
183*7f2958e8SEmil Renner Berthing 			return 0644;
184*7f2958e8SEmil Renner Berthing 		case hwmon_temp_input:
185*7f2958e8SEmil Renner Berthing 			return 0444;
186*7f2958e8SEmil Renner Berthing 		default:
187*7f2958e8SEmil Renner Berthing 			return 0;
188*7f2958e8SEmil Renner Berthing 		}
189*7f2958e8SEmil Renner Berthing 	default:
190*7f2958e8SEmil Renner Berthing 		return 0;
191*7f2958e8SEmil Renner Berthing 	}
192*7f2958e8SEmil Renner Berthing }
193*7f2958e8SEmil Renner Berthing 
194*7f2958e8SEmil Renner Berthing static int sfctemp_read(struct device *dev, enum hwmon_sensor_types type,
195*7f2958e8SEmil Renner Berthing 			u32 attr, int channel, long *val)
196*7f2958e8SEmil Renner Berthing {
197*7f2958e8SEmil Renner Berthing 	struct sfctemp *sfctemp = dev_get_drvdata(dev);
198*7f2958e8SEmil Renner Berthing 
199*7f2958e8SEmil Renner Berthing 	switch (type) {
200*7f2958e8SEmil Renner Berthing 	case hwmon_temp:
201*7f2958e8SEmil Renner Berthing 		switch (attr) {
202*7f2958e8SEmil Renner Berthing 		case hwmon_temp_enable:
203*7f2958e8SEmil Renner Berthing 			*val = sfctemp->enabled;
204*7f2958e8SEmil Renner Berthing 			return 0;
205*7f2958e8SEmil Renner Berthing 		case hwmon_temp_input:
206*7f2958e8SEmil Renner Berthing 			return sfctemp_convert(sfctemp, val);
207*7f2958e8SEmil Renner Berthing 		default:
208*7f2958e8SEmil Renner Berthing 			return -EINVAL;
209*7f2958e8SEmil Renner Berthing 		}
210*7f2958e8SEmil Renner Berthing 	default:
211*7f2958e8SEmil Renner Berthing 		return -EINVAL;
212*7f2958e8SEmil Renner Berthing 	}
213*7f2958e8SEmil Renner Berthing }
214*7f2958e8SEmil Renner Berthing 
215*7f2958e8SEmil Renner Berthing static int sfctemp_write(struct device *dev, enum hwmon_sensor_types type,
216*7f2958e8SEmil Renner Berthing 			 u32 attr, int channel, long val)
217*7f2958e8SEmil Renner Berthing {
218*7f2958e8SEmil Renner Berthing 	struct sfctemp *sfctemp = dev_get_drvdata(dev);
219*7f2958e8SEmil Renner Berthing 
220*7f2958e8SEmil Renner Berthing 	switch (type) {
221*7f2958e8SEmil Renner Berthing 	case hwmon_temp:
222*7f2958e8SEmil Renner Berthing 		switch (attr) {
223*7f2958e8SEmil Renner Berthing 		case hwmon_temp_enable:
224*7f2958e8SEmil Renner Berthing 			if (val == 0)
225*7f2958e8SEmil Renner Berthing 				return sfctemp_disable(sfctemp);
226*7f2958e8SEmil Renner Berthing 			if (val == 1)
227*7f2958e8SEmil Renner Berthing 				return sfctemp_enable(sfctemp);
228*7f2958e8SEmil Renner Berthing 			return -EINVAL;
229*7f2958e8SEmil Renner Berthing 		default:
230*7f2958e8SEmil Renner Berthing 			return -EINVAL;
231*7f2958e8SEmil Renner Berthing 		}
232*7f2958e8SEmil Renner Berthing 	default:
233*7f2958e8SEmil Renner Berthing 		return -EINVAL;
234*7f2958e8SEmil Renner Berthing 	}
235*7f2958e8SEmil Renner Berthing }
236*7f2958e8SEmil Renner Berthing 
237*7f2958e8SEmil Renner Berthing static const struct hwmon_channel_info *sfctemp_info[] = {
238*7f2958e8SEmil Renner Berthing 	HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
239*7f2958e8SEmil Renner Berthing 	HWMON_CHANNEL_INFO(temp, HWMON_T_ENABLE | HWMON_T_INPUT),
240*7f2958e8SEmil Renner Berthing 	NULL
241*7f2958e8SEmil Renner Berthing };
242*7f2958e8SEmil Renner Berthing 
243*7f2958e8SEmil Renner Berthing static const struct hwmon_ops sfctemp_hwmon_ops = {
244*7f2958e8SEmil Renner Berthing 	.is_visible = sfctemp_is_visible,
245*7f2958e8SEmil Renner Berthing 	.read = sfctemp_read,
246*7f2958e8SEmil Renner Berthing 	.write = sfctemp_write,
247*7f2958e8SEmil Renner Berthing };
248*7f2958e8SEmil Renner Berthing 
249*7f2958e8SEmil Renner Berthing static const struct hwmon_chip_info sfctemp_chip_info = {
250*7f2958e8SEmil Renner Berthing 	.ops = &sfctemp_hwmon_ops,
251*7f2958e8SEmil Renner Berthing 	.info = sfctemp_info,
252*7f2958e8SEmil Renner Berthing };
253*7f2958e8SEmil Renner Berthing 
254*7f2958e8SEmil Renner Berthing static int sfctemp_probe(struct platform_device *pdev)
255*7f2958e8SEmil Renner Berthing {
256*7f2958e8SEmil Renner Berthing 	struct device *dev = &pdev->dev;
257*7f2958e8SEmil Renner Berthing 	struct device *hwmon_dev;
258*7f2958e8SEmil Renner Berthing 	struct sfctemp *sfctemp;
259*7f2958e8SEmil Renner Berthing 	int ret;
260*7f2958e8SEmil Renner Berthing 
261*7f2958e8SEmil Renner Berthing 	sfctemp = devm_kzalloc(dev, sizeof(*sfctemp), GFP_KERNEL);
262*7f2958e8SEmil Renner Berthing 	if (!sfctemp)
263*7f2958e8SEmil Renner Berthing 		return -ENOMEM;
264*7f2958e8SEmil Renner Berthing 
265*7f2958e8SEmil Renner Berthing 	dev_set_drvdata(dev, sfctemp);
266*7f2958e8SEmil Renner Berthing 	mutex_init(&sfctemp->lock);
267*7f2958e8SEmil Renner Berthing 
268*7f2958e8SEmil Renner Berthing 	sfctemp->regs = devm_platform_ioremap_resource(pdev, 0);
269*7f2958e8SEmil Renner Berthing 	if (IS_ERR(sfctemp->regs))
270*7f2958e8SEmil Renner Berthing 		return PTR_ERR(sfctemp->regs);
271*7f2958e8SEmil Renner Berthing 
272*7f2958e8SEmil Renner Berthing 	sfctemp->clk_sense = devm_clk_get(dev, "sense");
273*7f2958e8SEmil Renner Berthing 	if (IS_ERR(sfctemp->clk_sense))
274*7f2958e8SEmil Renner Berthing 		return dev_err_probe(dev, PTR_ERR(sfctemp->clk_sense),
275*7f2958e8SEmil Renner Berthing 				     "error getting sense clock\n");
276*7f2958e8SEmil Renner Berthing 
277*7f2958e8SEmil Renner Berthing 	sfctemp->clk_bus = devm_clk_get(dev, "bus");
278*7f2958e8SEmil Renner Berthing 	if (IS_ERR(sfctemp->clk_bus))
279*7f2958e8SEmil Renner Berthing 		return dev_err_probe(dev, PTR_ERR(sfctemp->clk_bus),
280*7f2958e8SEmil Renner Berthing 				     "error getting bus clock\n");
281*7f2958e8SEmil Renner Berthing 
282*7f2958e8SEmil Renner Berthing 	sfctemp->rst_sense = devm_reset_control_get_exclusive(dev, "sense");
283*7f2958e8SEmil Renner Berthing 	if (IS_ERR(sfctemp->rst_sense))
284*7f2958e8SEmil Renner Berthing 		return dev_err_probe(dev, PTR_ERR(sfctemp->rst_sense),
285*7f2958e8SEmil Renner Berthing 				     "error getting sense reset\n");
286*7f2958e8SEmil Renner Berthing 
287*7f2958e8SEmil Renner Berthing 	sfctemp->rst_bus = devm_reset_control_get_exclusive(dev, "bus");
288*7f2958e8SEmil Renner Berthing 	if (IS_ERR(sfctemp->rst_bus))
289*7f2958e8SEmil Renner Berthing 		return dev_err_probe(dev, PTR_ERR(sfctemp->rst_bus),
290*7f2958e8SEmil Renner Berthing 				     "error getting busreset\n");
291*7f2958e8SEmil Renner Berthing 
292*7f2958e8SEmil Renner Berthing 	ret = reset_control_assert(sfctemp->rst_sense);
293*7f2958e8SEmil Renner Berthing 	if (ret)
294*7f2958e8SEmil Renner Berthing 		return dev_err_probe(dev, ret, "error asserting sense reset\n");
295*7f2958e8SEmil Renner Berthing 
296*7f2958e8SEmil Renner Berthing 	ret = reset_control_assert(sfctemp->rst_bus);
297*7f2958e8SEmil Renner Berthing 	if (ret)
298*7f2958e8SEmil Renner Berthing 		return dev_err_probe(dev, ret, "error asserting bus reset\n");
299*7f2958e8SEmil Renner Berthing 
300*7f2958e8SEmil Renner Berthing 	ret = devm_add_action(dev, sfctemp_disable_action, sfctemp);
301*7f2958e8SEmil Renner Berthing 	if (ret)
302*7f2958e8SEmil Renner Berthing 		return ret;
303*7f2958e8SEmil Renner Berthing 
304*7f2958e8SEmil Renner Berthing 	ret = sfctemp_enable(sfctemp);
305*7f2958e8SEmil Renner Berthing 	if (ret)
306*7f2958e8SEmil Renner Berthing 		return dev_err_probe(dev, ret, "error enabling temperature sensor: %d\n", ret);
307*7f2958e8SEmil Renner Berthing 
308*7f2958e8SEmil Renner Berthing 	hwmon_dev = devm_hwmon_device_register_with_info(dev, "sfctemp", sfctemp,
309*7f2958e8SEmil Renner Berthing 							 &sfctemp_chip_info, NULL);
310*7f2958e8SEmil Renner Berthing 	return PTR_ERR_OR_ZERO(hwmon_dev);
311*7f2958e8SEmil Renner Berthing }
312*7f2958e8SEmil Renner Berthing 
313*7f2958e8SEmil Renner Berthing static const struct of_device_id sfctemp_of_match[] = {
314*7f2958e8SEmil Renner Berthing 	{ .compatible = "starfive,jh7100-temp" },
315*7f2958e8SEmil Renner Berthing 	{ .compatible = "starfive,jh7110-temp" },
316*7f2958e8SEmil Renner Berthing 	{ /* sentinel */ }
317*7f2958e8SEmil Renner Berthing };
318*7f2958e8SEmil Renner Berthing MODULE_DEVICE_TABLE(of, sfctemp_of_match);
319*7f2958e8SEmil Renner Berthing 
320*7f2958e8SEmil Renner Berthing static struct platform_driver sfctemp_driver = {
321*7f2958e8SEmil Renner Berthing 	.probe  = sfctemp_probe,
322*7f2958e8SEmil Renner Berthing 	.driver = {
323*7f2958e8SEmil Renner Berthing 		.name = "sfctemp",
324*7f2958e8SEmil Renner Berthing 		.of_match_table = sfctemp_of_match,
325*7f2958e8SEmil Renner Berthing 	},
326*7f2958e8SEmil Renner Berthing };
327*7f2958e8SEmil Renner Berthing module_platform_driver(sfctemp_driver);
328*7f2958e8SEmil Renner Berthing 
329*7f2958e8SEmil Renner Berthing MODULE_AUTHOR("Emil Renner Berthing");
330*7f2958e8SEmil Renner Berthing MODULE_DESCRIPTION("StarFive JH71x0 temperature sensor driver");
331*7f2958e8SEmil Renner Berthing MODULE_LICENSE("GPL");
332