drivers: can: split CAN classic and CAN-FD syscalls

Split CAN classic and CAN-FD syscalls into two:
- can_set_timing() -> can_set_timing() + can_set_timing_data()
- can_set_bitrate() -> can_set_bitrate() + can_set_bitrate_data()

Fixes: #45303

Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
This commit is contained in:
Henrik Brix Andersen 2022-05-03 22:05:53 +02:00 committed by Carles Cufí
commit 18890828b8
19 changed files with 189 additions and 90 deletions

View file

@ -207,12 +207,9 @@ uint16_t sample_point_for_bitrate(uint32_t bitrate)
return sample_pnt;
}
int z_impl_can_set_bitrate(const struct device *dev, uint32_t bitrate, uint32_t bitrate_data)
int z_impl_can_set_bitrate(const struct device *dev, uint32_t bitrate)
{
struct can_timing timing;
#ifdef CONFIG_CAN_FD_MODE
struct can_timing timing_data;
#endif /* CONFIG_CAN_FD_MODE */
uint32_t max_bitrate;
uint16_t sample_pnt;
int ret;
@ -241,7 +238,25 @@ int z_impl_can_set_bitrate(const struct device *dev, uint32_t bitrate, uint32_t
timing.sjw = CAN_SJW_NO_CHANGE;
return can_set_timing(dev, &timing);
}
#ifdef CONFIG_CAN_FD_MODE
int z_impl_can_set_bitrate_data(const struct device *dev, uint32_t bitrate_data)
{
struct can_timing timing_data;
uint32_t max_bitrate;
uint16_t sample_pnt;
int ret;
ret = can_get_max_bitrate(dev, &max_bitrate);
if (ret == -ENOSYS) {
/* Maximum bitrate unknown */
max_bitrate = 0;
} else if (ret < 0) {
return ret;
}
if ((max_bitrate > 0) && (bitrate_data > max_bitrate)) {
return -ENOTSUP;
}
@ -258,8 +273,6 @@ int z_impl_can_set_bitrate(const struct device *dev, uint32_t bitrate, uint32_t
timing_data.sjw = CAN_SJW_NO_CHANGE;
return can_set_timing(dev, &timing, &timing_data);
#else /* CONFIG_CAN_FD_MODE */
return can_set_timing(dev, &timing, NULL);
#endif /* !CONFIG_CAN_FD_MODE */
return can_set_timing_data(dev, &timing_data);
}
#endif /* CONFIG_CAN_FD_MODE */

View file

@ -24,21 +24,14 @@ static int z_vrfy_can_calc_timing(const struct device *dev, struct can_timing *r
#include <syscalls/can_calc_timing_mrsh.c>
static inline int z_vrfy_can_set_timing(const struct device *dev,
const struct can_timing *timing,
const struct can_timing *timing_data)
const struct can_timing *timing)
{
struct can_timing timing_copy;
struct can_timing timing_data_copy;
Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, set_timing));
Z_OOPS(z_user_from_copy(&timing_copy, timing, sizeof(timing_copy)));
if (timing_data != NULL) {
Z_OOPS(z_user_from_copy(&timing_data_copy, timing_data, sizeof(timing_data_copy)));
return z_impl_can_set_timing(dev, &timing_copy, &timing_data_copy);
}
return z_impl_can_set_timing(dev, &timing_copy, NULL);
return z_impl_can_set_timing(dev, &timing_copy);
}
#include <syscalls/can_set_timing_mrsh.c>
@ -113,6 +106,27 @@ static inline const struct can_timing *z_vrfy_can_get_timing_max_data(const stru
}
#include <syscalls/can_get_timing_max_data_mrsh.c>
static inline int z_vrfy_can_set_timing_data(const struct device *dev,
const struct can_timing *timing_data)
{
struct can_timing timing_data_copy;
Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, set_timing_data));
Z_OOPS(z_user_from_copy(&timing_data_copy, timing_data, sizeof(timing_data_copy)));
return z_impl_can_set_timing_data(dev, &timing_data_copy);
}
#include <syscalls/can_set_timing_data_mrsh.c>
static inline int z_vrfy_can_set_bitrate_data(const struct device *dev,
uint32_t bitrate_data)
{
Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, set_timing_data));
return z_impl_can_set_bitrate_data(dev, bitrate_data);
}
#include <syscalls/can_set_bitrate_data_mrsh.c>
#endif /* CONFIG_CAN_FD_MODE */
static inline int z_vrfy_can_get_max_filters(const struct device *dev, enum can_ide id_type)
@ -132,12 +146,11 @@ static inline int z_vrfy_can_set_mode(const struct device *dev, enum can_mode mo
}
#include <syscalls/can_set_mode_mrsh.c>
static inline int z_vrfy_can_set_bitrate(const struct device *dev, uint32_t bitrate,
uint32_t bitrate_data)
static inline int z_vrfy_can_set_bitrate(const struct device *dev, uint32_t bitrate)
{
Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, set_timing));
return z_impl_can_set_bitrate(dev, bitrate, bitrate_data);
return z_impl_can_set_bitrate(dev, bitrate);
}
#include <syscalls/can_set_bitrate_mrsh.c>

