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 <gustavos@codeaurora.org>
This commit is contained in:
Gustavo Solaira 2017-08-24 00:49:13 -07:00
parent 4cf8fd54ec
commit 36d4d74d63
2 changed files with 37 additions and 21 deletions

View file

@ -3,15 +3,20 @@
This driver implements SPI slave protocol for Freescale K61 CAN controller. This driver implements SPI slave protocol for Freescale K61 CAN controller.
Required properties: Required properties:
- compatible: Should be "fsl,k61". - compatible: Should be "fsl,k61" or "nxp,mpc5746c".
- reg: Should contain SPI chip select. - reg: Should contain SPI chip select.
- interrupt-parent: Should specify interrupt controller for the interrupt. - interrupt-parent: Should specify interrupt controller for the interrupt.
- interrupts: Should contain IRQ line for the CAN controller. - interrupts: Should contain IRQ line for the CAN controller.
Optional properties:
- reset-gpio: Reference to the GPIO connected to the reset input. - reset-gpio: Reference to the GPIO connected to the reset input.
- pinctrl-names : Names corresponding to the numbered pinctrl states. - pinctrl-names : Names corresponding to the numbered pinctrl states.
- pinctrl-0 : This explains the active state of the GPIO line. - pinctrl-0 : This explains the active state of the GPIO line.
- pinctrl-1 : This explains the suspend 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: Example:
@ -24,4 +29,6 @@ Example:
pinctrl-names = "active", "sleep"; pinctrl-names = "active", "sleep";
pinctrl-0 = <&can_rst_on>; pinctrl-0 = <&can_rst_on>;
pinctrl-1 = <&can_rst_off>; pinctrl-1 = <&can_rst_off>;
bits-per-word = <8>;
reset-delay-msec = <100>;
}; };

View file

@ -57,6 +57,8 @@ struct k61_can {
int reset; int reset;
int wait_cmd; int wait_cmd;
int cmd_result; int cmd_result;
int bits_per_word;
int reset_delay_msec;
}; };
struct k61_netdev_privdata { 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->tx_buf = priv_data->tx_buf;
xfer->rx_buf = priv_data->rx_buf; xfer->rx_buf = priv_data->rx_buf;
xfer->len = XFER_BUFFER_SIZE; xfer->len = XFER_BUFFER_SIZE;
xfer->bits_per_word = 16; xfer->bits_per_word = priv_data->bits_per_word;
ret = spi_sync(spi, msg); ret = spi_sync(spi, msg);
LOGDI("spi_sync ret %d\n", ret); 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"); dev_dbg(dev, "k61_probe created priv_data");
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;
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); priv_data->reset = of_get_named_gpio(spi->dev.of_node, "reset-gpio", 0);
if (!gpio_is_valid(priv_data->reset)) { 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"); err = gpio_request(priv_data->reset, "k61-reset");
if (err < 0) { if (err < 0) {
dev_err(&spi->dev, dev_err(&spi->dev,
"failed to request gpio %d: %d\n", "failed to request gpio %d: %d\n",
priv_data->reset, err); priv_data->reset, err);
goto cleanup_candev;
} }
gpio_direction_output(priv_data->reset, 0); gpio_direction_output(priv_data->reset, 0);
udelay(1); udelay(1);
gpio_direction_output(priv_data->reset, 1); gpio_direction_output(priv_data->reset, 1);
/* Provide a delay of 300us for the chip to reset. This is part of msleep(priv_data->reset_delay_msec);
* the reset sequence. }
*/
usleep_range(300, 301);
err = k61_create_netdev(spi, priv_data); err = k61_create_netdev(spi, priv_data);
if (err) { if (err) {
@ -909,6 +917,7 @@ static int k61_remove(struct spi_device *spi)
static const struct of_device_id k61_match_table[] = { static const struct of_device_id k61_match_table[] = {
{ .compatible = "fsl,k61" }, { .compatible = "fsl,k61" },
{ .compatible = "nxp,mpc5746c" },
{ } { }
}; };