drivers: can: mcan: refactor to get rid of wrapper functions
Refactor the Bosch M_CAN shared driver functions to get rid of the front-end driver wrapper functions. This requires flipping the relationship between shared config/data structs and front-end config/data structs. Front-end drivers can now store a pointer to their custom config/data structs in the .custom fields of the can_mcan_config and can_mcan_data data structures. Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
This commit is contained in:
parent
7ea0951052
commit
5b3712a9ac
7 changed files with 300 additions and 703 deletions
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2022 Vestas Wind Systems A/S
|
||||
* Copyright (c) 2020 Alexander Wachter
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
|
@ -120,7 +121,7 @@ static int can_leave_init_mode(struct can_mcan_reg *can, k_timeout_t timeout)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void can_mcan_configure_timing(struct can_mcan_reg *can,
|
||||
void can_mcan_configure_timing(struct can_mcan_reg *can,
|
||||
const struct can_timing *timing,
|
||||
const struct can_timing *timing_data)
|
||||
{
|
||||
|
@ -183,10 +184,11 @@ void can_mcan_configure_timing(struct can_mcan_reg *can,
|
|||
#endif
|
||||
}
|
||||
|
||||
int can_mcan_set_timing(const struct can_mcan_config *cfg,
|
||||
int can_mcan_set_timing(const struct device *dev,
|
||||
const struct can_timing *timing,
|
||||
const struct can_timing *timing_data)
|
||||
{
|
||||
const struct can_mcan_config *cfg = dev->config;
|
||||
struct can_mcan_reg *can = cfg->can;
|
||||
int ret;
|
||||
|
||||
|
@ -210,8 +212,9 @@ int can_mcan_set_timing(const struct can_mcan_config *cfg,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int can_mcan_set_mode(const struct can_mcan_config *cfg, enum can_mode mode)
|
||||
int can_mcan_set_mode(const struct device *dev, enum can_mode mode)
|
||||
{
|
||||
const struct can_mcan_config *cfg = dev->config;
|
||||
struct can_mcan_reg *can = cfg->can;
|
||||
int ret;
|
||||
|
||||
|
@ -279,18 +282,18 @@ int can_mcan_set_mode(const struct can_mcan_config *cfg, enum can_mode mode)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int can_mcan_init(const struct device *dev, const struct can_mcan_config *cfg,
|
||||
struct can_mcan_msg_sram *msg_ram,
|
||||
struct can_mcan_data *data)
|
||||
int can_mcan_init(const struct device *dev)
|
||||
{
|
||||
struct can_mcan_reg *can = cfg->can;
|
||||
const struct can_mcan_config *cfg = dev->config;
|
||||
struct can_mcan_data *data = dev->data;
|
||||
struct can_mcan_reg *can = cfg->can;
|
||||
struct can_mcan_msg_sram *msg_ram = data->msg_ram;
|
||||
struct can_timing timing;
|
||||
#ifdef CONFIG_CAN_FD_MODE
|
||||
struct can_timing timing_data;
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
data->dev = dev;
|
||||
k_mutex_init(&data->inst_mutex);
|
||||
k_mutex_init(&data->tx_mtx);
|
||||
k_sem_init(&data->tx_sem, NUM_TX_BUF_ELEMENTS, NUM_TX_BUF_ELEMENTS);
|
||||
|
@ -495,25 +498,27 @@ done:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void can_mcan_state_change_handler(const struct can_mcan_config *cfg,
|
||||
struct can_mcan_data *data)
|
||||
static void can_mcan_state_change_handler(const struct device *dev)
|
||||
{
|
||||
enum can_state state;
|
||||
struct can_bus_err_cnt err_cnt;
|
||||
struct can_mcan_data *data = dev->data;
|
||||
const can_state_change_callback_t cb = data->state_change_cb;
|
||||
void *cb_data = data->state_change_cb_data;
|
||||
struct can_bus_err_cnt err_cnt;
|
||||
enum can_state state;
|
||||
|
||||
(void)can_mcan_get_state(cfg, &state, &err_cnt);
|
||||
(void)can_mcan_get_state(dev, &state, &err_cnt);
|
||||
|
||||
if (cb != NULL) {
|
||||
cb(data->dev, state, err_cnt, cb_data);
|
||||
cb(dev, state, err_cnt, cb_data);
|
||||
}
|
||||
}
|
||||
|
||||
static void can_mcan_tc_event_handler(struct can_mcan_reg *can,
|
||||
struct can_mcan_msg_sram *msg_ram,
|
||||
struct can_mcan_data *data)
|
||||
static void can_mcan_tc_event_handler(const struct device *dev)
|
||||
{
|
||||
const struct can_mcan_config *cfg = dev->config;
|
||||
struct can_mcan_data *data = dev->data;
|
||||
struct can_mcan_reg *can = cfg->can;
|
||||
struct can_mcan_msg_sram *msg_ram = data->msg_ram;
|
||||
volatile struct can_mcan_tx_event_fifo *tx_event;
|
||||
can_tx_callback_t tx_cb;
|
||||
uint32_t event_idx, tx_idx;
|
||||
|
@ -534,15 +539,15 @@ static void can_mcan_tc_event_handler(struct can_mcan_reg *can,
|
|||
if (tx_cb == NULL) {
|
||||
k_sem_give(&data->tx_fin_sem[tx_idx]);
|
||||
} else {
|
||||
tx_cb(data->dev, 0, data->tx_fin_cb_arg[tx_idx]);
|
||||
tx_cb(dev, 0, data->tx_fin_cb_arg[tx_idx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void can_mcan_line_0_isr(const struct can_mcan_config *cfg,
|
||||
struct can_mcan_msg_sram *msg_ram,
|
||||
struct can_mcan_data *data)
|
||||
void can_mcan_line_0_isr(const struct device *dev)
|
||||
{
|
||||
const struct can_mcan_config *cfg = dev->config;
|
||||
struct can_mcan_data *data = dev->data;
|
||||
struct can_mcan_reg *can = cfg->can;
|
||||
|
||||
do {
|
||||
|
@ -550,12 +555,12 @@ void can_mcan_line_0_isr(const struct can_mcan_config *cfg,
|
|||
CAN_MCAN_IR_EW)) {
|
||||
can->ir = CAN_MCAN_IR_BO | CAN_MCAN_IR_EP |
|
||||
CAN_MCAN_IR_EW;
|
||||
can_mcan_state_change_handler(cfg, data);
|
||||
can_mcan_state_change_handler(dev);
|
||||
}
|
||||
/* TX event FIFO new entry */
|
||||
if (can->ir & CAN_MCAN_IR_TEFN) {
|
||||
can->ir = CAN_MCAN_IR_TEFN;
|
||||
can_mcan_tc_event_handler(can, msg_ram, data);
|
||||
can_mcan_tc_event_handler(dev);
|
||||
}
|
||||
|
||||
if (can->ir & CAN_MCAN_IR_TEFL) {
|
||||
|
@ -578,11 +583,12 @@ void can_mcan_line_0_isr(const struct can_mcan_config *cfg,
|
|||
CAN_MCAN_IR_TEFL | CAN_MCAN_IR_TEFN));
|
||||
}
|
||||
|
||||
static void can_mcan_get_message(struct can_mcan_data *data,
|
||||
static void can_mcan_get_message(const struct device *dev,
|
||||
volatile struct can_mcan_rx_fifo *fifo,
|
||||
volatile uint32_t *fifo_status_reg,
|
||||
volatile uint32_t *fifo_ack_reg)
|
||||
{
|
||||
struct can_mcan_data *data = dev->data;
|
||||
uint32_t get_idx, filt_idx;
|
||||
struct zcan_frame frame;
|
||||
can_rx_callback_t cb;
|
||||
|
@ -647,7 +653,7 @@ static void can_mcan_get_message(struct can_mcan_data *data,
|
|||
}
|
||||
|
||||
if (cb) {
|
||||
cb(data->dev, &frame, cb_arg);
|
||||
cb(dev, &frame, cb_arg);
|
||||
} else {
|
||||
LOG_DBG("cb missing");
|
||||
}
|
||||
|
@ -659,24 +665,25 @@ static void can_mcan_get_message(struct can_mcan_data *data,
|
|||
}
|
||||
}
|
||||
|
||||
void can_mcan_line_1_isr(const struct can_mcan_config *cfg,
|
||||
struct can_mcan_msg_sram *msg_ram,
|
||||
struct can_mcan_data *data)
|
||||
void can_mcan_line_1_isr(const struct device *dev)
|
||||
{
|
||||
const struct can_mcan_config *cfg = dev->config;
|
||||
struct can_mcan_data *data = dev->data;
|
||||
struct can_mcan_reg *can = cfg->can;
|
||||
struct can_mcan_msg_sram *msg_ram = data->msg_ram;
|
||||
|
||||
do {
|
||||
if (can->ir & CAN_MCAN_IR_RF0N) {
|
||||
can->ir = CAN_MCAN_IR_RF0N;
|
||||
LOG_DBG("RX FIFO0 INT");
|
||||
can_mcan_get_message(data, msg_ram->rx_fifo0,
|
||||
can_mcan_get_message(dev, msg_ram->rx_fifo0,
|
||||
&can->rxf0s, &can->rxf0a);
|
||||
}
|
||||
|
||||
if (can->ir & CAN_MCAN_IR_RF1N) {
|
||||
can->ir = CAN_MCAN_IR_RF1N;
|
||||
LOG_DBG("RX FIFO1 INT");
|
||||
can_mcan_get_message(data, msg_ram->rx_fifo1,
|
||||
can_mcan_get_message(dev, msg_ram->rx_fifo1,
|
||||
&can->rxf1s, &can->rxf1a);
|
||||
}
|
||||
|
||||
|
@ -694,9 +701,10 @@ void can_mcan_line_1_isr(const struct can_mcan_config *cfg,
|
|||
CAN_MCAN_IR_RF0L | CAN_MCAN_IR_RF1L));
|
||||
}
|
||||
|
||||
int can_mcan_get_state(const struct can_mcan_config *cfg, enum can_state *state,
|
||||
int can_mcan_get_state(const struct device *dev, enum can_state *state,
|
||||
struct can_bus_err_cnt *err_cnt)
|
||||
{
|
||||
const struct can_mcan_config *cfg = dev->config;
|
||||
struct can_mcan_reg *can = cfg->can;
|
||||
|
||||
if (state != NULL) {
|
||||
|
@ -723,8 +731,9 @@ int can_mcan_get_state(const struct can_mcan_config *cfg, enum can_state *state,
|
|||
}
|
||||
|
||||
#ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
|
||||
int can_mcan_recover(const struct can_mcan_config *cfg, k_timeout_t timeout)
|
||||
int can_mcan_recover(const struct device *dev, k_timeout_t timeout)
|
||||
{
|
||||
const struct can_mcan_config *cfg = dev->config;
|
||||
struct can_mcan_reg *can = cfg->can;
|
||||
|
||||
return can_leave_init_mode(can, timeout);
|
||||
|
@ -732,14 +741,15 @@ int can_mcan_recover(const struct can_mcan_config *cfg, k_timeout_t timeout)
|
|||
#endif /* CONFIG_CAN_AUTO_BUS_OFF_RECOVERY */
|
||||
|
||||
|
||||
int can_mcan_send(const struct can_mcan_config *cfg,
|
||||
struct can_mcan_data *data,
|
||||
struct can_mcan_msg_sram *msg_ram,
|
||||
int can_mcan_send(const struct device *dev,
|
||||
const struct zcan_frame *frame,
|
||||
k_timeout_t timeout,
|
||||
can_tx_callback_t callback, void *user_data)
|
||||
{
|
||||
struct can_mcan_reg *can = cfg->can;
|
||||
const struct can_mcan_config *cfg = dev->config;
|
||||
struct can_mcan_data *data = dev->data;
|
||||
struct can_mcan_reg *can = cfg->can;
|
||||
struct can_mcan_msg_sram *msg_ram = data->msg_ram;
|
||||
size_t data_length = can_dlc_to_bytes(frame->dlc);
|
||||
struct can_mcan_tx_buffer_hdr tx_hdr = {
|
||||
.rtr = frame->rtr == CAN_REMOTEREQUEST,
|
||||
|
@ -850,11 +860,12 @@ int can_mcan_get_max_filters(const struct device *dev, enum can_ide id_type)
|
|||
* Dual mode gets tricky, because we can only activate both filters.
|
||||
* If one of the IDs is not used anymore, we would need to mark it as unused.
|
||||
*/
|
||||
int can_mcan_add_rx_filter_std(struct can_mcan_data *data,
|
||||
struct can_mcan_msg_sram *msg_ram,
|
||||
int can_mcan_add_rx_filter_std(const struct device *dev,
|
||||
can_rx_callback_t callback, void *user_data,
|
||||
const struct zcan_filter *filter)
|
||||
{
|
||||
struct can_mcan_data *data = dev->data;
|
||||
struct can_mcan_msg_sram *msg_ram = data->msg_ram;
|
||||
struct can_mcan_std_filter filter_element = {
|
||||
.id1 = filter->id,
|
||||
.id2 = filter->id_mask,
|
||||
|
@ -912,11 +923,12 @@ static int can_mcan_get_free_ext(volatile struct can_mcan_ext_filter *filters)
|
|||
return -ENOSPC;
|
||||
}
|
||||
|
||||
static int can_mcan_add_rx_filter_ext(struct can_mcan_data *data,
|
||||
struct can_mcan_msg_sram *msg_ram,
|
||||
static int can_mcan_add_rx_filter_ext(const struct device *dev,
|
||||
can_rx_callback_t callback, void *user_data,
|
||||
const struct zcan_filter *filter)
|
||||
{
|
||||
struct can_mcan_data *data = dev->data;
|
||||
struct can_mcan_msg_sram *msg_ram = data->msg_ram;
|
||||
struct can_mcan_ext_filter filter_element = {
|
||||
.id2 = filter->id_mask,
|
||||
.id1 = filter->id,
|
||||
|
@ -963,8 +975,7 @@ static int can_mcan_add_rx_filter_ext(struct can_mcan_data *data,
|
|||
return filter_id;
|
||||
}
|
||||
|
||||
int can_mcan_add_rx_filter(struct can_mcan_data *data,
|
||||
struct can_mcan_msg_sram *msg_ram,
|
||||
int can_mcan_add_rx_filter(const struct device *dev,
|
||||
can_rx_callback_t callback, void *user_data,
|
||||
const struct zcan_filter *filter)
|
||||
{
|
||||
|
@ -975,11 +986,9 @@ int can_mcan_add_rx_filter(struct can_mcan_data *data,
|
|||
}
|
||||
|
||||
if (filter->id_type == CAN_STANDARD_IDENTIFIER) {
|
||||
filter_id = can_mcan_add_rx_filter_std(data, msg_ram, callback,
|
||||
user_data, filter);
|
||||
filter_id = can_mcan_add_rx_filter_std(dev, callback, user_data, filter);
|
||||
} else {
|
||||
filter_id = can_mcan_add_rx_filter_ext(data, msg_ram, callback,
|
||||
user_data, filter);
|
||||
filter_id = can_mcan_add_rx_filter_ext(dev, callback, user_data, filter);
|
||||
if (filter_id >= 0) {
|
||||
filter_id += NUM_STD_FILTER_DATA;
|
||||
}
|
||||
|
@ -988,9 +997,11 @@ int can_mcan_add_rx_filter(struct can_mcan_data *data,
|
|||
return filter_id;
|
||||
}
|
||||
|
||||
void can_mcan_remove_rx_filter(struct can_mcan_data *data,
|
||||
struct can_mcan_msg_sram *msg_ram, int filter_id)
|
||||
void can_mcan_remove_rx_filter(const struct device *dev, int filter_id)
|
||||
{
|
||||
struct can_mcan_data *data = dev->data;
|
||||
struct can_mcan_msg_sram *msg_ram = data->msg_ram;
|
||||
|
||||
k_mutex_lock(&data->inst_mutex, K_FOREVER);
|
||||
if (filter_id >= NUM_STD_FILTER_DATA) {
|
||||
filter_id -= NUM_STD_FILTER_DATA;
|
||||
|
@ -1012,3 +1023,22 @@ void can_mcan_remove_rx_filter(struct can_mcan_data *data,
|
|||
|
||||
k_mutex_unlock(&data->inst_mutex);
|
||||
}
|
||||
|
||||
void can_mcan_set_state_change_callback(const struct device *dev,
|
||||
can_state_change_callback_t callback,
|
||||
void *user_data)
|
||||
{
|
||||
struct can_mcan_data *data = dev->data;
|
||||
|
||||
data->state_change_cb = callback;
|
||||
data->state_change_cb_data = user_data;
|
||||
}
|
||||
|
||||
int can_mcan_get_max_bitrate(const struct device *dev, uint32_t *max_bitrate)
|
||||
{
|
||||
const struct can_mcan_config *cfg = dev->config;
|
||||
|
||||
*max_bitrate = cfg->max_bitrate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue