/*
 * Copyright (c) 2022 Henrik Brix Andersen <henrik@brixandersen.dk>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/drivers/can/can_sja1000.h>
#include "can_sja1000_priv.h"

#include <zephyr/drivers/can.h>
#include <zephyr/drivers/can/transceiver.h>
#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(can_sja1000, CONFIG_CAN_LOG_LEVEL);

/* Timeout for entering/leaving reset mode */
#define CAN_SJA1000_RESET_MODE_TIMEOUT_USEC 1000
#define CAN_SJA1000_RESET_MODE_RETRIES      100
#define CAN_SJA1000_RESET_MODE_DELAY	    \
	K_USEC(CAN_SJA1000_RESET_MODE_TIMEOUT_USEC / CAN_SJA1000_RESET_MODE_RETRIES)

static inline void can_sja1000_write_reg(const struct device *dev, uint8_t reg, uint8_t val)
{
	const struct can_sja1000_config *config = dev->config;

	return config->write_reg(dev, reg, val);
}

static inline uint8_t can_sja1000_read_reg(const struct device *dev, uint8_t reg)
{
	const struct can_sja1000_config *config = dev->config;

	return config->read_reg(dev, reg);
}

static inline int can_sja1000_enter_reset_mode(const struct device *dev)
{
	int retries = CAN_SJA1000_RESET_MODE_RETRIES;
	uint8_t mod;

	mod = can_sja1000_read_reg(dev, CAN_SJA1000_MOD);

	while ((mod & CAN_SJA1000_MOD_RM) == 0) {
		if (--retries < 0) {
			return -EIO;
		}

		can_sja1000_write_reg(dev, CAN_SJA1000_MOD, mod | CAN_SJA1000_MOD_RM);
		k_sleep(CAN_SJA1000_RESET_MODE_DELAY);
		mod = can_sja1000_read_reg(dev, CAN_SJA1000_MOD);
	};

	return 0;
}

static inline void can_sja1000_leave_reset_mode_nowait(const struct device *dev)
{
	uint8_t mod;

	mod = can_sja1000_read_reg(dev, CAN_SJA1000_MOD);
	can_sja1000_write_reg(dev, CAN_SJA1000_MOD, mod & ~(CAN_SJA1000_MOD_RM));
}

static inline int can_sja1000_leave_reset_mode(const struct device *dev)
{
	int retries = CAN_SJA1000_RESET_MODE_RETRIES;
	uint8_t mod;

	mod = can_sja1000_read_reg(dev, CAN_SJA1000_MOD);

	while ((mod & CAN_SJA1000_MOD_RM) == 1) {
		if (--retries < 0) {
			return -EIO;
		}

		can_sja1000_write_reg(dev, CAN_SJA1000_MOD, mod & ~(CAN_SJA1000_MOD_RM));
		k_sleep(CAN_SJA1000_RESET_MODE_DELAY);
		mod = can_sja1000_read_reg(dev, CAN_SJA1000_MOD);
	};

	return 0;
}

static inline void can_sja1000_clear_errors(const struct device *dev)
{
	/* Clear error counters */
	can_sja1000_write_reg(dev, CAN_SJA1000_RXERR, 0);
	can_sja1000_write_reg(dev, CAN_SJA1000_TXERR, 0);

	/* Clear error capture */
	(void)can_sja1000_read_reg(dev, CAN_SJA1000_ECC);
}

static void can_sja1000_tx_done(const struct device *dev, int status)
{
	struct can_sja1000_data *data = dev->data;
	can_tx_callback_t callback = data->tx_callback;
	void *user_data = data->tx_user_data;

	if (callback != NULL) {
		data->tx_callback = NULL;
		callback(dev, status, user_data);
	}

	k_sem_give(&data->tx_idle);
}