View file

@ -206,12 +206,11 @@ static int can_loopback_set_mode(const struct device *dev, enum can_mode mode)
}
static int can_loopback_set_timing(const struct device *dev,
const struct can_timing *timing,
const struct can_timing *timing_data)
const struct can_timing *timing)
{
ARG_UNUSED(dev);
ARG_UNUSED(timing);
ARG_UNUSED(timing_data);
return 0;
}

View file

@ -185,7 +185,34 @@ void can_mcan_configure_timing(struct can_mcan_reg *can,
}
int can_mcan_set_timing(const struct device *dev,
const struct can_timing *timing,
const struct can_timing *timing)
{
const struct can_mcan_config *cfg = dev->config;
struct can_mcan_reg *can = cfg->can;
int ret;
ret = can_enter_init_mode(can, K_MSEC(CAN_INIT_TIMEOUT));
if (ret) {
LOG_ERR("Failed to enter init mode");
return -EIO;
}
/* Configuration Change Enable */
can->cccr |= CAN_MCAN_CCCR_CCE;
can_mcan_configure_timing(can, timing, NULL);
ret = can_leave_init_mode(can, K_MSEC(CAN_INIT_TIMEOUT));
if (ret) {
LOG_ERR("Failed to leave init mode");
return -EIO;
}
return 0;
}
#ifdef CONFIG_CAN_FD_MODE
int can_mcan_set_timing_data(const struct device *dev,
const struct can_timing *timing_data)
{
const struct can_mcan_config *cfg = dev->config;
@ -201,7 +228,7 @@ int can_mcan_set_timing(const struct device *dev,
/* Configuration Change Enable */
can->cccr |= CAN_MCAN_CCCR_CCE;
can_mcan_configure_timing(can, timing, timing_data);
can_mcan_configure_timing(can, NULL, timing_data);
ret = can_leave_init_mode(can, K_MSEC(CAN_INIT_TIMEOUT));
if (ret) {
@ -211,6 +238,7 @@ int can_mcan_set_timing(const struct device *dev,
return 0;
}
#endif /* CONFIG_CAN_FD_MODE */
int can_mcan_set_mode(const struct device *dev, enum can_mode mode)
{

View file

@ -260,8 +260,10 @@ struct can_mcan_reg;
int can_mcan_set_mode(const struct device *dev, enum can_mode mode);
int can_mcan_set_timing(const struct device *dev,
const struct can_timing *timing,
const struct can_timing *timing_data);
const struct can_timing *timing);
int can_mcan_set_timing_data(const struct device *dev,
const struct can_timing *timing_data);
int can_mcan_init(const struct device *dev);

View file

@ -330,10 +330,8 @@ static int mcp2515_get_max_bitrate(const struct device *dev, uint32_t *max_bitra
}
static int mcp2515_set_timing(const struct device *dev,
const struct can_timing *timing,
const struct can_timing *timing_data)
const struct can_timing *timing)
{
ARG_UNUSED(timing_data);
struct mcp2515_data *dev_data = dev->data;
int ret;
@ -949,7 +947,7 @@ static int mcp2515_init(const struct device *dev)
}
}
ret = can_set_timing(dev, &timing, NULL);
ret = can_set_timing(dev, &timing);
if (ret) {
return ret;
}

View file

@ -152,10 +152,8 @@ static int mcux_flexcan_get_max_bitrate(const struct device *dev, uint32_t *max_
}
static int mcux_flexcan_set_timing(const struct device *dev,
const struct can_timing *timing,
const struct can_timing *timing_data)
const struct can_timing *timing)
{
ARG_UNUSED(timing_data);
struct mcux_flexcan_data *data = dev->data;
const struct mcux_flexcan_config *config = dev->config;
uint8_t sjw_backup = data->timing.sjw;

View file

@ -94,6 +94,7 @@ static const struct can_driver_api mcux_mcan_driver_api = {
.prescaler = 512,
},
#ifdef CONFIG_CAN_FD_MODE
.set_timing_data = can_mcan_set_timing_data,
/*
* MCUX MCAN data timing limits are specified in the "Data bit timing
* and prescaler register (DBTP)" table in the SoC reference manual.

View file

@ -648,15 +648,12 @@ static void can_rcar_set_bittiming(const struct can_rcar_cfg *config,
}
static int can_rcar_set_timing(const struct device *dev,
const struct can_timing *timing,
const struct can_timing *timing_data)
const struct can_timing *timing)
{
const struct can_rcar_cfg *config = dev->config;
struct can_rcar_data *data = dev->data;
int ret = 0;
ARG_UNUSED(timing_data);
k_mutex_lock(&data->inst_mutex, K_FOREVER);
/* Changing bittiming should be done in reset mode */
@ -955,7 +952,7 @@ static int can_rcar_init(const struct device *dev)
}
}
ret = can_rcar_set_timing(dev, &timing, NULL);
ret = can_rcar_set_timing(dev, &timing);
if (ret) {
return ret;
}

