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/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; + }; }; }; }; 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 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" }, { } };