Skip to content

Commit 482d17f

Browse files
JhanBoChao-Realtekkartben
authored andcommitted
driver: sensor: add tachometer driver for rts5912
Add tachometer driver for Realtek rts5912. Signed-off-by: Jhan BoChao <jhan_bo_chao@realtek.com>
1 parent 8b54e8a commit 482d17f

File tree

11 files changed

+261
-0
lines changed

11 files changed

+261
-0
lines changed

boards/realtek/rts5912_evb/rts5912_evb.dts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,10 @@
5353
&swj_port {
5454
status = "okay";
5555
};
56+
57+
&tach0 {
58+
status = "okay";
59+
pinctrl-0 = <&tacho0_gpio052>;
60+
pinctrl-names = "default";
61+
pulses-per-round = <2>;
62+
};

drivers/sensor/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ add_subdirectory(nordic)
2222
add_subdirectory(nuvoton)
2323
add_subdirectory(nxp)
2424
add_subdirectory(pixart)
25+
add_subdirectory(realtek)
2526
add_subdirectory(renesas)
2627
add_subdirectory(rohm)
2728
add_subdirectory(seeed)

drivers/sensor/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ source "drivers/sensor/nordic/Kconfig"
108108
source "drivers/sensor/nuvoton/Kconfig"
109109
source "drivers/sensor/nxp/Kconfig"
110110
source "drivers/sensor/pixart/Kconfig"
111+
source "drivers/sensor/realtek/Kconfig"
111112
source "drivers/sensor/renesas/Kconfig"
112113
source "drivers/sensor/rohm/Kconfig"
113114
source "drivers/sensor/seeed/Kconfig"

drivers/sensor/realtek/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Copyright (c) 2025, Realtek, SIBG-SD7
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
add_subdirectory_ifdef(CONFIG_TACH_RTS5912 rts5912)

