All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] can: gs_usb: add switchable termination support
@ 2022-09-18 20:23 Marc Kleine-Budde
  2022-09-18 20:31 ` Marc Kleine-Budde
  0 siblings, 1 reply; 2+ messages in thread
From: Marc Kleine-Budde @ 2022-09-18 20:23 UTC (permalink / raw)
  To: linux-can; +Cc: Marc Kleine-Budde, Daniel Trevitz, Ryan Edwards

The candleLight community is working on switchable termination support
for the candleLight firmware. As the the Linux CAN framework supports
switchable termination add this feature to the gs_usb driver.

Devices supporting the feature should set the
GS_CAN_FEATURE_TERMINATION and implement the
GS_USB_BREQ_SET_TERMINATION and GS_USB_BREQ_GET_TERMINATION control
messages.

For now the driver assumes for activated termination the standard
termination of 120Ω.

Link: https://github.com/candle-usb/candleLight_fw/issues/92
Link: https://github.com/candle-usb/candleLight_fw/pull/108
Cc: Daniel Trevitz <daniel.trevitz@wika.com>
Cc: Ryan Edwards <ryan.edwards@gmail.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/usb/gs_usb.c | 77 +++++++++++++++++++++++++++++++++++-
 1 file changed, 76 insertions(+), 1 deletion(-)

diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
index cc363f1935ce..2d6c1fe0c8d3 100644
--- a/drivers/net/can/usb/gs_usb.c
+++ b/drivers/net/can/usb/gs_usb.c
@@ -64,6 +64,8 @@ enum gs_usb_breq {
 	GS_USB_BREQ_SET_USER_ID,
 	GS_USB_BREQ_DATA_BITTIMING,
 	GS_USB_BREQ_BT_CONST_EXT,
+	GS_USB_BREQ_SET_TERMINATION,
+	GS_USB_BREQ_GET_TERMINATION,
 };
 
 enum gs_can_mode {
@@ -87,6 +89,14 @@ enum gs_can_identify_mode {
 	GS_CAN_IDENTIFY_ON
 };
 
+enum gs_can_termination_state {
+	GS_CAN_TERMINATION_STATE_OFF = 0,
+	GS_CAN_TERMINATION_STATE_ON
+};
+
+#define GS_USB_TERMINATION_DISABLED CAN_TERMINATION_DISABLED
+#define GS_USB_TERMINATION_ENABLED 120
+
 /* data types passed between host and device */
 
 /* The firmware on the original USB2CAN by Geschwister Schneider
@@ -123,6 +133,7 @@ struct gs_device_config {
 #define GS_CAN_MODE_FD BIT(8)
 /* GS_CAN_FEATURE_REQ_USB_QUIRK_LPC546XX BIT(9) */
 /* GS_CAN_FEATURE_BT_CONST_EXT BIT(10) */
+/* GS_CAN_FEATURE_TERMINATION BIT(11) */
 
 struct gs_device_mode {
 	__le32 mode;
@@ -147,6 +158,10 @@ struct gs_identify_mode {
 	__le32 mode;
 } __packed;
 
+struct gs_termination_state {
+	__le32 state;
+} __packed;
+
 #define GS_CAN_FEATURE_LISTEN_ONLY BIT(0)
 #define GS_CAN_FEATURE_LOOP_BACK BIT(1)
 #define GS_CAN_FEATURE_TRIPLE_SAMPLE BIT(2)
@@ -158,7 +173,8 @@ struct gs_identify_mode {
 #define GS_CAN_FEATURE_FD BIT(8)
 #define GS_CAN_FEATURE_REQ_USB_QUIRK_LPC546XX BIT(9)
 #define GS_CAN_FEATURE_BT_CONST_EXT BIT(10)
-#define GS_CAN_FEATURE_MASK GENMASK(10, 0)
+#define GS_CAN_FEATURE_TERMINATION BIT(11)
+#define GS_CAN_FEATURE_MASK GENMASK(11, 0)
 
 /* internal quirks - keep in GS_CAN_FEATURE space for now */
 
@@ -1117,6 +1133,59 @@ static const struct ethtool_ops gs_usb_ethtool_ops = {
 	.get_ts_info = gs_usb_get_ts_info,
 };
 
+static int gs_usb_get_termination(struct net_device *netdev, u16 *term)
+{
+	struct gs_can *dev = netdev_priv(netdev);
+	struct gs_termination_state state;
+	int rc;
+
+	rc = usb_control_msg_recv(interface_to_usbdev(dev->iface), 0,
+				  GS_USB_BREQ_GET_TERMINATION,
+				  USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+				  dev->channel, 0,
+				  &state, sizeof(state), 1000,
+				  GFP_KERNEL);
+
+	return rc;
+}
+
+static int gs_usb_set_termination(struct net_device *netdev, u16 term)
+{
+	struct gs_can *dev = netdev_priv(netdev);
+	struct gs_termination_state state;
+	u16 actual_term;
+	int rc;
+
+	if (term == GS_USB_TERMINATION_ENABLED)
+		state.state = cpu_to_le32(GS_CAN_TERMINATION_STATE_ON);
+	else
+		state.state = cpu_to_le32(GS_CAN_TERMINATION_STATE_OFF);
+
+	rc = usb_control_msg_send(interface_to_usbdev(dev->iface), 0,
+				  GS_USB_BREQ_SET_TERMINATION,
+				  USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+				  dev->channel, 0,
+				  &state, sizeof(state), 1000,
+				  GFP_KERNEL);
+
+	if (rc)
+		return rc;
+
+	rc = gs_usb_get_termination(netdev, &actual_term);
+	if (rc)
+		return rc;
+
+	if (term != actual_term)
+		return -EIO;
+
+	return rc;
+}
+
+static const u16 gs_usb_termination_const[] = {
+	GS_USB_TERMINATION_DISABLED,
+	GS_USB_TERMINATION_ENABLED
+};
+
 static struct gs_can *gs_make_candev(unsigned int channel,
 				     struct usb_interface *intf,
 				     struct gs_device_config *dconf)
@@ -1217,6 +1286,12 @@ static struct gs_can *gs_make_candev(unsigned int channel,
 		dev->can.do_set_data_bittiming = gs_usb_set_data_bittiming;
 	}
 
+	if (feature & GS_CAN_FEATURE_TERMINATION) {
+		dev->can.termination_const = gs_usb_termination_const;
+		dev->can.termination_const_cnt = ARRAY_SIZE(gs_usb_termination_const);
+		dev->can.do_set_termination = gs_usb_set_termination;
+	}
+
 	/* The CANtact Pro from LinkLayer Labs is based on the
 	 * LPC54616 µC, which is affected by the NXP LPC USB transfer
 	 * erratum. However, the current firmware (version 2) doesn't
-- 
2.35.1



^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] can: gs_usb: add switchable termination support
  2022-09-18 20:23 [PATCH] can: gs_usb: add switchable termination support Marc Kleine-Budde
@ 2022-09-18 20:31 ` Marc Kleine-Budde
  0 siblings, 0 replies; 2+ messages in thread
