From 36d4d74d63498496a39c67b2e50e0c8e33b4a429 Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Thu, 24 Aug 2017 00:49:13 -0700 Subject: [PATCH 1/3] 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" }, { } }; From 79be912c145f417489b20116f85a51b3e60cbe60 Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Wed, 23 Aug 2017 22:53:27 -0700 Subject: [PATCH 2/3] defconfig: msm: Enable the K61 CAN driver Enable configuration for K61 CAN over SPI driver. Change-Id: I801629ac04303582530bed354282960db8f9c9ab Signed-off-by: Gustavo Solaira --- arch/arm64/configs/msm-auto-perf_defconfig | 1 + arch/arm64/configs/msm-auto_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/msm-auto-perf_defconfig b/arch/arm64/configs/msm-auto-perf_defconfig index 28d10091da43..a521b24b61f5 100644 --- a/arch/arm64/configs/msm-auto-perf_defconfig +++ b/arch/arm64/configs/msm-auto-perf_defconfig @@ -220,6 +220,7 @@ CONFIG_RMNET_DATA_DEBUG_PKT=y CONFIG_SOCKEV_NLMCAST=y CONFIG_CAN=y CONFIG_CAN_RH850=y +CONFIG_CAN_K61=y CONFIG_BT=y CONFIG_MSM_BT_POWER=y CONFIG_BTFM_SLIM=y diff --git a/arch/arm64/configs/msm-auto_defconfig b/arch/arm64/configs/msm-auto_defconfig index 1783707399ca..f8187f87f763 100644 --- a/arch/arm64/configs/msm-auto_defconfig +++ b/arch/arm64/configs/msm-auto_defconfig @@ -222,6 +222,7 @@ CONFIG_RMNET_DATA_DEBUG_PKT=y CONFIG_SOCKEV_NLMCAST=y CONFIG_CAN=y CONFIG_CAN_RH850=y +CONFIG_CAN_K61=y CONFIG_BT=y CONFIG_MSM_BT_POWER=y CONFIG_BTFM_SLIM=y From be06210b35c32dc674b98e52232d3e5f647ba021 Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Wed, 23 Aug 2017 11:30:39 -0700 Subject: [PATCH 3/3] ARM: dts: msm: Enable CAN controller for msm8996 CV2X boards Add a device tree node for the SPI CAN controller to enable a CAN network interface for msm8996 CV2X boards. Change-Id: Ib9c1d63bf86e3b823aa8d762065ed374bdfeaa0e Signed-off-by: Gustavo Solaira --- arch/arm/boot/dts/qcom/msm8996-cv2x.dtsi | 21 ++++++------- arch/arm/boot/dts/qcom/msm8996-pinctrl.dtsi | 33 +++++++++++++++------ 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/arch/arm/boot/dts/qcom/msm8996-cv2x.dtsi b/arch/arm/boot/dts/qcom/msm8996-cv2x.dtsi index d18344eb3daf..3dfc57752ea0 100644 --- a/arch/arm/boot/dts/qcom/msm8996-cv2x.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996-cv2x.dtsi @@ -216,11 +216,18 @@ &spi_9 { status = "okay"; - /* CAN controller */ - spi@0 { - compatible = "nxp,mpc57xx"; + can-controller@0 { + compatible = "nxp,mpc5746c"; reg = <0>; - spi-max-frequency = <19200000>; + spi-max-frequency = <9600000>; + interrupt-parent = <&tlmm>; + interrupts = <78 0>; + reset-gpio = <&tlmm 71 GPIO_ACTIVE_LOW>; + bits-per-word = <8>; + reset-delay-msec = <100>; + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&can_rst_on>; + pinctrl-1 = <&can_rst_off>; }; }; @@ -400,12 +407,6 @@ status = "okay"; }; -&tlmm { - /* Set these up as hogs */ - pinctrl-names = "default"; - pinctrl-0 = <&can_reset_gpio>; -}; - &pm8994_gpios { gpio@c700 { /* GPIO 8 - WLAN_EN */ qcom,mode = <1>; /* Digital output*/ diff --git a/arch/arm/boot/dts/qcom/msm8996-pinctrl.dtsi b/arch/arm/boot/dts/qcom/msm8996-pinctrl.dtsi index d800fdaae3de..244901bd5cef 100644 --- a/arch/arm/boot/dts/qcom/msm8996-pinctrl.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996-pinctrl.dtsi @@ -2745,17 +2745,32 @@ }; }; - can_reset_gpio: can_reset_gpio { - mux { - pins = "gpio71"; - function = "gpio"; + can_reset { + can_rst_on: rst_on { + mux { + pins = "gpio71"; + function = "gpio"; + }; + + config { + pins = "gpio71"; + drive-strength = <2>; /* 2 mA */ + bias-pull-up; + }; }; - config { - pins = "gpio71"; - drive-strength = <2>; - output-high; - bias-pull-up; + can_rst_off: rst_off { + mux { + pins = "gpio71"; + function = "gpio"; + }; + + config { + pins = "gpio71"; + drive-strength = <2>; /* 2 mA */ + bias-pull-up; + output-high; + }; }; }; };