View file

@ -98,6 +98,7 @@ static const struct can_driver_api can_sam_driver_api = {
.prescaler = 0x200
},
#ifdef CONFIG_CAN_FD_MODE
.set_timing_data = can_mcan_set_timing_data,
.timing_min_data = {
.sjw = 0x01,
.prop_seg = 0x00,

View file

@ -272,7 +272,7 @@ static int cmd_config(const struct shell *sh, size_t argc, char **argv)
return -EINVAL;
}
ret = can_set_bitrate(can_dev, bitrate, 0);
ret = can_set_bitrate(can_dev, bitrate);
if (ret) {
shell_error(sh, "Failed to set bitrate [%d]",
ret);

View file

@ -402,16 +402,13 @@ done:
}
static int can_stm32_set_timing(const struct device *dev,
const struct can_timing *timing,
const struct can_timing *timing_data)
const struct can_timing *timing)
{
const struct can_stm32_config *cfg = dev->config;
CAN_TypeDef *can = cfg->can;
struct can_stm32_data *data = dev->data;
int ret = -EIO;
ARG_UNUSED(timing_data);
k_mutex_lock(&data->inst_mutex, K_FOREVER);
ret = can_enter_init_mode(can);
if (ret) {
@ -566,7 +563,7 @@ static int can_stm32_init(const struct device *dev)
}
}
ret = can_stm32_set_timing(dev, &timing, NULL);
ret = can_stm32_set_timing(dev, &timing);
if (ret) {
return ret;
}

View file

@ -137,6 +137,7 @@ static const struct can_driver_api can_stm32fd_driver_api = {
.prescaler = 0x200
},
#ifdef CONFIG_CAN_FD_MODE
.set_timing_data = can_mcan_set_timing_data,
.timing_min_data = {
.sjw = 0x01,
.prop_seg = 0x00,

View file

@ -127,6 +127,7 @@ static const struct can_driver_api can_stm32h7_driver_api = {
.prescaler = 0x200
},
#ifdef CONFIG_CAN_FD_MODE
.set_timing_data = can_mcan_set_timing_data,
/* Data timing limits are per the STM32H7 Reference Manual
* (RM0433 Rev 7), section 56.5.3, FDCAN data bit timing and prescaler
* register (FDCAN_DBTP).