int can_sja1000_set_timing(const struct device *dev, const struct can_timing *timing)
{
	struct can_sja1000_data *data = dev->data;
	uint8_t btr0;
	uint8_t btr1;

	if (data->common.started) {
		return -EBUSY;
	}

	k_mutex_lock(&data->mod_lock, K_FOREVER);

	btr0 = CAN_SJA1000_BTR0_BRP_PREP(timing->prescaler - 1) |
	       CAN_SJA1000_BTR0_SJW_PREP(timing->sjw - 1);
	btr1 = CAN_SJA1000_BTR1_TSEG1_PREP(timing->phase_seg1 - 1) |
	       CAN_SJA1000_BTR1_TSEG2_PREP(timing->phase_seg2 - 1);

	if ((data->common.mode & CAN_MODE_3_SAMPLES) != 0) {
		btr1 |= CAN_SJA1000_BTR1_SAM;
	}

	can_sja1000_write_reg(dev, CAN_SJA1000_BTR0, btr0);
	can_sja1000_write_reg(dev, CAN_SJA1000_BTR1, btr1);

	k_mutex_unlock(&data->mod_lock);

	return 0;
}

int can_sja1000_get_capabilities(const struct device *dev, can_mode_t *cap)
{
	ARG_UNUSED(dev);

	*cap = CAN_MODE_NORMAL | CAN_MODE_LOOPBACK | CAN_MODE_LISTENONLY |
	       CAN_MODE_ONE_SHOT | CAN_MODE_3_SAMPLES;

	if (IS_ENABLED(CONFIG_CAN_MANUAL_RECOVERY_MODE)) {
		*cap |= CAN_MODE_MANUAL_RECOVERY;
	}

	return 0;
}

int can_sja1000_start(const struct device *dev)
{
	const struct can_sja1000_config *config = dev->config;
	struct can_sja1000_data *data = dev->data;
	int err;

	if (data->common.started) {
		return -EALREADY;
	}

	if (config->common.phy != NULL) {
		err = can_transceiver_enable(config->common.phy, data->common.mode);
		if (err != 0) {
			LOG_ERR("failed to enable CAN transceiver (err %d)", err);
			return err;
		}
	}

	can_sja1000_clear_errors(dev);
	CAN_STATS_RESET(dev);

	err = can_sja1000_leave_reset_mode(dev);
	if (err != 0) {
		if (config->common.phy != NULL) {
			/* Attempt to disable the CAN transceiver in case of error */
			(void)can_transceiver_disable(config->common.phy);
		}

		return err;
	}

	data->common.started = true;

	return 0;
}

int can_sja1000_stop(const struct device *dev)
{
	const struct can_sja1000_config *config = dev->config;
	struct can_sja1000_data *data = dev->data;
	int err;

	if (!data->common.started) {
		return -EALREADY;
	}

	/* Entering reset mode aborts current transmission, if any */
	err = can_sja1000_enter_reset_mode(dev);
	if (err != 0) {
		return err;
	}

	if (config->common.phy != NULL) {
		err = can_transceiver_disable(config->common.phy);
		if (err != 0) {
			LOG_ERR("failed to disable CAN transceiver (err %d)", err);
			return err;
		}
	}

	data->common.started = false;

	can_sja1000_tx_done(dev, -ENETDOWN);

	return 0;
}

int can_sja1000_set_mode(const struct device *dev, can_mode_t mode)
{
	can_mode_t supported = CAN_MODE_LOOPBACK | CAN_MODE_LISTENONLY | CAN_MODE_ONE_SHOT |
		CAN_MODE_3_SAMPLES;
	struct can_sja1000_data *data = dev->data;
	uint8_t btr1;
	uint8_t mod;

	if (IS_ENABLED(CONFIG_CAN_MANUAL_RECOVERY_MODE)) {
		supported |= CAN_MODE_MANUAL_RECOVERY;
	}

	if ((mode & ~(supported)) != 0) {
		LOG_ERR("unsupported mode: 0x%08x", mode);
		return -ENOTSUP;
	}

	if (data->common.started) {
		return -EBUSY;
	}

	k_mutex_lock(&data->mod_lock, K_FOREVER);

	mod = can_sja1000_read_reg(dev, CAN_SJA1000_MOD);
	mod |= CAN_SJA1000_MOD_AFM;

	if ((mode & CAN_MODE_LOOPBACK) != 0) {
		/* (Local) self test mode */
		mod |= CAN_SJA1000_MOD_STM;
	} else {
		mod &= ~(CAN_SJA1000_MOD_STM);
	}

	if ((mode & CAN_MODE_LISTENONLY) != 0) {
		mod |= CAN_SJA1000_MOD_LOM;
	} else {
		mod &= ~(CAN_SJA1000_MOD_LOM);
	}

	btr1 = can_sja1000_read_reg(dev, CAN_SJA1000_BTR1);
	if ((mode & CAN_MODE_3_SAMPLES) != 0) {
		btr1 |= CAN_SJA1000_BTR1_SAM;
	} else {
		btr1 &= ~(CAN_SJA1000_BTR1_SAM);
	}

	can_sja1000_write_reg(dev, CAN_SJA1000_MOD, mod);
	can_sja1000_write_reg(dev, CAN_SJA1000_BTR1, btr1);

	data->common.mode = mode;

	k_mutex_unlock(&data->mod_lock);

	return 0;
}

