From 36d4d74d63498496a39c67b2e50e0c8e33b4a429 Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Thu, 24 Aug 2017 00:49:13 -0700 Subject: [PATCH] can: k61: Changes to support the mpc5746c controller Add new parameters to account for different MCUs that can be used with this driver. These devices have different reset sequences and number of bits per word supported via SPI. Add bindings for the mpc5746c controller and make the reset signal optional. Change-Id: I616dd3cfedf18a6e21683e1c07551c57c62a675d Signed-off-by: Gustavo Solaira --- .../devicetree/bindings/net/can/k61-can.txt | 11 ++++- drivers/net/can/spi/k61.c | 47 +++++++++++-------- 2 files changed, 37 insertions(+), 21 deletions(-) diff --git a/Documentation/devicetree/bindings/net/can/k61-can.txt b/Documentation/devicetree/bindings/net/can/k61-can.txt index 57e85817a0a5..ea4a7b4ae035 100644 --- a/Documentation/devicetree/bindings/net/can/k61-can.txt +++ b/Documentation/devicetree/bindings/net/can/k61-can.txt @@ -3,15 +3,20 @@ This driver implements SPI slave protocol for Freescale K61 CAN controller. Required properties: - - compatible: Should be "fsl,k61". + - compatible: Should be "fsl,k61" or "nxp,mpc5746c". - reg: Should contain SPI chip select. - interrupt-parent: Should specify interrupt controller for the interrupt. - interrupts: Should contain IRQ line for the CAN controller. + +Optional properties: - reset-gpio: Reference to the GPIO connected to the reset input. - pinctrl-names : Names corresponding to the numbered pinctrl states. - pinctrl-0 : This explains the active state of the GPIO line. - pinctrl-1 : This explains the suspend state of the GPIO line. - + - bits-per-word: Indicate how many bits are in a SPI frame. e.g.: 8, 16, 32. + Default to 16. + - reset-delay-msec: Delay in milliseconds to be applied after resetting the chip. + Default to 1 ms. Example: @@ -24,4 +29,6 @@ Example: pinctrl-names = "active", "sleep"; pinctrl-0 = <&can_rst_on>; pinctrl-1 = <&can_rst_off>; + bits-per-word = <8>; + reset-delay-msec = <100>; }; diff --git a/drivers/net/can/spi/k61.c b/drivers/net/can/spi/k61.c index a567cc653e46..9ce0ad854caa 100644 --- a/drivers/net/can/spi/k61.c +++ b/drivers/net/can/spi/k61.c @@ -57,6 +57,8 @@ struct k61_can { int reset; int wait_cmd; int cmd_result; + int bits_per_word; + int reset_delay_msec; }; struct k61_netdev_privdata { @@ -310,7 +312,7 @@ static int k61_do_spi_transaction(struct k61_can *priv_data) xfer->tx_buf = priv_data->tx_buf; xfer->rx_buf = priv_data->rx_buf; xfer->len = XFER_BUFFER_SIZE; - xfer->bits_per_word = 16; + xfer->bits_per_word = priv_data->bits_per_word; ret = spi_sync(spi, msg); LOGDI("spi_sync ret %d\n", ret); @@ -829,25 +831,31 @@ static int k61_probe(struct spi_device *spi) } dev_dbg(dev, "k61_probe created priv_data"); - priv_data->reset = of_get_named_gpio(spi->dev.of_node, "reset-gpio", 0); - if (!gpio_is_valid(priv_data->reset)) { - dev_err(&spi->dev, "Missing dt property: reset-gpio\n"); - return -EINVAL; - } - err = gpio_request(priv_data->reset, "k61-reset"); - if (err < 0) { - dev_err(&spi->dev, - "failed to request gpio %d: %d\n", - priv_data->reset, err); - } + err = of_property_read_u32(spi->dev.of_node, "bits-per-word", + &priv_data->bits_per_word); + if (err) + priv_data->bits_per_word = 16; - gpio_direction_output(priv_data->reset, 0); - udelay(1); - gpio_direction_output(priv_data->reset, 1); - /* Provide a delay of 300us for the chip to reset. This is part of - * the reset sequence. - */ - usleep_range(300, 301); + err = of_property_read_u32(spi->dev.of_node, "reset-delay-msec", + &priv_data->reset_delay_msec); + if (err) + priv_data->reset_delay_msec = 1; + + priv_data->reset = of_get_named_gpio(spi->dev.of_node, "reset-gpio", 0); + if (gpio_is_valid(priv_data->reset)) { + err = gpio_request(priv_data->reset, "k61-reset"); + if (err < 0) { + dev_err(&spi->dev, + "failed to request gpio %d: %d\n", + priv_data->reset, err); + goto cleanup_candev; + } + + gpio_direction_output(priv_data->reset, 0); + udelay(1); + gpio_direction_output(priv_data->reset, 1); + msleep(priv_data->reset_delay_msec); + } err = k61_create_netdev(spi, priv_data); if (err) { @@ -909,6 +917,7 @@ static int k61_remove(struct spi_device *spi) static const struct of_device_id k61_match_table[] = { { .compatible = "fsl,k61" }, + { .compatible = "nxp,mpc5746c" }, { } };