linux/drivers/net/can/spi/mcp251x.c

// SPDX-License-Identifier: GPL-2.0-only
/* CAN bus driver for Microchip 251x/25625 CAN Controller with SPI Interface
 *
 * MCP2510 support and bug fixes by Christian Pellegrin
 * <[email protected]>
 *
 * Copyright 2009 Christian Pellegrin EVOL S.r.l.
 *
 * Copyright 2007 Raymarine UK, Ltd. All Rights Reserved.
 * Written under contract by:
 *   Chris Elston, Katalix Systems, Ltd.
 *
 * Based on Microchip MCP251x CAN controller driver written by
 * David Vrabel, Copyright 2006 Arcom Control Systems Ltd.
 *
 * Based on CAN bus driver for the CCAN controller written by
 * - Sascha Hauer, Marc Kleine-Budde, Pengutronix
 * - Simon Kallweit, intefo AG
 * Copyright 2007
 */

#include <linux/bitfield.h>
#include <linux/can/core.h>
#include <linux/can/dev.h>
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/ethtool.h>
#include <linux/freezer.h>
#include <linux/gpio/driver.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/spi/spi.h>
#include <linux/uaccess.h>

/* SPI interface instruction set */
#define INSTRUCTION_WRITE
#define INSTRUCTION_READ
#define INSTRUCTION_BIT_MODIFY
#define INSTRUCTION_LOAD_TXB(n)
#define INSTRUCTION_READ_RXB(n)
#define INSTRUCTION_RESET
#define RTS_TXB0
#define RTS_TXB1
#define RTS_TXB2
#define INSTRUCTION_RTS(n)

/* MPC251x registers */
#define BFPCTRL
#define BFPCTRL_B0BFM
#define BFPCTRL_B1BFM
#define BFPCTRL_BFM(n)
#define BFPCTRL_BFM_MASK
#define BFPCTRL_B0BFE
#define BFPCTRL_B1BFE
#define BFPCTRL_BFE(n)
#define BFPCTRL_BFE_MASK
#define BFPCTRL_B0BFS
#define BFPCTRL_B1BFS
#define BFPCTRL_BFS(n)
#define BFPCTRL_BFS_MASK
#define TXRTSCTRL
#define TXRTSCTRL_B0RTSM
#define TXRTSCTRL_B1RTSM
#define TXRTSCTRL_B2RTSM
#define TXRTSCTRL_RTSM(n)
#define TXRTSCTRL_RTSM_MASK
#define TXRTSCTRL_B0RTS
#define TXRTSCTRL_B1RTS
#define TXRTSCTRL_B2RTS
#define TXRTSCTRL_RTS(n)
#define TXRTSCTRL_RTS_MASK
#define CANSTAT
#define CANCTRL
#define CANCTRL_REQOP_MASK
#define CANCTRL_REQOP_CONF
#define CANCTRL_REQOP_LISTEN_ONLY
#define CANCTRL_REQOP_LOOPBACK
#define CANCTRL_REQOP_SLEEP
#define CANCTRL_REQOP_NORMAL
#define CANCTRL_OSM
#define CANCTRL_ABAT
#define TEC
#define REC
#define CNF1
#define CNF1_SJW_SHIFT
#define CNF2
#define CNF2_BTLMODE
#define CNF2_SAM
#define CNF2_PS1_SHIFT
#define CNF3
#define CNF3_SOF
#define CNF3_WAKFIL
#define CNF3_PHSEG2_MASK
#define CANINTE
#define CANINTE_MERRE
#define CANINTE_WAKIE
#define CANINTE_ERRIE
#define CANINTE_TX2IE
#define CANINTE_TX1IE
#define CANINTE_TX0IE
#define CANINTE_RX1IE
#define CANINTE_RX0IE
#define CANINTF
#define CANINTF_MERRF
#define CANINTF_WAKIF
#define CANINTF_ERRIF
#define CANINTF_TX2IF
#define CANINTF_TX1IF
#define CANINTF_TX0IF
#define CANINTF_RX1IF
#define CANINTF_RX0IF
#define CANINTF_RX
#define CANINTF_TX
#define CANINTF_ERR
#define EFLG
#define EFLG_EWARN
#define EFLG_RXWAR
#define EFLG_TXWAR
#define EFLG_RXEP
#define EFLG_TXEP
#define EFLG_TXBO
#define EFLG_RX0OVR
#define EFLG_RX1OVR
#define TXBCTRL(n)
#define TXBCTRL_ABTF
#define TXBCTRL_MLOA
#define TXBCTRL_TXERR
#define TXBCTRL_TXREQ
#define TXBSIDH(n)
#define SIDH_SHIFT
#define TXBSIDL(n)
#define SIDL_SID_MASK
#define SIDL_SID_SHIFT
#define SIDL_EXIDE_SHIFT
#define SIDL_EID_SHIFT
#define SIDL_EID_MASK
#define TXBEID8(n)
#define TXBEID0(n)
#define TXBDLC(n)
#define DLC_RTR_SHIFT
#define TXBCTRL_OFF
#define TXBSIDH_OFF
#define TXBSIDL_OFF
#define TXBEID8_OFF
#define TXBEID0_OFF
#define TXBDLC_OFF
#define TXBDAT_OFF
#define RXBCTRL(n)
#define RXBCTRL_BUKT
#define RXBCTRL_RXM0
#define RXBCTRL_RXM1
#define RXBSIDH(n)
#define RXBSIDH_SHIFT
#define RXBSIDL(n)
#define RXBSIDL_IDE
#define RXBSIDL_SRR
#define RXBSIDL_EID
#define RXBSIDL_SHIFT
#define RXBEID8(n)
#define RXBEID0(n)
#define RXBDLC(n)
#define RXBDLC_LEN_MASK
#define RXBDLC_RTR
#define RXBCTRL_OFF
#define RXBSIDH_OFF
#define RXBSIDL_OFF
#define RXBEID8_OFF
#define RXBEID0_OFF
#define RXBDLC_OFF
#define RXBDAT_OFF
#define RXFSID(n)
#define RXFSIDH(n)
#define RXFSIDL(n)
#define RXFEID8(n)
#define RXFEID0(n)
#define RXMSIDH(n)
#define RXMSIDL(n)
#define RXMEID8(n)
#define RXMEID0(n)