static void can_sja1000_read_frame(const struct device *dev, struct can_frame *frame)
{
	uint8_t info;
	int i;

	memset(frame, 0, sizeof(*frame));

	info = can_sja1000_read_reg(dev, CAN_SJA1000_FRAME_INFO);

	if ((info & CAN_SJA1000_FRAME_INFO_RTR) != 0) {
		frame->flags |= CAN_FRAME_RTR;
	}

	frame->dlc = CAN_SJA1000_FRAME_INFO_DLC_GET(info);
	if (frame->dlc > CAN_MAX_DLC) {
		LOG_ERR("RX frame DLC %u exceeds maximum (%d)", frame->dlc, CAN_MAX_DLC);
		return;
	}

	if ((info & CAN_SJA1000_FRAME_INFO_FF) != 0) {
		frame->flags |= CAN_FRAME_IDE;

		frame->id = FIELD_PREP(GENMASK(28, 21),
				can_sja1000_read_reg(dev, CAN_SJA1000_XFF_ID1));
		frame->id |= FIELD_PREP(GENMASK(20, 13),
				can_sja1000_read_reg(dev, CAN_SJA1000_XFF_ID2));
		frame->id |= FIELD_PREP(GENMASK(12, 5),
				can_sja1000_read_reg(dev, CAN_SJA1000_EFF_ID3));
		frame->id |= FIELD_PREP(GENMASK(4, 0),
				can_sja1000_read_reg(dev, CAN_SJA1000_EFF_ID4) >> 3);

		if ((frame->flags & CAN_FRAME_RTR) == 0U) {
			for (i = 0; i < frame->dlc; i++) {
				frame->data[i] = can_sja1000_read_reg(dev, CAN_SJA1000_EFF_DATA +
								      i);
			}
		}
	} else {
		frame->id = FIELD_PREP(GENMASK(10, 3),
				can_sja1000_read_reg(dev, CAN_SJA1000_XFF_ID1));
		frame->id |= FIELD_PREP(GENMASK(2, 0),
				can_sja1000_read_reg(dev, CAN_SJA1000_XFF_ID2) >> 5);

		if ((frame->flags & CAN_FRAME_RTR) == 0U) {
			for (i = 0; i < frame->dlc; i++) {
				frame->data[i] = can_sja1000_read_reg(dev, CAN_SJA1000_SFF_DATA +
								      i);
			}
		}
	}
}

void can_sja1000_write_frame(const struct device *dev, const struct can_frame *frame)
{
	uint8_t info;
	int i;

	info = CAN_SJA1000_FRAME_INFO_DLC_PREP(frame->dlc);

	if ((frame->flags & CAN_FRAME_RTR) != 0) {
		info |= CAN_SJA1000_FRAME_INFO_RTR;
	}

	if ((frame->flags & CAN_FRAME_IDE) != 0) {
		info |= CAN_SJA1000_FRAME_INFO_FF;
	}

	can_sja1000_write_reg(dev, CAN_SJA1000_FRAME_INFO, info);

	if ((frame->flags & CAN_FRAME_IDE) != 0) {
		can_sja1000_write_reg(dev, CAN_SJA1000_XFF_ID1,
				FIELD_GET(GENMASK(28, 21), frame->id));
		can_sja1000_write_reg(dev, CAN_SJA1000_XFF_ID2,
				FIELD_GET(GENMASK(20, 13), frame->id));
		can_sja1000_write_reg(dev, CAN_SJA1000_EFF_ID3,
				FIELD_GET(GENMASK(12, 5), frame->id));
		can_sja1000_write_reg(dev, CAN_SJA1000_EFF_ID4,
				FIELD_GET(GENMASK(4, 0), frame->id) << 3);

		if ((frame->flags & CAN_FRAME_RTR) == 0U) {
			for (i = 0; i < frame->dlc; i++) {
				can_sja1000_write_reg(dev, CAN_SJA1000_EFF_DATA + i,
						      frame->data[i]);
			}
		}
	} else {
		can_sja1000_write_reg(dev, CAN_SJA1000_XFF_ID1,
				FIELD_GET(GENMASK(10, 3), frame->id));
		can_sja1000_write_reg(dev, CAN_SJA1000_XFF_ID2,
				FIELD_GET(GENMASK(2, 0), frame->id) << 5);

		if ((frame->flags & CAN_FRAME_RTR) == 0U) {
			for (i = 0; i < frame->dlc; i++) {
				can_sja1000_write_reg(dev, CAN_SJA1000_SFF_DATA + i,
						      frame->data[i]);
			}
		}
	}
}