drivers/sensor/realtek/Kconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Copyright (c) 2025, Realtek, SIBG-SD7
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
source "drivers/sensor/realtek/rts5912/Kconfig"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Copyright (c) 2025, Realtek, SIBG-SD7
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
zephyr_library()
5+
6+
zephyr_library_sources(rts5912.c)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Copyright (c) 2025, Realtek, SIBG-SD7
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config TACH_RTS5912
5+
bool "RTS5912 Tachometer sensor"
6+
default y
7+
depends on DT_HAS_REALTEK_RTS5912_TACH_ENABLED
8+
help
9+
Enable the Realtek RTS5912 tachometer sensor.
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/*
2+
* Copyright (c) 2025 Realtek, SIBG-SD7
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#define DT_DRV_COMPAT realtek_rts5912_tach
8+
9+
#include <errno.h>
10+
#include <zephyr/device.h>
11+
#include <zephyr/drivers/clock_control.h>
12+
#include <zephyr/drivers/clock_control/clock_control_rts5912.h>
13+
#include <zephyr/drivers/pinctrl.h>
14+
#include <zephyr/drivers/sensor.h>
15+
#include <zephyr/sys/sys_io.h>
16+
#include <zephyr/logging/log.h>
17+
18+
#include "reg/reg_tacho.h"
19+
20+
LOG_MODULE_REGISTER(tach_rts5912, CONFIG_SENSOR_LOG_LEVEL);
21+
22+
struct tach_rts5912_config {
23+
volatile struct tacho_regs *regs;
24+
uint32_t clk_grp;
25+
uint32_t clk_idx;
26+
uint32_t clk_src;
27+
uint32_t clk_div;
28+
const struct device *clk_dev;
29+
const struct pinctrl_dev_config *pcfg;
30+
int pulses_per_round;
31+
};
32+
33+
struct tach_rts5912_data {
34+
uint16_t count;
35+
};
36+
37+
#define COUNT_100KHZ_SEC 100000U
38+
#define SEC_TO_MINUTE 60U
39+
#define PIN_STUCK_TIMEOUT (100U * USEC_PER_MSEC)
40+
41+
int tach_rts5912_sample_fetch(const struct device *dev, enum sensor_channel chan)
42+
{
43+
const struct tach_rts5912_config *const cfg = dev->config;
44+
struct tach_rts5912_data *const data = dev->data;
45+
volatile struct tacho_regs *const tach = cfg->regs;
46+
47+
if (chan != SENSOR_CHAN_RPM && chan != SENSOR_CHAN_ALL) {
48+
return -ENOTSUP;
49+
}
50+
51+
tach->status = TACHO_STS_CNTRDY;
52+
53+
if (WAIT_FOR(tach->status & TACHO_STS_CNTRDY, PIN_STUCK_TIMEOUT, k_msleep(1))) {
54+
/* See whether internal counter is already latched */
55+
if (tach->status & TACHO_STS_CNTRDY) {
56+
tach->status = TACHO_STS_CNTRDY;
57+
data->count = (tach->ctrl & TACHO_CTRL_CNT_Msk) >> TACHO_CTRL_CNT_Pos;
58+
}
59+
} else {
60+
data->count = 0;
61+
}
62+
63+
return 0;
64+
}
65+
66+
static int tach_rts5912_channel_get(const struct device *dev, enum sensor_channel chan,
67+
struct sensor_value *val)
68+
{
69+
const struct tach_rts5912_config *const cfg = dev->config;
70+
struct tach_rts5912_data *const data = dev->data;
71+
72+
if (chan != SENSOR_CHAN_RPM) {
73+
return -ENOTSUP;
74+
}
75+
76+
/* Convert the count per 100khz cycles to rpm */
77+
if (data->count != 0U) {
78+
val->val1 =
79+
(SEC_TO_MINUTE * COUNT_100KHZ_SEC) / (cfg->pulses_per_round * data->count);
80+
} else {
81+
val->val1 = 0U;
82+
}
83+
84+
val->val2 = 0U;
85+
86+
return 0;
87+
}
88+
89+
static int tach_rts5912_init(const struct device *dev)
90+
{
91+
const struct tach_rts5912_config *const cfg = dev->config;
92+
volatile struct tacho_regs *const tach = cfg->regs;
93+
int ret;
94+
95+
struct rts5912_sccon_subsys sccon_subsys = {
96+
.clk_grp = cfg->clk_grp,
97+
.clk_idx = cfg->clk_idx,
98+
};
99+
100+
if (!device_is_ready(cfg->clk_dev)) {
101+
return -ENODEV;
102+
}
103+
104+
ret = clock_control_on(cfg->clk_dev, (clock_control_subsys_t)&sccon_subsys);
105+
if (ret != 0) {
106+
LOG_ERR("RTS5912 Tachometer clock control failed (%d)", ret);
107+
return ret;
108+
}
109+
110+
#ifdef CONFIG_PINCTRL
111+
ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
112+
113+
if (ret != 0) {
114+
LOG_ERR("RTS5912 pinctrl failed (%d)", ret);
115+
return ret;
116+
}
117+
#endif
118+
119+
/* write one clear the status */
120+
tach->status = TACHO_STS_LIMIT | TACHO_STS_CHG | TACHO_STS_CNTRDY;
121+
tach->ctrl &= ~TACHO_CTRL_SELEDGE_Msk;
122+
tach->ctrl = ((0x01ul << TACHO_CTRL_SELEDGE_Pos) | TACHO_CTRL_READMODE | TACHO_CTRL_EN);
123+
124+
return 0;
125+
}
126+
127+
static DEVICE_API(sensor, tach_rts5912_driver_api) = {
128+
.sample_fetch = tach_rts5912_sample_fetch,
129+
.channel_get = tach_rts5912_channel_get,
130+
};
131+
132+
#define REALTEK_TACH_INIT(inst) \
133+
PINCTRL_DT_INST_DEFINE(inst); \
134+
\
135+
static const struct tach_rts5912_config tach_cfg_##inst = { \
136+
.regs = (struct tacho_regs *const)DT_INST_REG_ADDR(inst), \
137+
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \
138+
.clk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(inst)), \
139+
.clk_grp = DT_INST_CLOCKS_CELL_BY_NAME(inst, tacho, clk_grp), \
140+
.clk_idx = DT_INST_CLOCKS_CELL_BY_NAME(inst, tacho, clk_idx), \
141+
.pulses_per_round = DT_INST_PROP(inst, pulses_per_round), \
142+
}; \
143+
\
144+
static struct tach_rts5912_data tach_data_##inst; \
145+
\
146+
SENSOR_DEVICE_DT_INST_DEFINE(inst, tach_rts5912_init, NULL, &tach_data_##inst, \
147+
&tach_cfg_##inst, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \
148+
&tach_rts5912_driver_api);
149+
150+
DT_INST_FOREACH_STATUS_OKAY(REALTEK_TACH_INIT)

dts/arm/realtek/ec/rts5912.dtsi

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,15 @@
267267
interrupt-parent = <&nvic>;
268268
status = "disabled";
269269
};
270+
271+
tach0: tach@4000fd00 {
272+
compatible = "realtek,rts5912-tach";
273+
reg = <0x4000fd00 0x40>;
274+
clocks = <&sccon RTS5912_SCCON_PERIPH_GRP0 PERIPH_GRP0_TACH0_CLKPWR>;
275+
clock-names = "tacho";
276+
interrupts = <192 0>;
277+
status = "disabled";
278+
};
270279
};
271280

272281
swj_port: swj-port {
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
#
3+
# Copyright (c) 2025 Realtek Semiconductor Corporation, SIBG-SD7
4+
#
5+
6+
description: Realtek rts5912 tachometer controller
7+
8+
compatible: "realtek,rts5912-tach"
9+
10+
include: [tach.yaml, pinctrl-device.yaml, sensor-device.yaml]
11+
12+
properties:
13+
reg:
14+
required: true
15+
16+
interrupts:
17+
required: true
18+
19+
pinctrl-0:
20+
required: true
21+
22+
pinctrl-names:
23+
required: true
24+
25+
pulses-per-round:
26+
type: int
27+
required: true
28+
description: number of pulses per round of tachometer's input

0 commit comments

Comments
 (0)