// SPDX-License-Identifier: GPL-2.0
/* Fintek F81604 USB-to-2CAN controller driver.
*
* Copyright (C) 2023 Ji-Ze Hong (Peter Hong) <peter_hong@fintek.com.tw>
*/
#include <linux/bitfield.h>
#include <linux/netdevice.h>
#include <linux/units.h>
#include <linux/usb.h>
#include <linux/can.h>
#include <linux/can/dev.h>
#include <linux/can/error.h>
#include <linux/can/platform/sja1000.h>
#include <linux/unaligned.h>
/* vendor and product id */
#define F81604_VENDOR_ID 0x2c42
#define F81604_PRODUCT_ID 0x1709
#define F81604_CAN_CLOCK (12 * MEGA)
#define F81604_MAX_DEV 2
#define F81604_SET_DEVICE_RETRY 10
#define F81604_USB_TIMEOUT 2000
#define F81604_SET_GET_REGISTER 0xA0
#define F81604_PORT_OFFSET 0x1000
#define F81604_MAX_RX_URBS 4
#define F81604_CMD_DATA 0x00
#define F81604_DLC_LEN_MASK GENMASK(3, 0)
#define F81604_DLC_EFF_BIT BIT(7)
#define F81604_DLC_RTR_BIT BIT(6)
#define F81604_SFF_SHIFT 5
#define F81604_EFF_SHIFT 3
#define F81604_BRP_MASK GENMASK(5, 0)
#define F81604_SJW_MASK GENMASK(7, 6)
#define F81604_SEG1_MASK GENMASK(3, 0)
#define F81604_SEG2_MASK GENMASK(6, 4)
#define F81604_CLEAR_ALC 0
#define F81604_CLEAR_ECC 1
#define F81604_CLEAR_OVERRUN 2
/* device setting */
#define F81604_CTRL_MODE_REG 0x80
#define F81604_TX_ONESHOT (0x03 << 3)
#define F81604_TX_NORMAL (0x01 << 3)
#define F81604_RX_AUTO_RELEASE_BUF BIT(1)
#define F81604_INT_WHEN_CHANGE BIT(0)
#define F81604_TERMINATOR_REG 0x105
#define F81604_CAN0_TERM BIT(2)
#define F81604_CAN1_TERM BIT(3)
#define F81604_TERMINATION_DISABLED CAN_TERMINATION_DISABLED
#define F81604_TERMINATION_ENABLED 120
/* SJA1000 registers - manual section 6.4 (Pelican Mode) */
#define F81604_SJA1000_MOD 0x00
#define F81604_SJA1000_CMR 0x01
#define F81604_SJA1000_IR 0x03
#define F81604_SJA1000_IER 0x04
#define F81604_SJA1000_ALC 0x0B
#define F81604_SJA1000_ECC 0x0C
#define F81604_SJA1000_RXERR 0x0E
#define F81604_SJA1000_TXERR 0x0F
#define F81604_SJA1000_ACCC0 0x10
#define F81604_SJA1000_ACCM0 0x14
#define F81604_MAX_FILTER_CNT 4
/* Common registers - manual section 6.5 */
#define F81604_SJA1000_BTR0 0x06
#define F81604_SJA1000_BTR1 0x07
#define F81604_SJA1000_BTR1_SAMPLE_TRIPLE BIT(7)
#define F81604_SJA1000_OCR 0x08
#define F81604_SJA1000_CDR 0x1F
/* mode register */
#define F81604_SJA1000_MOD_RM 0x01
#define F81604_SJA1000_MOD_LOM 0x02
#define F81604_SJA1000_MOD_STM 0x04
/* commands */
#define F81604_SJA1000_CMD_CDO 0x08
/* interrupt sources */
#define F81604_SJA1000_IRQ_BEI 0x80
#define F81604_SJA1000_IRQ_ALI 0x40
#define F81604_SJA1000_IRQ_EPI 0x20
#define F81604_SJA1000_IRQ_DOI 0x08
#define F81604_SJA1000_IRQ_EI 0x04
#define F81604_SJA1000_IRQ_TI 0x02
#define F81604_SJA1000_IRQ_RI 0x01
#define F81604_SJA1000_IRQ_ALL 0xFF
#define F81604_SJA1000_IRQ_OFF 0x00
/* status register content */
#define F81604_SJA1000_SR_BS 0x80
#define F81604_SJA1000_SR_ES 0x40
#define F81604_SJA1000_SR_TCS 0x08
/* ECC register */
#define F81604_SJA1000_ECC_SEG 0x1F
#define F81604_SJA1000_ECC_DIR 0x20
#define F81604_SJA1000_ECC_BIT 0x00
#define F81604_SJA1000_ECC_FORM 0x40
#define F81604_SJA1000_ECC_STUFF 0x80
#define F81604_SJA1000_ECC_MASK 0xc0
/* ALC register */
#define F81604_SJA1000_ALC_MASK 0x1f
/* table of devices that work with this driver */
static const struct usb_device_id f81604_table[] = {
{ USB_DEVICE(F81604_VENDOR_ID, F81604_PRODUCT_ID) },
{} /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, f81604_table);
static const struct ethtool_ops f81604_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};
static const u16 f81604_termination[] = { F81604_TERMINATION_DISABLED,
F81604_TERMINATION_ENABLED };
struct f81604_priv {
struct net_device *netdev[F81604_MAX_DEV];
};
struct f81604_port_priv {
struct can_priv can;
struct net_device *netdev;
struct sk_buff *echo_skb;
unsigned long clear_flags;
struct work_struct clear_reg_work;
struct usb_device *dev;
struct usb_interface *intf;
struct usb_anchor urbs_anchor;
};
/* Interrupt endpoint data format:
* Byte 0: Status register.
* Byte 1: Interrupt register.
* Byte 2: Interrupt enable register.
* Byte 3: Arbitration lost capture(ALC) register.
* Byte 4: Error code capture(ECC) register.
* Byte 5: Error warning limit register.
* Byte 6: RX error counter register.
* Byte 7: TX error counter register.
* Byte 8: Reserved.
*/
struct f81604_int_data {
u8 sr;
u8 isrc;
u8 ier;
u8 alc;
u8 ecc;
u8 ewlr;
u8 rxerr;
u8 txerr;
u8 val;
} __packed __aligned(4);
struct f81604_sff {
__be16 id;
u8 data[CAN_MAX_DLEN];
} __packed __aligned(2);
struct f81604_eff {
__be32 id;
u8 data[CAN_MAX_DLEN];
} __packed __aligned(2);
struct f81604_can_frame {
u8 cmd;
/* According for F81604 DLC define:
* bit 3~0: data length (0~8)
* bit6: is RTR flag.
* bit7: is EFF frame.
*/
u8 dlc;
union {
struct f81604_sff sff;
struct f81604_eff eff;
};
} __packed __aligned(2);
static const u8 bulk_in_addr[F81604_MAX_DEV] = { 2, 4 };
static const u8 bulk_out_addr[F81604_MAX_DEV] = { 1, 3 };
static const u8 int_in_addr[F81604_MAX_DEV] = { 1, 3 };
static int f81604_write(struct usb_device *dev, u16 reg, u8 data)
{
int ret;
ret = usb_control_msg_send(dev, 0, F81604_SET_GET_REGISTER,
USB_TYPE_VENDOR | USB_DIR_OUT, 0, reg,
&data, sizeof(data), F81604_USB_TIMEOUT,
GFP_KERNEL);
if (ret)
dev_err(&dev->dev, "%s: reg: %x data: %x failed: %pe\n",
__func__, reg, data, ERR_PTR(ret));
return ret;