int can_sja1000_send(const struct device *dev, const struct can_frame *frame, k_timeout_t timeout,
		     can_tx_callback_t callback, void *user_data)
{
	struct can_sja1000_data *data = dev->data;
	uint8_t cmr;
	uint8_t sr;

	if (frame->dlc > CAN_MAX_DLC) {
		LOG_ERR("TX frame DLC %u exceeds maximum (%d)", frame->dlc, CAN_MAX_DLC);
		return -EINVAL;
	}

	if ((frame->flags & ~(CAN_FRAME_IDE | CAN_FRAME_RTR)) != 0) {
		LOG_ERR("unsupported CAN frame flags 0x%02x", frame->flags);
		return -ENOTSUP;
	}

	if (!data->common.started) {
		return -ENETDOWN;
	}

	if (data->state == CAN_STATE_BUS_OFF) {
		LOG_DBG("transmit failed, bus-off");
		return -ENETUNREACH;
	}

	if (k_sem_take(&data->tx_idle, timeout) != 0) {
		return -EAGAIN;
	}

	sr = can_sja1000_read_reg(dev, CAN_SJA1000_SR);
	if ((sr & CAN_SJA1000_SR_TBS) == 0) {
		LOG_ERR("transmit buffer locked, sr = 0x%02x", sr);
		return -EIO;
	}

	data->tx_callback = callback;
	data->tx_user_data = user_data;

	can_sja1000_write_frame(dev, frame);

	if ((data->common.mode & CAN_MODE_LOOPBACK) != 0) {
		cmr = CAN_SJA1000_CMR_SRR;
	} else {
		cmr = CAN_SJA1000_CMR_TR;
	}

	if ((data->common.mode & CAN_MODE_ONE_SHOT) != 0) {
		cmr |= CAN_SJA1000_CMR_AT;
	}

	can_sja1000_write_reg(dev, CAN_SJA1000_CMR, cmr);

	return 0;
}

int can_sja1000_add_rx_filter(const struct device *dev, can_rx_callback_t callback, void *user_data,
			      const struct can_filter *filter)
{
	struct can_sja1000_data *data = dev->data;
	int filter_id = -ENOSPC;
	int i;

	if ((filter->flags & ~(CAN_FILTER_IDE)) != 0) {
		LOG_ERR("unsupported CAN filter flags 0x%02x", filter->flags);
		return -ENOTSUP;
	}

	for (i = 0; i < ARRAY_SIZE(data->filters); i++) {
		if (!atomic_test_and_set_bit(data->rx_allocs, i)) {
			filter_id = i;
			break;
		}
	}

	if (filter_id >= 0) {
		data->filters[filter_id].filter = *filter;
		data->filters[filter_id].user_data = user_data;
		data->filters[filter_id].callback = callback;
	}

	return filter_id;
}

void can_sja1000_remove_rx_filter(const struct device *dev, int filter_id)
{
	struct can_sja1000_data *data = dev->data;

	if (filter_id < 0 || filter_id >= ARRAY_SIZE(data->filters)) {
		LOG_ERR("filter ID %d out of bounds", filter_id);
		return;
	}

	if (atomic_test_and_clear_bit(data->rx_allocs, filter_id)) {
		data->filters[filter_id].callback = NULL;
		data->filters[filter_id].user_data = NULL;
		data->filters[filter_id].filter = (struct can_filter){0};
	}
}