#define GET_BYTE(val, byte)
#define SET_BYTE(val, byte)

/* Buffer size required for the largest SPI transfer (i.e., reading a
 * frame)
 */
#define CAN_FRAME_MAX_DATA_LEN
#define SPI_TRANSFER_BUF_LEN
#define CAN_FRAME_MAX_BITS

#define TX_ECHO_SKB_MAX

#define MCP251X_OST_DELAY_MS

#define DEVICE_NAME

static const struct can_bittiming_const mcp251x_bittiming_const =;

enum mcp251x_model {};

struct mcp251x_priv {};

#define MCP251X_IS(_model)

MCP251X_IS(2510);

static void mcp251x_clean(struct net_device *net)
{}

/* Note about handling of error return of mcp251x_spi_trans: accessing
 * registers via SPI is not really different conceptually than using
 * normal I/O assembler instructions, although it's much more
 * complicated from a practical POV. So it's not advisable to always
 * check the return value of this function. Imagine that every
 * read{b,l}, write{b,l} and friends would be bracketed in "if ( < 0)
 * error();", it would be a great mess (well there are some situation
 * when exception handling C++ like could be useful after all). So we
 * just check that transfers are OK at the beginning of our
 * conversation with the chip and to avoid doing really nasty things
 * (like injecting bogus packets in the network stack).
 */
static int mcp251x_spi_trans(struct spi_device *spi, int len)
{}

static int mcp251x_spi_write(struct spi_device *spi, int len)
{}

static u8 mcp251x_read_reg(struct spi_device *spi, u8 reg)
{}

static void mcp251x_read_2regs(struct spi_device *spi, u8 reg, u8 *v1, u8 *v2)
{}

static void mcp251x_write_reg(struct spi_device *spi, u8 reg, u8 val)
{}

static void mcp251x_write_2regs(struct spi_device *spi, u8 reg, u8 v1, u8 v2)
{}

static void mcp251x_write_bits(struct spi_device *spi, u8 reg,
			       u8 mask, u8 val)
{}

