For the GS_USB_BREQ_DATA_BITTIMING USB control message the CANtact Pro firmware uses a request value, which is already used by the candleLight firmware for a different purpose (GS_USB_BREQ_GET_USER_ID). This patch adds a quirk to use the CANtact Pro's value for the GS_USB_BREQ_DATA_BITTIMING USB control message instead of the official one. Link: https://lore.kernel.org/all/20220309124132.291861-18-mkl@xxxxxxxxxxxxxx Signed-off-by: Marc Kleine-Budde <mkl@xxxxxxxxxxxxxx> --- drivers/net/can/usb/gs_usb.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index b0651789ccd3..1661b91de364 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c @@ -42,6 +42,7 @@ enum gs_usb_breq { GS_USB_BREQ_TIMESTAMP, GS_USB_BREQ_IDENTIFY, GS_USB_BREQ_GET_USER_ID, + GS_USB_BREQ_QUIRK_CANTACT_PRO_DATA_BITTIMING = GS_USB_BREQ_GET_USER_ID, GS_USB_BREQ_SET_USER_ID, GS_USB_BREQ_DATA_BITTIMING, }; @@ -138,6 +139,13 @@ struct gs_identify_mode { #define GS_CAN_FEATURE_REQ_USB_QUIRK_LPC546XX BIT(9) #define GS_CAN_FEATURE_MASK GENMASK(9, 0) +/* internal quirks - keep in GS_CAN_FEATURE space for now */ + +/* CANtact Pro original firmware: + * BREQ DATA_BITTIMING overlaps with GET_USER_ID + */ +#define GS_CAN_FEATURE_QUIRK_BREQ_CANTACT_PRO BIT(31) + struct gs_device_bt_const { __le32 feature; __le32 fclk_can; @@ -506,6 +514,7 @@ static int gs_usb_set_data_bittiming(struct net_device *netdev) struct can_bittiming *bt = &dev->can.data_bittiming; struct usb_interface *intf = dev->iface; struct gs_device_bittiming *dbt; + u8 request = GS_USB_BREQ_DATA_BITTIMING; int rc; dbt = kmalloc(sizeof(*dbt), GFP_KERNEL); @@ -518,10 +527,13 @@ static int gs_usb_set_data_bittiming(struct net_device *netdev) dbt->sjw = cpu_to_le32(bt->sjw); dbt->brp = cpu_to_le32(bt->brp); + if (dev->feature & GS_CAN_FEATURE_QUIRK_BREQ_CANTACT_PRO) + request = GS_USB_BREQ_QUIRK_CANTACT_PRO_DATA_BITTIMING; + /* request bit timings */ rc = usb_control_msg(interface_to_usbdev(intf), usb_sndctrlpipe(interface_to_usbdev(intf), 0), - GS_USB_BREQ_DATA_BITTIMING, + request, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, dev->channel, 0, dbt, sizeof(*dbt), 1000); -- 2.35.1