#ifdef CONFIG_CAN_MANUAL_RECOVERY_MODE
int can_sja1000_recover(const struct device *dev, k_timeout_t timeout)
{
	struct can_sja1000_data *data = dev->data;
	int64_t start_ticks;
	uint8_t sr;
	int err;

	if (!data->common.started) {
		return -ENETDOWN;
	}

	if ((data->common.mode & CAN_MODE_MANUAL_RECOVERY) == 0U) {
		return -ENOTSUP;
	}

	sr = can_sja1000_read_reg(dev, CAN_SJA1000_SR);
	if ((sr & CAN_SJA1000_SR_BS) == 0) {
		return 0;
	}

	start_ticks = k_uptime_ticks();

	err = k_mutex_lock(&data->mod_lock, timeout);
	if (err != 0) {
		LOG_WRN("failed to acquire MOD lock");
		return err;
	}

	err = can_sja1000_leave_reset_mode(dev);
	if (err != 0) {
		LOG_ERR("failed to initiate bus recovery");
		k_mutex_unlock(&data->mod_lock);
		return err;
	}

	k_mutex_unlock(&data->mod_lock);

	while ((sr & CAN_SJA1000_SR_BS) != 0) {
		if (k_uptime_ticks() - start_ticks > timeout.ticks) {
			LOG_WRN("bus recovery timed out");
			return -EAGAIN;
		}

		sr = can_sja1000_read_reg(dev, CAN_SJA1000_SR);
	}

	return 0;
}
#endif /* CONFIG_CAN_MANUAL_RECOVERY_MODE */

int can_sja1000_get_state(const struct device *dev, enum can_state *state,
			  struct can_bus_err_cnt *err_cnt)
{
	struct can_sja1000_data *data = dev->data;

	if (state != NULL) {
		if (!data->common.started) {
			*state = CAN_STATE_STOPPED;
		} else {
			*state = data->state;
		}
	}

	if (err_cnt != NULL) {
		err_cnt->rx_err_cnt = can_sja1000_read_reg(dev, CAN_SJA1000_RXERR);
		err_cnt->tx_err_cnt = can_sja1000_read_reg(dev, CAN_SJA1000_TXERR);
	}

	return 0;
}

void can_sja1000_set_state_change_callback(const struct device *dev,
					   can_state_change_callback_t callback, void *user_data)
{
	struct can_sja1000_data *data = dev->data;

	data->common.state_change_cb = callback;
	data->common.state_change_cb_user_data = user_data;
}

int can_sja1000_get_max_filters(const struct device *dev, bool ide)
{
	ARG_UNUSED(dev);
	ARG_UNUSED(ide);

	return CONFIG_CAN_MAX_FILTER;
}

static void can_sja1000_handle_receive_irq(const struct device *dev)
{
	struct can_sja1000_data *data = dev->data;
	struct can_frame frame;
	can_rx_callback_t callback;
	uint8_t sr;
	int i;

	do {
		can_sja1000_read_frame(dev, &frame);

#ifndef CONFIG_CAN_ACCEPT_RTR
		if ((frame.flags & CAN_FRAME_RTR) == 0U) {
#endif /* !CONFIG_CAN_ACCEPT_RTR */
			for (i = 0; i < ARRAY_SIZE(data->filters); i++) {
				if (!atomic_test_bit(data->rx_allocs, i)) {
					continue;
				}

				if (can_frame_matches_filter(&frame, &data->filters[i].filter)) {
					callback = data->filters[i].callback;
					if (callback != NULL) {
						callback(dev, &frame, data->filters[i].user_data);
					}
				}
			}
#ifndef CONFIG_CAN_ACCEPT_RTR
		}
#endif /* !CONFIG_CAN_ACCEPT_RTR */

		can_sja1000_write_reg(dev, CAN_SJA1000_CMR, CAN_SJA1000_CMR_RRB);
		sr = can_sja1000_read_reg(dev, CAN_SJA1000_SR);
	} while ((sr & CAN_SJA1000_SR_RBS) != 0);
}

static void can_sja1000_handle_transmit_irq(const struct device *dev)
{
	int status = 0;
	uint8_t sr;

	sr = can_sja1000_read_reg(dev, CAN_SJA1000_SR);
	if ((sr & CAN_SJA1000_SR_TCS) == 0) {
		status = -EIO;
	}

	can_sja1000_tx_done(dev, status);
}

