driver: sensor: add tachometer driver for rts5912
Add tachometer driver for Realtek rts5912. Signed-off-by: Jhan BoChao <jhan_bo_chao@realtek.com>
This commit is contained in:
parent
8b54e8afa9
commit
482d17f235
11 changed files with 261 additions and 0 deletions
|
@ -53,3 +53,10 @@
|
|||
&swj_port {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&tach0 {
|
||||
status = "okay";
|
||||
pinctrl-0 = <&tacho0_gpio052>;
|
||||
pinctrl-names = "default";
|
||||
pulses-per-round = <2>;
|
||||
};
|
||||
|
|
|
@ -22,6 +22,7 @@ add_subdirectory(nordic)
|
|||
add_subdirectory(nuvoton)
|
||||
add_subdirectory(nxp)
|
||||
add_subdirectory(pixart)
|
||||
add_subdirectory(realtek)
|
||||
add_subdirectory(renesas)
|
||||
add_subdirectory(rohm)
|
||||
add_subdirectory(seeed)
|
||||
|
|
|
@ -108,6 +108,7 @@ source "drivers/sensor/nordic/Kconfig"
|
|||
source "drivers/sensor/nuvoton/Kconfig"
|
||||
source "drivers/sensor/nxp/Kconfig"
|
||||
source "drivers/sensor/pixart/Kconfig"
|
||||
source "drivers/sensor/realtek/Kconfig"
|
||||
source "drivers/sensor/renesas/Kconfig"
|
||||
source "drivers/sensor/rohm/Kconfig"
|
||||
source "drivers/sensor/seeed/Kconfig"
|
||||
|
|
4
drivers/sensor/realtek/CMakeLists.txt
Normal file
4
drivers/sensor/realtek/CMakeLists.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
# Copyright (c) 2025, Realtek, SIBG-SD7
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
add_subdirectory_ifdef(CONFIG_TACH_RTS5912 rts5912)
|
4
drivers/sensor/realtek/Kconfig
Normal file
4
drivers/sensor/realtek/Kconfig
Normal file
|
@ -0,0 +1,4 @@
|
|||
# Copyright (c) 2025, Realtek, SIBG-SD7
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
source "drivers/sensor/realtek/rts5912/Kconfig"
|
6
drivers/sensor/realtek/rts5912/CMakeLists.txt
Normal file
6
drivers/sensor/realtek/rts5912/CMakeLists.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Copyright (c) 2025, Realtek, SIBG-SD7
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_library()
|
||||
|
||||
zephyr_library_sources(rts5912.c)
|
9
drivers/sensor/realtek/rts5912/Kconfig
Normal file
9
drivers/sensor/realtek/rts5912/Kconfig
Normal file
|
@ -0,0 +1,9 @@
|
|||
# Copyright (c) 2025, Realtek, SIBG-SD7
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config TACH_RTS5912
|
||||
bool "RTS5912 Tachometer sensor"
|
||||
default y
|
||||
depends on DT_HAS_REALTEK_RTS5912_TACH_ENABLED
|
||||
help
|
||||
Enable the Realtek RTS5912 tachometer sensor.
|
150
drivers/sensor/realtek/rts5912/rts5912.c
Normal file
150
drivers/sensor/realtek/rts5912/rts5912.c
Normal file
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* Copyright (c) 2025 Realtek, SIBG-SD7
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT realtek_rts5912_tach
|
||||
|
||||
#include <errno.h>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/drivers/clock_control.h>
|
||||
#include <zephyr/drivers/clock_control/clock_control_rts5912.h>
|
||||
#include <zephyr/drivers/pinctrl.h>
|
||||
#include <zephyr/drivers/sensor.h>
|
||||
#include <zephyr/sys/sys_io.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
|
||||
#include "reg/reg_tacho.h"
|
||||
|
||||
LOG_MODULE_REGISTER(tach_rts5912, CONFIG_SENSOR_LOG_LEVEL);
|
||||
|
||||
struct tach_rts5912_config {
|
||||
volatile struct tacho_regs *regs;
|
||||
uint32_t clk_grp;
|
||||
uint32_t clk_idx;
|
||||
uint32_t clk_src;
|
||||
uint32_t clk_div;
|
||||
const struct device *clk_dev;
|
||||
const struct pinctrl_dev_config *pcfg;
|
||||
int pulses_per_round;
|
||||
};
|
||||
|
||||
struct tach_rts5912_data {
|
||||
uint16_t count;
|
||||
};
|
||||
|
||||
#define COUNT_100KHZ_SEC 100000U
|
||||
#define SEC_TO_MINUTE 60U
|
||||
#define PIN_STUCK_TIMEOUT (100U * USEC_PER_MSEC)
|
||||
|
||||
int tach_rts5912_sample_fetch(const struct device *dev, enum sensor_channel chan)
|
||||
{
|
||||
const struct tach_rts5912_config *const cfg = dev->config;
|
||||
struct tach_rts5912_data *const data = dev->data;
|
||||
volatile struct tacho_regs *const tach = cfg->regs;
|
||||
|
||||
if (chan != SENSOR_CHAN_RPM && chan != SENSOR_CHAN_ALL) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
tach->status = TACHO_STS_CNTRDY;
|
||||
|
||||
if (WAIT_FOR(tach->status & TACHO_STS_CNTRDY, PIN_STUCK_TIMEOUT, k_msleep(1))) {
|
||||
/* See whether internal counter is already latched */
|
||||
if (tach->status & TACHO_STS_CNTRDY) {
|
||||
tach->status = TACHO_STS_CNTRDY;
|
||||
data->count = (tach->ctrl & TACHO_CTRL_CNT_Msk) >> TACHO_CTRL_CNT_Pos;
|
||||
}
|
||||
} else {
|
||||
data->count = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tach_rts5912_channel_get(const struct device *dev, enum sensor_channel chan,
|
||||
struct sensor_value *val)
|
||||
{
|
||||
const struct tach_rts5912_config *const cfg = dev->config;
|
||||
struct tach_rts5912_data *const data = dev->data;
|
||||
|
||||
if (chan != SENSOR_CHAN_RPM) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
/* Convert the count per 100khz cycles to rpm */
|
||||
if (data->count != 0U) {
|
||||
val->val1 =
|
||||
(SEC_TO_MINUTE * COUNT_100KHZ_SEC) / (cfg->pulses_per_round * data->count);
|
||||
} else {
|
||||
val->val1 = 0U;
|
||||
}
|
||||
|
||||
val->val2 = 0U;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tach_rts5912_init(const struct device *dev)
|
||||
{
|
||||
const struct tach_rts5912_config *const cfg = dev->config;
|
||||
volatile struct tacho_regs *const tach = cfg->regs;
|
||||
int ret;
|
||||
|
||||
struct rts5912_sccon_subsys sccon_subsys = {
|
||||
.clk_grp = cfg->clk_grp,
|
||||
.clk_idx = cfg->clk_idx,
|
||||
};
|
||||
|
||||
if (!device_is_ready(cfg->clk_dev)) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = clock_control_on(cfg->clk_dev, (clock_control_subsys_t)&sccon_subsys);
|
||||
if (ret != 0) {
|
||||
LOG_ERR("RTS5912 Tachometer clock control failed (%d)", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PINCTRL
|
||||
ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
|
||||
|
||||
if (ret != 0) {
|
||||
LOG_ERR("RTS5912 pinctrl failed (%d)", ret);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* write one clear the status */
|
||||
tach->status = TACHO_STS_LIMIT | TACHO_STS_CHG | TACHO_STS_CNTRDY;
|
||||
tach->ctrl &= ~TACHO_CTRL_SELEDGE_Msk;
|
||||
tach->ctrl = ((0x01ul << TACHO_CTRL_SELEDGE_Pos) | TACHO_CTRL_READMODE | TACHO_CTRL_EN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DEVICE_API(sensor, tach_rts5912_driver_api) = {
|
||||
.sample_fetch = tach_rts5912_sample_fetch,
|
||||
.channel_get = tach_rts5912_channel_get,
|
||||
};
|
||||
|
||||
#define REALTEK_TACH_INIT(inst) \
|
||||
PINCTRL_DT_INST_DEFINE(inst); \
|
||||
\
|
||||
static const struct tach_rts5912_config tach_cfg_##inst = { \
|
||||
.regs = (struct tacho_regs *const)DT_INST_REG_ADDR(inst), \
|
||||
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \
|
||||
.clk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(inst)), \
|
||||
.clk_grp = DT_INST_CLOCKS_CELL_BY_NAME(inst, tacho, clk_grp), \
|
||||
.clk_idx = DT_INST_CLOCKS_CELL_BY_NAME(inst, tacho, clk_idx), \
|
||||
.pulses_per_round = DT_INST_PROP(inst, pulses_per_round), \
|
||||
}; \
|
||||
\
|
||||
static struct tach_rts5912_data tach_data_##inst; \
|
||||
\
|
||||
SENSOR_DEVICE_DT_INST_DEFINE(inst, tach_rts5912_init, NULL, &tach_data_##inst, \
|
||||
&tach_cfg_##inst, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \
|
||||
&tach_rts5912_driver_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(REALTEK_TACH_INIT)
|
|
@ -267,6 +267,15 @@
|
|||
interrupt-parent = <&nvic>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
tach0: tach@4000fd00 {
|
||||
compatible = "realtek,rts5912-tach";
|
||||
reg = <0x4000fd00 0x40>;
|
||||
clocks = <&sccon RTS5912_SCCON_PERIPH_GRP0 PERIPH_GRP0_TACH0_CLKPWR>;
|
||||
clock-names = "tacho";
|
||||
interrupts = <192 0>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
swj_port: swj-port {
|
||||
|
|
28
dts/bindings/tach/realtek,rts5912-tach.yaml
Normal file
28
dts/bindings/tach/realtek,rts5912-tach.yaml
Normal file
|
@ -0,0 +1,28 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Copyright (c) 2025 Realtek Semiconductor Corporation, SIBG-SD7
|
||||
#
|
||||
|
||||
description: Realtek rts5912 tachometer controller
|
||||
|
||||
compatible: "realtek,rts5912-tach"
|
||||
|
||||
include: [tach.yaml, pinctrl-device.yaml, sensor-device.yaml]
|
||||
|
||||
properties:
|
||||
reg:
|
||||
required: true
|
||||
|
||||
interrupts:
|
||||
required: true
|
||||
|
||||
pinctrl-0:
|
||||
required: true
|
||||
|
||||
pinctrl-names:
|
||||
required: true
|
||||
|
||||
pulses-per-round:
|
||||
type: int
|
||||
required: true
|
||||
description: number of pulses per round of tachometer's input
|
42
soc/realtek/ec/rts5912/reg/reg_tacho.h
Normal file
42
soc/realtek/ec/rts5912/reg/reg_tacho.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2025 Realtek, SIBG-SD7
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_SOC_REALTEK_RTS5912_REG_TACHO_H
|
||||
#define ZEPHYR_SOC_REALTEK_RTS5912_REG_TACHO_H
|
||||
|
||||
struct tacho_regs {
|
||||
uint32_t ctrl;
|
||||
uint32_t status;
|
||||
uint32_t limit_high;
|
||||
uint32_t limit_low;
|
||||
uint32_t int_en;
|
||||
};
|
||||
|
||||
/* CTRL */
|
||||
#define TACHO_CTRL_EN BIT(0UL)
|
||||
#define TACHO_CTRL_FILTEREN BIT(1UL)
|
||||
#define TACHO_CTRL_SELEDGE_Pos (2UL)
|
||||
#define TACHO_CTRL_SELEDGE_Msk GENMASK(3, TACHO_CTRL_SELEDGE_Pos)
|
||||
#define TACHO_CTRL_READMODE BIT(4UL)
|
||||
#define TACHO_CTRL_CNT_Pos (16UL)
|
||||
#define TACHO_CTRL_CNT_Msk GENMASK(31, TACHO_CTRL_CNT_Pos)
|
||||
/* STS */
|
||||
#define TACHO_STS_LIMIT BIT(0UL)
|
||||
#define TACHO_STS_PIN BIT(1UL)
|
||||
#define TACHO_STS_CHG BIT(2UL)
|
||||
#define TACHO_STS_CNTRDY BIT(3UL)
|
||||
/* LIMITH */
|
||||
#define TACHO_LIMITH_VAL_Pos (0UL)
|
||||
#define TACHO_LIMITH_VAL_Msk GENMASK(15, TACHO_LIMITH_VAL_Pos)
|
||||
/* LIMITL */
|
||||
#define TACHO_LIMITL_VAL_Pos (0UL)
|
||||
#define TACHO_LIMITL_VAL_Msk GENMASK(15, TACHO_LIMITL_VAL_Pos)
|
||||
/* INTEN */
|
||||
#define TACHO_INTEN_LIMITEN BIT(0UL)
|
||||
#define TACHO_INTEN_CNTRDYEN BIT(1UL)
|
||||
#define TACHO_INTEN_CHGEN BIT(2UL)
|
||||
|
||||
#endif /* ZEPHYR_SOC_REALTEK_RTS5912_REG_TACHO_H */
|
Loading…
Add table
Add a link
Reference in a new issue