static u8 mcp251x_read_stat(struct spi_device *spi)
{}

#define mcp251x_read_stat_poll_timeout(addr, val, cond, delay_us, timeout_us)

#ifdef CONFIG_GPIOLIB
enum {};

#define MCP251X_GPIO_INPUT_MASK
#define MCP251X_GPIO_OUTPUT_MASK

static const char * const mcp251x_gpio_names[] =;

static inline bool mcp251x_gpio_is_input(unsigned int offset)
{}

static int mcp251x_gpio_request(struct gpio_chip *chip,
				unsigned int offset)
{}

static void mcp251x_gpio_free(struct gpio_chip *chip,
			      unsigned int offset)
{}

static int mcp251x_gpio_get_direction(struct gpio_chip *chip,
				      unsigned int offset)
{}

static int mcp251x_gpio_get(struct gpio_chip *chip, unsigned int offset)
{}

static int mcp251x_gpio_get_multiple(struct gpio_chip *chip,
				     unsigned long *maskp, unsigned long *bitsp)
{}

static void mcp251x_gpio_set(struct gpio_chip *chip, unsigned int offset,
			     int value)
{}

static void
mcp251x_gpio_set_multiple(struct gpio_chip *chip,
			  unsigned long *maskp, unsigned long *bitsp)
{}

static void mcp251x_gpio_restore(struct spi_device *spi)
{}

static int mcp251x_gpio_setup(struct mcp251x_priv *priv)
{}
#else
static inline void mcp251x_gpio_restore(struct spi_device *spi)
{
}

static inline int mcp251x_gpio_setup(struct mcp251x_priv *priv)
{
	return 0;
}
#endif

static void mcp251x_hw_tx_frame(struct spi_device *spi, u8 *buf,
				int len, int tx_buf_idx)
{}

static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame,
			  int tx_buf_idx)
{}

static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf,
				int buf_idx)
{}

static void mcp251x_hw_rx(struct spi_device *spi, int buf_idx)
{}

static void mcp251x_hw_sleep(struct spi_device *spi)
{}

/* May only be called when device is sleeping! */
static int mcp251x_hw_wake(struct spi_device *spi)
{}

static netdev_tx_t mcp251x_hard_start_xmit(struct sk_buff *skb,
					   struct net_device *net)
{}

static int mcp251x_do_set_mode(struct net_device *net, enum can_mode mode)
{}

static int mcp251x_set_normal_mode(struct spi_device *spi)
{}

static int mcp251x_do_set_bittiming(struct net_device *net)
{}

static int mcp251x_setup(struct net_device *net, struct spi_device *spi)
{}

static int mcp251x_hw_reset(struct spi_device *spi)
{}

static int mcp251x_hw_probe(struct spi_device *spi)
{}

static int mcp251x_power_enable(struct regulator *reg, int enable)
{}

static int mcp251x_stop(struct net_device *net)
{}

static void mcp251x_error_skb(struct net_device *net, int can_id, int data1)
{}

static void mcp251x_tx_work_handler(struct work_struct *ws)
{}

static void mcp251x_restart_work_handler(struct work_struct *ws)
{}

static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)
{}

static int mcp251x_open(struct net_device *net)
{}

static const struct net_device_ops mcp251x_netdev_ops =;

static const struct ethtool_ops mcp251x_ethtool_ops =;

static const struct of_device_id mcp251x_of_match[] =;
MODULE_DEVICE_TABLE(of, mcp251x_of_match);

static const struct spi_device_id mcp251x_id_table[] =;
MODULE_DEVICE_TABLE(spi, mcp251x_id_table);

static int mcp251x_can_probe(struct spi_device *spi)
{}

static void mcp251x_can_remove(struct spi_device *spi)
{}

static int __maybe_unused mcp251x_can_suspend(struct device *dev)
{}

static int __maybe_unused mcp251x_can_resume(struct device *dev)
{}

static SIMPLE_DEV_PM_OPS(mcp251x_can_pm_ops, mcp251x_can_suspend,
	mcp251x_can_resume);

static struct spi_driver mcp251x_can_driver =;
module_spi_driver();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();