#ifdef CONFIG_CAN_STATS
static void can_sja1000_handle_data_overrun_irq(const struct device *dev)
{
	/* See NXP SJA1000 Application Note AN97076 (figure 18) for data overrun details */

	CAN_STATS_RX_OVERRUN_INC(dev);

	can_sja1000_write_reg(dev, CAN_SJA1000_CMR, CAN_SJA1000_CMR_CDO);
}

static void can_sja1000_handle_bus_error_irq(const struct device *dev)
{
	/* See NXP SJA1000 Application Note AN97076 (tables 6 and 7) for ECC details */
	uint8_t ecc;

	/* Read the Error Code Capture register to re-activate it */
	ecc = can_sja1000_read_reg(dev, CAN_SJA1000_ECC);

	if (ecc == (CAN_SJA1000_ECC_ERRC_OTHER_ERROR | CAN_SJA1000_ECC_DIR_TX |
		CAN_SJA1000_ECC_SEG_ACK_SLOT)) {
		/* Missing ACK is reported as a TX "other" error in the ACK slot */
		CAN_STATS_ACK_ERROR_INC(dev);
		return;
	}

	if (ecc == (CAN_SJA1000_ECC_ERRC_FORM_ERROR | CAN_SJA1000_ECC_DIR_RX |
		CAN_SJA1000_ECC_SEG_ACK_DELIM)) {
		/* CRC error is reported as a RX "form" error in the ACK delimiter */
		CAN_STATS_CRC_ERROR_INC(dev);
		return;
	}

	switch (ecc & CAN_SJA1000_ECC_ERRC_MASK) {
	case CAN_SJA1000_ECC_ERRC_BIT_ERROR:
		CAN_STATS_BIT_ERROR_INC(dev);
		break;

	case CAN_SJA1000_ECC_ERRC_FORM_ERROR:
		CAN_STATS_FORM_ERROR_INC(dev);
		break;
	case CAN_SJA1000_ECC_ERRC_STUFF_ERROR:
		CAN_STATS_STUFF_ERROR_INC(dev);
		break;

	case CAN_SJA1000_ECC_ERRC_OTHER_ERROR:
		__fallthrough;
	default:
		/* Other error not currently reported in CAN statistics */
		break;
	}
}
#endif /* CONFIG_CAN_STATS */

static void can_sja1000_handle_error_warning_irq(const struct device *dev)
{
	struct can_sja1000_data *data = dev->data;
	uint8_t sr;

	sr = can_sja1000_read_reg(dev, CAN_SJA1000_SR);
	if ((sr & CAN_SJA1000_SR_BS) != 0) {
		data->state = CAN_STATE_BUS_OFF;
		can_sja1000_tx_done(dev, -ENETUNREACH);

		if (data->common.started &&
			(data->common.mode & CAN_MODE_MANUAL_RECOVERY) == 0U) {
			can_sja1000_leave_reset_mode_nowait(dev);
		}
	} else if ((sr & CAN_SJA1000_SR_ES) != 0) {
		data->state = CAN_STATE_ERROR_WARNING;
	} else {
		data->state = CAN_STATE_ERROR_ACTIVE;
	}
}

static void can_sja1000_handle_error_passive_irq(const struct device *dev)
{
	struct can_sja1000_data *data = dev->data;

	if (data->state == CAN_STATE_ERROR_PASSIVE) {
		data->state = CAN_STATE_ERROR_WARNING;
	} else {
		data->state = CAN_STATE_ERROR_PASSIVE;
	}
}

void can_sja1000_isr(const struct device *dev)
{
	struct can_sja1000_data *data = dev->data;
	const can_state_change_callback_t cb = data->common.state_change_cb;
	void *cb_data = data->common.state_change_cb_user_data;
	enum can_state prev_state = data->state;
	struct can_bus_err_cnt err_cnt;
	uint8_t ir;

	ir = can_sja1000_read_reg(dev, CAN_SJA1000_IR);

	if ((ir & CAN_SJA1000_IR_TI) != 0) {
		can_sja1000_handle_transmit_irq(dev);
	}

	if ((ir & CAN_SJA1000_IR_RI) != 0) {
		can_sja1000_handle_receive_irq(dev);
	}

#ifdef CONFIG_CAN_STATS
	if ((ir & CAN_SJA1000_IR_DOI) != 0) {
		can_sja1000_handle_data_overrun_irq(dev);
	}

	if ((ir & CAN_SJA1000_IR_BEI) != 0) {
		can_sja1000_handle_bus_error_irq(dev);
	}
#endif /* CONFIG_CAN_STATS */

	if ((ir & CAN_SJA1000_IR_EI) != 0) {
		can_sja1000_handle_error_warning_irq(dev);
	}

	if ((ir & CAN_SJA1000_IR_EPI) != 0) {
		can_sja1000_handle_error_passive_irq(dev);
	}

	if (prev_state != data->state && cb != NULL) {
		err_cnt.rx_err_cnt = can_sja1000_read_reg(dev, CAN_SJA1000_RXERR);
		err_cnt.tx_err_cnt = can_sja1000_read_reg(dev, CAN_SJA1000_TXERR);
		cb(dev, data->state, err_cnt, cb_data);
	}
}

