mirror of
https://github.com/edk2-porting/linux-next.git
synced 2025-01-15 17:14:00 +08:00
can: peak_usb: add support of ethtool set_phys_id()
This patch makes it possible to specifically flash the LED of a CAN port of the CAN-USB interfaces of PEAK-System. Link: https://lore.kernel.org/r/20210309122141.3276927-1-mkl@pengutronix.de Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com> [mkl: use common prefix PCAN_ for defines] Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
This commit is contained in:
parent
cfe2a4ca1e
commit
a7e8511ffd
@ -11,6 +11,7 @@
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ethtool.h>
|
||||
|
||||
#include <linux/can.h>
|
||||
#include <linux/can/dev.h>
|
||||
@ -40,6 +41,7 @@
|
||||
#define PCAN_USB_CMD_REGISTER 9
|
||||
#define PCAN_USB_CMD_EXT_VCC 10
|
||||
#define PCAN_USB_CMD_ERR_FR 11
|
||||
#define PCAN_USB_CMD_LED 12
|
||||
|
||||
/* PCAN_USB_CMD_SET_BUS number arg */
|
||||
#define PCAN_USB_BUS_XCVER 2
|
||||
@ -248,6 +250,15 @@ static int pcan_usb_set_ext_vcc(struct peak_usb_device *dev, u8 onoff)
|
||||
return pcan_usb_send_cmd(dev, PCAN_USB_CMD_EXT_VCC, PCAN_USB_SET, args);
|
||||
}
|
||||
|
||||
static int pcan_usb_set_led(struct peak_usb_device *dev, u8 onoff)
|
||||
{
|
||||
u8 args[PCAN_USB_CMD_ARGS_LEN] = {
|
||||
[0] = !!onoff,
|
||||
};
|
||||
|
||||
return pcan_usb_send_cmd(dev, PCAN_USB_CMD_LED, PCAN_USB_SET, args);
|
||||
}
|
||||
|
||||
/*
|
||||
* set bittiming value to can
|
||||
*/
|
||||
@ -971,6 +982,40 @@ static int pcan_usb_probe(struct usb_interface *intf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pcan_usb_set_phys_id(struct net_device *netdev,
|
||||
enum ethtool_phys_id_state state)
|
||||
{
|
||||
struct peak_usb_device *dev = netdev_priv(netdev);
|
||||
int err = 0;
|
||||
|
||||
switch (state) {
|
||||
case ETHTOOL_ID_ACTIVE:
|
||||
/* call ON/OFF twice a second */
|
||||
return 2;
|
||||
|
||||
case ETHTOOL_ID_OFF:
|
||||
err = pcan_usb_set_led(dev, 0);
|
||||
break;
|
||||
|
||||
case ETHTOOL_ID_ON:
|
||||
fallthrough;
|
||||
|
||||
case ETHTOOL_ID_INACTIVE:
|
||||
/* restore LED default */
|
||||
err = pcan_usb_set_led(dev, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct ethtool_ops pcan_usb_ethtool_ops = {
|
||||
.set_phys_id = pcan_usb_set_phys_id,
|
||||
};
|
||||
|
||||
/*
|
||||
* describe the PCAN-USB adapter
|
||||
*/
|
||||
@ -1001,6 +1046,8 @@ const struct peak_usb_adapter pcan_usb = {
|
||||
/* size of device private data */
|
||||
.sizeof_dev_private = sizeof(struct pcan_usb),
|
||||
|
||||
.ethtool_ops = &pcan_usb_ethtool_ops,
|
||||
|
||||
/* timestamps usage */
|
||||
.ts_used_bits = 16,
|
||||
.ts_period = 24575, /* calibration period in ts. */
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/ethtool.h>
|
||||
|
||||
#include <linux/can.h>
|
||||
#include <linux/can/dev.h>
|
||||
@ -820,6 +821,9 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
|
||||
|
||||
netdev->flags |= IFF_ECHO; /* we support local echo */
|
||||
|
||||
/* add ethtool support */
|
||||
netdev->ethtool_ops = peak_usb_adapter->ethtool_ops;
|
||||
|
||||
init_usb_anchor(&dev->rx_submitted);
|
||||
|
||||
init_usb_anchor(&dev->tx_submitted);
|
||||
|
@ -46,6 +46,8 @@ struct peak_usb_adapter {
|
||||
const struct can_bittiming_const * const data_bittiming_const;
|
||||
unsigned int ctrl_count;
|
||||
|
||||
const struct ethtool_ops *ethtool_ops;
|
||||
|
||||
int (*intf_probe)(struct usb_interface *intf);
|
||||
|
||||
int (*dev_init)(struct peak_usb_device *dev);
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ethtool.h>
|
||||
|
||||
#include <linux/can.h>
|
||||
#include <linux/can/dev.h>
|
||||
@ -1006,6 +1007,31 @@ static void pcan_usb_fd_free(struct peak_usb_device *dev)
|
||||
}
|
||||
}
|
||||
|
||||
/* blink LED's */
|
||||
static int pcan_usb_fd_set_phys_id(struct net_device *netdev,
|
||||
enum ethtool_phys_id_state state)
|
||||
{
|
||||
struct peak_usb_device *dev = netdev_priv(netdev);
|
||||
int err = 0;
|
||||
|
||||
switch (state) {
|
||||
case ETHTOOL_ID_ACTIVE:
|
||||
err = pcan_usb_fd_set_can_led(dev, PCAN_UFD_LED_FAST);
|
||||
break;
|
||||
case ETHTOOL_ID_INACTIVE:
|
||||
err = pcan_usb_fd_set_can_led(dev, PCAN_UFD_LED_DEF);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct ethtool_ops pcan_usb_fd_ethtool_ops = {
|
||||
.set_phys_id = pcan_usb_fd_set_phys_id,
|
||||
};
|
||||
|
||||
/* describes the PCAN-USB FD adapter */
|
||||
static const struct can_bittiming_const pcan_usb_fd_const = {
|
||||
.name = "pcan_usb_fd",
|
||||
@ -1047,6 +1073,8 @@ const struct peak_usb_adapter pcan_usb_fd = {
|
||||
/* size of device private data */
|
||||
.sizeof_dev_private = sizeof(struct pcan_usb_fd_device),
|
||||
|
||||
.ethtool_ops = &pcan_usb_fd_ethtool_ops,
|
||||
|
||||
/* timestamps usage */
|
||||
.ts_used_bits = 32,
|
||||
.ts_period = 1000000, /* calibration period in ts. */
|
||||
@ -1120,6 +1148,8 @@ const struct peak_usb_adapter pcan_usb_chip = {
|
||||
/* size of device private data */
|
||||
.sizeof_dev_private = sizeof(struct pcan_usb_fd_device),
|
||||
|
||||
.ethtool_ops = &pcan_usb_fd_ethtool_ops,
|
||||
|
||||
/* timestamps usage */
|
||||
.ts_used_bits = 32,
|
||||
.ts_period = 1000000, /* calibration period in ts. */
|
||||
@ -1193,6 +1223,8 @@ const struct peak_usb_adapter pcan_usb_pro_fd = {
|
||||
/* size of device private data */
|
||||
.sizeof_dev_private = sizeof(struct pcan_usb_fd_device),
|
||||
|
||||
.ethtool_ops = &pcan_usb_fd_ethtool_ops,
|
||||
|
||||
/* timestamps usage */
|
||||
.ts_used_bits = 32,
|
||||
.ts_period = 1000000, /* calibration period in ts. */
|
||||
@ -1266,6 +1298,8 @@ const struct peak_usb_adapter pcan_usb_x6 = {
|
||||
/* size of device private data */
|
||||
.sizeof_dev_private = sizeof(struct pcan_usb_fd_device),
|
||||
|
||||
.ethtool_ops = &pcan_usb_fd_ethtool_ops,
|
||||
|
||||
/* timestamps usage */
|
||||
.ts_used_bits = 32,
|
||||
.ts_period = 1000000, /* calibration period in ts. */
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ethtool.h>
|
||||
|
||||
#include <linux/can.h>
|
||||
#include <linux/can/dev.h>
|
||||
@ -906,7 +907,7 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev)
|
||||
usb_if->dev[dev->ctrl_idx] = dev;
|
||||
|
||||
/* set LED in default state (end of init phase) */
|
||||
pcan_usb_pro_set_led(dev, 0, 1);
|
||||
pcan_usb_pro_set_led(dev, PCAN_USBPRO_LED_DEVICE, 1);
|
||||
|
||||
kfree(bi);
|
||||
kfree(fi);
|
||||
@ -990,6 +991,35 @@ int pcan_usb_pro_probe(struct usb_interface *intf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pcan_usb_pro_set_phys_id(struct net_device *netdev,
|
||||
enum ethtool_phys_id_state state)
|
||||
{
|
||||
struct peak_usb_device *dev = netdev_priv(netdev);
|
||||
int err = 0;
|
||||
|
||||
switch (state) {
|
||||
case ETHTOOL_ID_ACTIVE:
|
||||
/* fast blinking forever */
|
||||
err = pcan_usb_pro_set_led(dev, PCAN_USBPRO_LED_BLINK_FAST,
|
||||
0xffffffff);
|
||||
break;
|
||||
|
||||
case ETHTOOL_ID_INACTIVE:
|
||||
/* restore LED default */
|
||||
err = pcan_usb_pro_set_led(dev, PCAN_USBPRO_LED_DEVICE, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct ethtool_ops pcan_usb_pro_ethtool_ops = {
|
||||
.set_phys_id = pcan_usb_pro_set_phys_id,
|
||||
};
|
||||
|
||||
/*
|
||||
* describe the PCAN-USB Pro adapter
|
||||
*/
|
||||
@ -1018,6 +1048,8 @@ const struct peak_usb_adapter pcan_usb_pro = {
|
||||
/* size of device private data */
|
||||
.sizeof_dev_private = sizeof(struct pcan_usb_pro_device),
|
||||
|
||||
.ethtool_ops = &pcan_usb_pro_ethtool_ops,
|
||||
|
||||
/* timestamps usage */
|
||||
.ts_used_bits = 32,
|
||||
.ts_period = 1000000, /* calibration period in ts. */
|
||||
|
@ -115,6 +115,12 @@ struct __packed pcan_usb_pro_devid {
|
||||
__le32 serial_num;
|
||||
};
|
||||
|
||||
#define PCAN_USBPRO_LED_DEVICE 0x00
|
||||
#define PCAN_USBPRO_LED_BLINK_FAST 0x01
|
||||
#define PCAN_USBPRO_LED_BLINK_SLOW 0x02
|
||||
#define PCAN_USBPRO_LED_ON 0x03
|
||||
#define PCAN_USBPRO_LED_OFF 0x04
|
||||
|
||||
struct __packed pcan_usb_pro_setled {
|
||||
u8 data_type;
|
||||
u8 channel;
|
||||
|
Loading…
Reference in New Issue
Block a user