Module Name:    src
Committed By:   mrg
Date:           Tue May 14 07:45:03 UTC 2019

Modified Files:
        src/sys/arch/arm/rockchip: rk_tsadc.c

Log Message:
mostly port to rk3328.

- add rk3328 data<->temp table, and adjust code to use this vs rk3399
  table for rk3328.  add support for decrementing data.
- adjust auto period times for rk3328 vs rk3399
- add min/max data values, if data is outside these values mark the
  sensor invalid.
- move init code into cpu specific sections, add rk3328 support

with a rk3328_cru.c update to add clocks, this attaches and reports
garbage values, so for now it's disabled.


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/rockchip/rk_tsadc.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/rockchip/rk_tsadc.c
diff -u src/sys/arch/arm/rockchip/rk_tsadc.c:1.3 src/sys/arch/arm/rockchip/rk_tsadc.c:1.4
--- src/sys/arch/arm/rockchip/rk_tsadc.c:1.3	Fri Apr 26 10:27:49 2019
+++ src/sys/arch/arm/rockchip/rk_tsadc.c	Tue May 14 07:45:03 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: rk_tsadc.c,v 1.3 2019/04/26 10:27:49 mrg Exp $	*/
+/*	$NetBSD: rk_tsadc.c,v 1.4 2019/05/14 07:45:03 mrg Exp $	*/
 
 /*
  * Copyright (c) 2019 Matthew R. Green
@@ -30,7 +30,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(0, "$NetBSD: rk_tsadc.c,v 1.3 2019/04/26 10:27:49 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rk_tsadc.c,v 1.4 2019/05/14 07:45:03 mrg Exp $");
 
 /*
  * Driver for the TSADC temperature sensor monitor in RK3328 and RK3399.
@@ -40,7 +40,7 @@ __KERNEL_RCSID(0, "$NetBSD: rk_tsadc.c,v
  * - handle DT trips/temp value defaults
  * - interrupts aren't triggered (test by lowering warn/crit values), and
  *   once they work, make the interrupt do something
- * - test on RK3328, and port to other rockchips (will require moving some
+ * - fix for RK3328, and port to other rockchips (will require moving some
  *   part into per-chipset sections, such as code<->temp tables)
  */
 