int can_sja1000_init(const struct device *dev)
{
	const struct can_sja1000_config *config = dev->config;
	struct can_sja1000_data *data = dev->data;
	struct can_timing timing = { 0 };
	int err;

	__ASSERT_NO_MSG(config->read_reg != NULL);
	__ASSERT_NO_MSG(config->write_reg != NULL);

	if (config->common.phy != NULL) {
		if (!device_is_ready(config->common.phy)) {
			LOG_ERR("CAN transceiver not ready");
			return -ENODEV;
		}
	}

	k_mutex_init(&data->mod_lock);
	k_sem_init(&data->tx_idle, 1, 1);

	data->state = CAN_STATE_ERROR_ACTIVE;

	/* See NXP SJA1000 Application Note AN97076 (figure 12) for initialization sequence */

	/* Enter reset mode */
	err = can_sja1000_enter_reset_mode(dev);
	if (err != 0) {
		return err;
	}

	/* Set PeliCAN mode */
	can_sja1000_write_reg(dev, CAN_SJA1000_CDR, config->cdr | CAN_SJA1000_CDR_CAN_MODE);

	/* Set up acceptance code and mask to match any frame (software filtering) */
	can_sja1000_write_reg(dev, CAN_SJA1000_ACR0, 0x00);
	can_sja1000_write_reg(dev, CAN_SJA1000_ACR1, 0x00);
	can_sja1000_write_reg(dev, CAN_SJA1000_ACR2, 0x00);
	can_sja1000_write_reg(dev, CAN_SJA1000_ACR3, 0x00);

	can_sja1000_write_reg(dev, CAN_SJA1000_AMR0, 0xFF);
	can_sja1000_write_reg(dev, CAN_SJA1000_AMR1, 0xFF);
	can_sja1000_write_reg(dev, CAN_SJA1000_AMR2, 0xFF);
	can_sja1000_write_reg(dev, CAN_SJA1000_AMR3, 0xFF);

	err = can_calc_timing(dev, &timing, config->common.bus_speed,
			      config->common.sample_point);
	if (err == -EINVAL) {
		LOG_ERR("bitrate/sample point cannot be met (err %d)", err);
		return err;
	}

	LOG_DBG("initial sample point error: %d", err);

	/* Configure timing */
	err = can_set_timing(dev, &timing);
	if (err != 0) {
		LOG_ERR("timing parameters cannot be met (err %d)", err);
		return err;
	}

	/* Set output control */
	can_sja1000_write_reg(dev, CAN_SJA1000_OCR, config->ocr);

	/* Clear error counters and error capture */
	can_sja1000_clear_errors(dev);

	/* Set error warning limit */
	can_sja1000_write_reg(dev, CAN_SJA1000_EWLR, 96);

	/* Set normal mode */
	data->common.mode = CAN_MODE_NORMAL;
	err = can_sja1000_set_mode(dev, CAN_MODE_NORMAL);
	if (err != 0) {
		return err;
	}

	/* Enable interrupts */
	can_sja1000_write_reg(dev, CAN_SJA1000_IER,
#ifdef CONFIG_CAN_STATS
			      CAN_SJA1000_IER_BEIE | CAN_SJA1000_IER_DOIE |
#endif /* CONFIG_CAN_STATS */
			      CAN_SJA1000_IER_RIE | CAN_SJA1000_IER_TIE |
			      CAN_SJA1000_IER_EIE | CAN_SJA1000_IER_EPIE);

	return 0;
}
