mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 18:43:33 +02:00
Merge patch series "can: mcp251xfd: add XSTBYEN transceiver standby control"
Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com> says: The MCP251xFD provides a dedicated transceiver standby control function via the INT0/GPIO0/XSTBY pin, controlled by the XSTBYEN bit in IOCON. When enabled, the hardware automatically drives the pin low while the controller is active and high when it enters Sleep mode, allowing automatic standby control of an external CAN transceiver without software intervention. This series adds driver support for the XSTBYEN-based transceiver standby control feature. Tested on QCS6490 RB3 Gen2 with a PCAN-USB FD adapter: the transceiver is active in normal mode, CAN communication works correctly, and the pin is automatically managed across sleep and wake transitions. Link: https://patch.msgid.link/20260321135031.3107408-1-viken.dadhaniya@oss.qualcomm.com Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
This commit is contained in:
commit
572a36d279
|
|
@ -44,6 +44,14 @@ properties:
|
|||
signals a pending RX interrupt.
|
||||
maxItems: 1
|
||||
|
||||
microchip,xstbyen:
|
||||
type: boolean
|
||||
description:
|
||||
If present, configure the INT0/GPIO0/XSTBY pin as transceiver standby
|
||||
control. The pin is driven low when the controller is active and high
|
||||
when it enters Sleep mode, allowing automatic standby control of an
|
||||
external CAN transceiver connected to this pin.
|
||||
|
||||
spi-max-frequency:
|
||||
description:
|
||||
Must be half or less of "clocks" frequency.
|
||||
|
|
|
|||
|
|
@ -764,6 +764,31 @@ static void mcp251xfd_chip_stop(struct mcp251xfd_priv *priv,
|
|||
mcp251xfd_chip_set_mode(priv, MCP251XFD_REG_CON_MODE_CONFIG);
|
||||
}
|
||||
|
||||
static int mcp251xfd_chip_xstbyen_enable(const struct mcp251xfd_priv *priv)
|
||||
{
|
||||
/* Configure the INT0/GPIO0/XSTBY pin as transceiver standby control:
|
||||
*
|
||||
* - XSTBYEN=1: route the pin to the transceiver standby function
|
||||
* - TRIS0=0: set output direction; the reset default is 1 (input),
|
||||
* which leaves the pin floating HIGH and keeps the
|
||||
* transceiver in standby regardless of XSTBYEN
|
||||
* - LAT0=0: drive pin LOW => transceiver active (not in standby)
|
||||
*
|
||||
* All three bits are included in the mask; only XSTBYEN is set in
|
||||
* val, so TRIS0 and LAT0 are cleared to 0 atomically.
|
||||
*
|
||||
* Pin behaviour by mode:
|
||||
* - Config mode: controlled by LAT0 (LAT0=0 => LOW => active)
|
||||
* - Normal mode: hardware drives pin LOW (active)
|
||||
* - Sleep mode: hardware drives pin HIGH (standby)
|
||||
*/
|
||||
return regmap_update_bits(priv->map_reg, MCP251XFD_REG_IOCON,
|
||||
MCP251XFD_REG_IOCON_XSTBYEN |
|
||||
MCP251XFD_REG_IOCON_TRIS0 |
|
||||
MCP251XFD_REG_IOCON_LAT0,
|
||||
MCP251XFD_REG_IOCON_XSTBYEN);
|
||||
}
|
||||
|
||||
static int mcp251xfd_chip_start(struct mcp251xfd_priv *priv)
|
||||
{
|
||||
int err;
|
||||
|
|
@ -796,6 +821,12 @@ static int mcp251xfd_chip_start(struct mcp251xfd_priv *priv)
|
|||
|
||||
priv->can.state = CAN_STATE_ERROR_ACTIVE;
|
||||
|
||||
if (priv->xstbyen) {
|
||||
err = mcp251xfd_chip_xstbyen_enable(priv);
|
||||
if (err)
|
||||
goto out_chip_stop;
|
||||
}
|
||||
|
||||
err = mcp251xfd_chip_set_normal_mode(priv);
|
||||
if (err)
|
||||
goto out_chip_stop;
|
||||
|
|
@ -1805,6 +1836,11 @@ static int mcp251xfd_gpio_request(struct gpio_chip *chip, unsigned int offset)
|
|||
u32 pin_mask = MCP251XFD_REG_IOCON_PM(offset);
|
||||
int ret;
|
||||
|
||||
if (priv->xstbyen && offset == 0) {
|
||||
netdev_err(priv->ndev, "Can't use GPIO 0 with XSTBYEN!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (priv->rx_int && offset == 1) {
|
||||
netdev_err(priv->ndev, "Can't use GPIO 1 with RX-INT!\n");
|
||||
return -EINVAL;
|
||||
|
|
@ -2271,6 +2307,7 @@ static int mcp251xfd_probe(struct spi_device *spi)
|
|||
priv->pll_enable = pll_enable;
|
||||
priv->reg_vdd = reg_vdd;
|
||||
priv->reg_xceiver = reg_xceiver;
|
||||
priv->xstbyen = device_property_present(&spi->dev, "microchip,xstbyen");
|
||||
priv->devtype_data = *(struct mcp251xfd_devtype_data *)spi_get_device_match_data(spi);
|
||||
|
||||
/* Errata Reference:
|
||||
|
|
|
|||
|
|
@ -672,6 +672,7 @@ struct mcp251xfd_priv {
|
|||
struct gpio_desc *rx_int;
|
||||
struct clk *clk;
|
||||
bool pll_enable;
|
||||
bool xstbyen;
|
||||
struct regulator *reg_vdd;
|
||||
struct regulator *reg_xceiver;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user