From: Marc Kleine-Budde @ 2022-09-18 20:31 UTC (permalink / raw)
  To: linux-can; +Cc: Daniel Trevitz, Ryan Edwards

[-- Attachment #1: Type: text/plain, Size: 2688 bytes --]

On 18.09.2022 22:23:48, Marc Kleine-Budde wrote:
> The candleLight community is working on switchable termination support
> for the candleLight firmware. As the the Linux CAN framework supports
> switchable termination add this feature to the gs_usb driver.
> 
> Devices supporting the feature should set the
> GS_CAN_FEATURE_TERMINATION and implement the
> GS_USB_BREQ_SET_TERMINATION and GS_USB_BREQ_GET_TERMINATION control
> messages.
> 
> For now the driver assumes for activated termination the standard
> termination of 120Ω.
> 
> Link: https://github.com/candle-usb/candleLight_fw/issues/92
> Link: https://github.com/candle-usb/candleLight_fw/pull/108
> Cc: Daniel Trevitz <daniel.trevitz@wika.com>
> Cc: Ryan Edwards <ryan.edwards@gmail.com>
> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>

[...]

> +static int gs_usb_get_termination(struct net_device *netdev, u16 *term)
> +{
> +	struct gs_can *dev = netdev_priv(netdev);
> +	struct gs_termination_state state;
> +	int rc;
> +
> +	rc = usb_control_msg_recv(interface_to_usbdev(dev->iface), 0,
> +				  GS_USB_BREQ_GET_TERMINATION,
> +				  USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
> +				  dev->channel, 0,
> +				  &state, sizeof(state), 1000,
> +				  GFP_KERNEL);
> +
> +	return rc;
> +}
> +
> +static int gs_usb_set_termination(struct net_device *netdev, u16 term)
> +{
> +	struct gs_can *dev = netdev_priv(netdev);
> +	struct gs_termination_state state;
> +	u16 actual_term;
> +	int rc;
> +
> +	if (term == GS_USB_TERMINATION_ENABLED)
> +		state.state = cpu_to_le32(GS_CAN_TERMINATION_STATE_ON);
> +	else
> +		state.state = cpu_to_le32(GS_CAN_TERMINATION_STATE_OFF);
> +
> +	rc = usb_control_msg_send(interface_to_usbdev(dev->iface), 0,
> +				  GS_USB_BREQ_SET_TERMINATION,
> +				  USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
> +				  dev->channel, 0,
> +				  &state, sizeof(state), 1000,
> +				  GFP_KERNEL);
> +
> +	if (rc)
> +		return rc;
> +
> +	rc = gs_usb_get_termination(netdev, &actual_term);

I'm not sure if we need this. The usb_control_msg_send() should only
return if the request succeeds.

I'll add a gs_usb_get_termination() call to the probe function, so that
the driver knows the termination state.

> +	if (rc)
> +		return rc;
> +
> +	if (term != actual_term)
> +		return -EIO;
> +
> +	return rc;
> +}
> +

regards,
Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde           |
Embedded Linux                   | https://www.pengutronix.de  |
Vertretung West/Dortmund         | Phone: +49-231-2826-924     |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-5555 |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-09-18 20:31 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-18 20:23 [PATCH] can: gs_usb: add switchable termination support Marc Kleine-Budde
2022-09-18 20:31 ` Marc Kleine-Budde

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.