@@ -128,7 +128,8 @@ __KERNEL_RCSID(0, "$NetBSD: rk_tsadc.c,v
 #define TSADC_COMP1_LOW_INT                     0x84
 #define  TSADC_COMP1_LOW_INT_COMP_SRC1          __BITS(11,0)
 
-#define TSADC_AUTO_PERIOD_TIME                  1875 /* 2.5ms */
+#define RK3328_TSADC_AUTO_PERIOD_TIME           250 /* 250ms */
+#define RK3399_TSADC_AUTO_PERIOD_TIME           1875 /* 2.5ms */
 #define TSADC_HT_DEBOUNCE_COUNT                 4
 
 /*
@@ -160,50 +161,20 @@ __KERNEL_RCSID(0, "$NetBSD: rk_tsadc.c,v
 
 #define NUM_SENSORS       2
 
-/* Table from RK3399 manual */
-static const struct {
+typedef struct rk_data_array {
 	uint32_t data;  /* register value */
 	int temp;       /* micro-degC */
-} rk3399_data_table[] = {
-#define ENTRY(d,C)	{ .data = (d), .temp = (C) * 1000 * 1000, }
-	ENTRY(0,   -40),
-	ENTRY(402, -40),
-	ENTRY(410, -35),
-	ENTRY(419, -30),
-	ENTRY(427, -25),
-	ENTRY(436, -20),
-	ENTRY(444, -15),
-	ENTRY(453, -10),
-	ENTRY(461,  -5),
-	ENTRY(470,   0),
-	ENTRY(478,   5),
-	ENTRY(487,  10),
-	ENTRY(496,  15),
-	ENTRY(504,  20),
-	ENTRY(513,  25),
-	ENTRY(521,  30),
-	ENTRY(530,  35),
-	ENTRY(538,  40),
-	ENTRY(547,  45),
-	ENTRY(555,  50),
-	ENTRY(564,  55),
-	ENTRY(573,  60),
-	ENTRY(581,  65),
-	ENTRY(590,  70),
-	ENTRY(599,  75),
-	ENTRY(607,  80),
-	ENTRY(616,  85),
-	ENTRY(624,  90),
-	ENTRY(633,  95),
-	ENTRY(642, 100),
-	ENTRY(650, 105),
-	ENTRY(659, 110),
-	ENTRY(668, 115),
-	ENTRY(677, 120),
-	ENTRY(685, 125),
-	ENTRY(TSADC_DATA_MAX, 125),
-#undef ENTRY
-};
+} rk_data_array;
+
+struct rk_tsadc_softc;
+typedef struct rk_data_table {
+	const rk_data_array	*rdt_array;
+	size_t			 rdt_size;
+	void			(*rdt_init)(struct rk_tsadc_softc *, int, int);
+	bool			 rdt_decr;  /* lower values -> higher temp */
+	unsigned		 rdt_min, rdt_max;
+	unsigned		 rdt_auto_period;
+} rk_data_table;
 
 /* Per-sensor data */
 struct rk_tsadc_sensor {
@@ -236,6 +207,8 @@ struct rk_tsadc_softc {
 	struct clk		*sc_clockapb;
 	struct fdtbus_reset	*sc_reset;
 	struct syscon		*sc_syscon;
+
+	const rk_data_table	*sc_rdt;
 };
 
 static int rk_tsadc_match(device_t, cfdata_t, void *);
@@ -245,8 +218,10 @@ static int rk_tsadc_init_clocks(struct r
 static void rk_tsadc_init_counts(struct rk_tsadc_softc *);
 static void rk_tsadc_tshut_set(struct rk_tsadc_softc *s);
 static void rk_tsadc_init_tshut(struct rk_tsadc_softc *, int, int);
-static void rk_tsadc_init_grf(struct rk_tsadc_softc *);
+static void rk_tsadc_init_rk3328(struct rk_tsadc_softc *, int, int);
+static void rk_tsadc_init_rk3399(struct rk_tsadc_softc *, int, int);
 static void rk_tsadc_init_enable(struct rk_tsadc_softc *);
+static void rk_tsadc_init(struct rk_tsadc_softc *, int, int);
 static void rk_tsadc_refresh(struct sysmon_envsys *, envsys_data_t *);
 static void rk_tsadc_get_limits(struct sysmon_envsys *, envsys_data_t *,
                                 sysmon_envsys_lim_t *, uint32_t *);
@@ -289,8 +264,122 @@ static const struct rk_tsadc_sensor rk_t
 	},
 };
 
-static const char * const compatible[] = {
+/* Table from RK3328 manual */
+static const rk_data_array rk3328_data_array[] = {
+#define ENTRY(d,C)	{ .data = (d), .temp = (C) * 1000 * 1000, }
+	ENTRY(TSADC_DATA_MAX,    -40),
+	ENTRY(3800, -40),
+	ENTRY(3792, -35),
+	ENTRY(3783, -30),
+	ENTRY(3774, -25),
+	ENTRY(3765, -20),
+	ENTRY(3756, -15),
+	ENTRY(3747, -10),
+	ENTRY(3737,  -5),
+	ENTRY(3728,   0),
+	ENTRY(3718,   5),
+	ENTRY(3708,  10),
+	ENTRY(3698,  15),
+	ENTRY(3688,  20),
+	ENTRY(3678,  25),
+	ENTRY(3667,  30),
+	ENTRY(3656,  35),
+	ENTRY(3645,  40),
+	ENTRY(3634,  45),
+	ENTRY(3623,  50),
+	ENTRY(3611,  55),
+	ENTRY(3600,  60),
+	ENTRY(3588,  65),
+	ENTRY(3575,  70),
+	ENTRY(3563,  75),
+	ENTRY(3550,  80),
+	ENTRY(3537,  85),
+	ENTRY(3524,  90),
+	ENTRY(3510,  95),
+	ENTRY(3496, 100),
+	ENTRY(3482, 105),
+	ENTRY(3467, 110),
+	ENTRY(3452, 115),
+	ENTRY(3437, 120),
+	ENTRY(3421, 125),
+	ENTRY(0,    125),
+#undef ENTRY
+};
+
+/* Table from RK3399 manual */
+static const rk_data_array rk3399_data_array[] = {
+#define ENTRY(d,C)	{ .data = (d), .temp = (C) * 1000 * 1000, }
+	ENTRY(0,   -40),
+	ENTRY(402, -40),
+	ENTRY(410, -35),
+	ENTRY(419, -30),
+	ENTRY(427, -25),
+	ENTRY(436, -20),
+	ENTRY(444, -15),
+	ENTRY(453, -10),
+	ENTRY(461,  -5),
+	ENTRY(470,   0),
+	ENTRY(478,   5),
+	ENTRY(487,  10),
+	ENTRY(496,  15),
+	ENTRY(504,  20),
+	ENTRY(513,  25),
+	ENTRY(521,  30),
+	ENTRY(530,  35),
+	ENTRY(538,  40),
+	ENTRY(547,  45),
+	ENTRY(555,  50),
+	ENTRY(564,  55),
+	ENTRY(573,  60),
+	ENTRY(581,  65),
+	ENTRY(590,  70),
+	ENTRY(599,  75),
+	ENTRY(607,  80),
+	ENTRY(616,  85),
+	ENTRY(624,  90),
+	ENTRY(633,  95),
+	ENTRY(642, 100),
+	ENTRY(650, 105),
+	ENTRY(659, 110),
+	ENTRY(668, 115),
+	ENTRY(677, 120),
+	ENTRY(685, 125),
+	ENTRY(TSADC_DATA_MAX, 125),
+#undef ENTRY
+};
+
+static const rk_data_table rk3328_data_table = {
+	.rdt_array = rk3328_data_array,
+	.rdt_size = __arraycount(rk3328_data_array),
+	.rdt_init = rk_tsadc_init_rk3328,
+	.rdt_decr = true,
+	.rdt_max = 3801,
+	.rdt_min = 3420,
+	.rdt_auto_period = RK3328_TSADC_AUTO_PERIOD_TIME,
+};
+
+static const rk_data_table rk3399_data_table = {
+	.rdt_array = rk3399_data_array,
+	.rdt_size = __arraycount(rk3399_data_array),
+	.rdt_init = rk_tsadc_init_rk3399,
+	.rdt_decr = false,
+	.rdt_max = 686,
+	.rdt_min = 401,
+	.rdt_auto_period = RK3399_TSADC_AUTO_PERIOD_TIME,
+};
+
+static const char * const compatible_rk3328[] = {
+#if 0
+	/*
+	 * does not yet report sane values.  should be between 3421 and 3800,
+	 * but CPU tends to report < 1000 and the GPU reports 600-1600.
+	 */
 	"rockchip,rk3328-tsadc",
+#endif
+	NULL
+};
+
+static const char * const compatible_rk3399[] = {
 	"rockchip,rk3399-tsadc",
 	NULL
 };
@@ -310,7 +399,8 @@ rk_tsadc_match(device_t parent, cfdata_t
 {
 	struct fdt_attach_args * const faa = aux;
 
-	return of_match_compatible(faa->faa_phandle, compatible);
+	return of_match_compatible(faa->faa_phandle, compatible_rk3328) ||
+	       of_match_compatible(faa->faa_phandle, compatible_rk3399);
 }
 
 static void
@@ -418,16 +508,20 @@ rk_tsadc_attach(device_t parent, device_
 		return;
 	}
 
+	if (of_match_compatible(faa->faa_phandle, compatible_rk3328)) {
+		sc->sc_rdt = &rk3328_data_table;
+	} else {
+		KASSERT(of_match_compatible(faa->faa_phandle, compatible_rk3399));
+		sc->sc_rdt = &rk3399_data_table;
+	}
+
 	/*
 	 * Manual says to setup auto period (both), high temp (interrupt),
 	 * high temp (shutdown), enable high temp resets (TSHUT to GPIO
 	 * or reset chip), set the debounce times, and, finally, enable the
 	 * controller iself.
 	 */
-	rk_tsadc_init_counts(sc);
-	rk_tsadc_init_tshut(sc, mode, polarity);
-	rk_tsadc_init_grf(sc);
-	rk_tsadc_init_enable(sc);
+	rk_tsadc_init(sc, mode, polarity);
 
 	return;
 
@@ -504,8 +598,8 @@ static void
 rk_tsadc_init_counts(struct rk_tsadc_softc *sc)
 {
 
-	TSADC_WRITE(sc, TSADC_AUTO_PERIOD, TSADC_AUTO_PERIOD_TIME);
-	TSADC_WRITE(sc, TSADC_AUTO_PERIOD_HT, TSADC_AUTO_PERIOD_TIME);
+	TSADC_WRITE(sc, TSADC_AUTO_PERIOD, sc->sc_rdt->rdt_auto_period);
+	TSADC_WRITE(sc, TSADC_AUTO_PERIOD_HT, sc->sc_rdt->rdt_auto_period);
 	TSADC_WRITE(sc, TSADC_HIGH_INT_DEBOUNCE, TSADC_HT_DEBOUNCE_COUNT);
 	TSADC_WRITE(sc, TSADC_HIGH_TSHUT_DEBOUNCE, TSADC_HT_DEBOUNCE_COUNT);
 }
@@ -581,7 +675,15 @@ rk_tsadc_init_tshut(struct rk_tsadc_soft
 }
 
 static void
-rk_tsadc_init_grf(struct rk_tsadc_softc *sc)
+rk_tsadc_init_rk3328(struct rk_tsadc_softc *sc, int mode, int polarity)
+{
+
+	rk_tsadc_init_tshut(sc, mode, polarity);
+	rk_tsadc_init_counts(sc);
+}
+
+static void
+rk_tsadc_init_rk3399(struct rk_tsadc_softc *sc, int mode, int polarity)
 {
 
 	syscon_lock(sc->sc_syscon);
@@ -597,6 +699,9 @@ rk_tsadc_init_grf(struct rk_tsadc_softc 
 				      RK3399_GRF_TSADC_TESTBIT_H_ON);
 	DELAY(100);
 	syscon_unlock(sc->sc_syscon);
+
+	rk_tsadc_init_counts(sc);
+	rk_tsadc_init_tshut(sc, mode, polarity);
 }
 
 static void
@@ -617,11 +722,20 @@ rk_tsadc_init_enable(struct rk_tsadc_sof
 	TSADC_WRITE(sc, TSADC_AUTO_CON, val);
 }
 
+static void
+rk_tsadc_init(struct rk_tsadc_softc *sc, int mode, int polarity)
+{
+
+	(*sc->sc_rdt->rdt_init)(sc, mode, polarity);
+	rk_tsadc_init_enable(sc);
+}
+
 /* run time support */
 
 static struct rk_tsadc_sensor *
 rk_tsadc_edata_to_sensor(struct rk_tsadc_softc * const sc, envsys_data_t *edata)
 {
+
 	for (unsigned n = 0; n < NUM_SENSORS; n++) {
 		struct rk_tsadc_sensor *rks = &sc->sc_sensors[n];
 
@@ -645,6 +759,10 @@ rk_tsadc_refresh(struct sysmon_envsys *s
 	data = TSADC_READ(sc, rks->s_data_reg) & sc->sc_data_mask;
 	temp = rk_tsadc_data_to_temp(sc, data);
 
+	DPRINTF("(%s:%s): temp/data %d/%u",
+		sc->sc_sme->sme_name, rks->s_data.desc,
+		temp, data);
+
 	if (temp == sc->sc_data_mask) {
 		edata->state = ENVSYS_SINVALID;
 	} else {
@@ -703,52 +821,75 @@ static int
 rk_tsadc_data_to_temp(struct rk_tsadc_softc *sc, uint32_t data)
 {
 	unsigned i;
+	const rk_data_table *rdt = sc->sc_rdt;
 
-	for (i = 1; i < __arraycount(rk3399_data_table) - 1; i++) {
-		if (rk3399_data_table[i].data >= data) {
+	if (data > rdt->rdt_max || data < rdt->rdt_min) {
+		DPRINTF("data out of range (%u > %u || %u < %u)", data, rdt->rdt_max, data, rdt->rdt_min);
+		return sc->sc_data_mask;
+	}
+	for (i = 1; i < rdt->rdt_size; i++) {
+		if (rdt->rdt_array[i].data >= data) {
 			int temprange, offset;
 			uint32_t datarange, datadiff;
+			unsigned first, secnd;
 
-			if (rk3399_data_table[i].data == data)
-				return rk3399_data_table[i].temp;
+			if (rdt->rdt_array[i].data == data)
+				return rdt->rdt_array[i].temp;
 
 			/* must interpolate */
-			temprange = rk3399_data_table[i].temp -
-				    rk3399_data_table[i-1].temp;
-			datarange = rk3399_data_table[i].data -
-				    rk3399_data_table[i-1].data;
-			datadiff = data - rk3399_data_table[i-1].data;
+			if (rdt->rdt_decr) {
+				first = i;
+				secnd = i+1;
+			} else {
+				first = i;
+				secnd = i-1;
+			}
+
+			temprange = rdt->rdt_array[first].temp -
+				    rdt->rdt_array[secnd].temp;
+			datarange = rdt->rdt_array[first].data -
+				    rdt->rdt_array[secnd].data;
+			datadiff = data - rdt->rdt_array[secnd].data;
 
 			offset = (temprange * datadiff) / datarange;
-			return rk3399_data_table[i-1].temp + offset;
+			return rdt->rdt_array[secnd].temp + offset;
 		}
 	}
-
-	return rk3399_data_table[i].temp;
+	panic("didn't find range");
 }
 
 static uint32_t
 rk_tsadc_temp_to_data(struct rk_tsadc_softc *sc, int temp)
 {
 	unsigned i;
+	const rk_data_table *rdt = sc->sc_rdt;
 
-	for (i = 1; i < __arraycount(rk3399_data_table); i++) {
-		if (rk3399_data_table[i].temp >= temp) {
+	for (i = 1; i < rdt->rdt_size; i++) {
+		if (rdt->rdt_array[i].temp >= temp) {
 			int temprange, tempdiff;
 			uint32_t datarange, offset;
+			unsigned first, secnd;
 
-			if (rk3399_data_table[i].temp == temp)
-				return rk3399_data_table[i].data;
+			if (rdt->rdt_array[i].temp == temp)
+				return rdt->rdt_array[i].data;
 
 			/* must interpolate */
-			datarange = rk3399_data_table[i].data -
-				    rk3399_data_table[i-1].data;
-			temprange = rk3399_data_table[i].temp -
-				    rk3399_data_table[i-1].temp;
-			tempdiff = temp - rk3399_data_table[i-1].temp;
+			if (rdt->rdt_decr) {
+				first = i;
+				secnd = i+1;
+			} else {
+				first = i;
+				secnd = i-1;
+			}
+
+			datarange = rdt->rdt_array[first].data -
+				    rdt->rdt_array[secnd].data;
+			temprange = rdt->rdt_array[first].temp -
+				    rdt->rdt_array[secnd].temp;
+			tempdiff = temp - rdt->rdt_array[secnd].temp;
 
 			offset = (datarange * tempdiff) / temprange;
-			return rk3399_data_table[i-1].data + offset;
+			return rdt->rdt_array[secnd].data + offset;
 		}
 	}
 

Reply via email to