mcp251x.c (35e62ae830f950cfb09d2386412e09cc6d0e34b2) mcp251x.c (35b7fa4d07c43ad79b88e6462119e7140eae955c)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
1/*
3 * CAN bus driver for Microchip 251x CAN Controller with SPI Interface
2 * CAN bus driver for Microchip 251x/25625 CAN Controller with SPI Interface
4 *
5 * MCP2510 support and bug fixes by Christian Pellegrin
6 * <chripell@evolware.org>
7 *
8 * Copyright 2009 Christian Pellegrin EVOL S.r.l.
9 *
10 * Copyright 2007 Raymarine UK, Ltd. All Rights Reserved.
11 * Written under contract by:
12 * Chris Elston, Katalix Systems, Ltd.
13 *
14 * Based on Microchip MCP251x CAN controller driver written by
15 * David Vrabel, Copyright 2006 Arcom Control Systems Ltd.
16 *
17 * Based on CAN bus driver for the CCAN controller written by
18 * - Sascha Hauer, Marc Kleine-Budde, Pengutronix
19 * - Simon Kallweit, intefo AG
20 * Copyright 2007
21 *
3 *
4 * MCP2510 support and bug fixes by Christian Pellegrin
5 * <chripell@evolware.org>
6 *
7 * Copyright 2009 Christian Pellegrin EVOL S.r.l.
8 *
9 * Copyright 2007 Raymarine UK, Ltd. All Rights Reserved.
10 * Written under contract by:
11 * Chris Elston, Katalix Systems, Ltd.
12 *
13 * Based on Microchip MCP251x CAN controller driver written by
14 * David Vrabel, Copyright 2006 Arcom Control Systems Ltd.
15 *
16 * Based on CAN bus driver for the CCAN controller written by
17 * - Sascha Hauer, Marc Kleine-Budde, Pengutronix
18 * - Simon Kallweit, intefo AG
19 * Copyright 2007
20 *
21 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the version 2 of the GNU General Public License
23 * as published by the Free Software Foundation
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, see <http://www.gnu.org/licenses/>.
32 *
33 *
34 *
22 * Your platform definition file should specify something like:
23 *
24 * static struct mcp251x_platform_data mcp251x_info = {
25 * .oscillator_frequency = 8000000,
26 * };
27 *
28 * static struct spi_board_info spi_board_info[] = {
29 * {
30 * .modalias = "mcp2510",
35 * Your platform definition file should specify something like:
36 *
37 * static struct mcp251x_platform_data mcp251x_info = {
38 * .oscillator_frequency = 8000000,
39 * };
40 *
41 * static struct spi_board_info spi_board_info[] = {
42 * {
43 * .modalias = "mcp2510",
31 * // or "mcp2515" depending on your controller
44 * // "mcp2515" or "mcp25625" depending on your controller
32 * .platform_data = &mcp251x_info,
33 * .irq = IRQ_EINT13,
34 * .max_speed_hz = 2*1000*1000,
35 * .chip_select = 2,
36 * },
37 * };
38 *
39 * Please see mcp251x.h for a description of the fields in
40 * struct mcp251x_platform_data.
45 * .platform_data = &mcp251x_info,
46 * .irq = IRQ_EINT13,
47 * .max_speed_hz = 2*1000*1000,
48 * .chip_select = 2,
49 * },
50 * };
51 *
52 * Please see mcp251x.h for a description of the fields in
53 * struct mcp251x_platform_data.
54 *
41 */
42
43#include <linux/can/core.h>
44#include <linux/can/dev.h>
45#include <linux/can/led.h>
46#include <linux/can/platform/mcp251x.h>
47#include <linux/clk.h>
48#include <linux/completion.h>

--- 170 unchanged lines hidden (view full) ---

219 .brp_min = 1,
220 .brp_max = 64,
221 .brp_inc = 1,
222};
223
224enum mcp251x_model {
225 CAN_MCP251X_MCP2510 = 0x2510,
226 CAN_MCP251X_MCP2515 = 0x2515,
55 */
56
57#include <linux/can/core.h>
58#include <linux/can/dev.h>
59#include <linux/can/led.h>
60#include <linux/can/platform/mcp251x.h>
61#include <linux/clk.h>
62#include <linux/completion.h>

--- 170 unchanged lines hidden (view full) ---

233 .brp_min = 1,
234 .brp_max = 64,
235 .brp_inc = 1,
236};
237
238enum mcp251x_model {
239 CAN_MCP251X_MCP2510 = 0x2510,
240 CAN_MCP251X_MCP2515 = 0x2515,
241 CAN_MCP251X_MCP25625 = 0x25625,
227};
228
229struct mcp251x_priv {
230 struct can_priv can;
231 struct net_device *net;
232 struct spi_device *spi;
233 enum mcp251x_model model;
234

--- 26 unchanged lines hidden (view full) ---

261#define MCP251X_IS(_model) \
262static inline int mcp251x_is_##_model(struct spi_device *spi) \
263{ \
264 struct mcp251x_priv *priv = spi_get_drvdata(spi); \
265 return priv->model == CAN_MCP251X_MCP##_model; \
266}
267
268MCP251X_IS(2510);
242};
243
244struct mcp251x_priv {
245 struct can_priv can;
246 struct net_device *net;
247 struct spi_device *spi;
248 enum mcp251x_model model;
249

--- 26 unchanged lines hidden (view full) ---

276#define MCP251X_IS(_model) \
277static inline int mcp251x_is_##_model(struct spi_device *spi) \
278{ \
279 struct mcp251x_priv *priv = spi_get_drvdata(spi); \
280 return priv->model == CAN_MCP251X_MCP##_model; \
281}
282
283MCP251X_IS(2510);
269MCP251X_IS(2515);
270
271static void mcp251x_clean(struct net_device *net)
272{
273 struct mcp251x_priv *priv = netdev_priv(net);
274
275 if (priv->tx_skb || priv->tx_len)
276 net->stats.tx_errors++;
277 if (priv->tx_skb)

--- 342 unchanged lines hidden (view full) ---

620
621 priv->spi_tx_buf[0] = INSTRUCTION_RESET;
622 ret = mcp251x_spi_trans(spi, 1);
623 if (ret)
624 return ret;
625
626 /* Wait for oscillator startup timer after reset */
627 mdelay(MCP251X_OST_DELAY_MS);
284
285static void mcp251x_clean(struct net_device *net)
286{
287 struct mcp251x_priv *priv = netdev_priv(net);
288
289 if (priv->tx_skb || priv->tx_len)
290 net->stats.tx_errors++;
291 if (priv->tx_skb)

--- 342 unchanged lines hidden (view full) ---

634
635 priv->spi_tx_buf[0] = INSTRUCTION_RESET;
636 ret = mcp251x_spi_trans(spi, 1);
637 if (ret)
638 return ret;
639
640 /* Wait for oscillator startup timer after reset */
641 mdelay(MCP251X_OST_DELAY_MS);
628
642
629 reg = mcp251x_read_reg(spi, CANSTAT);
630 if ((reg & CANCTRL_REQOP_MASK) != CANCTRL_REQOP_CONF)
631 return -ENODEV;
632
633 return 0;
634}
635
636static int mcp251x_hw_probe(struct spi_device *spi)

--- 164 unchanged lines hidden (view full) ---

801 mcp251x_read_2regs(spi, CANINTF, &intf, &eflag);
802
803 /* mask out flags we don't care about */
804 intf &= CANINTF_RX | CANINTF_TX | CANINTF_ERR;
805
806 /* receive buffer 0 */
807 if (intf & CANINTF_RX0IF) {
808 mcp251x_hw_rx(spi, 0);
643 reg = mcp251x_read_reg(spi, CANSTAT);
644 if ((reg & CANCTRL_REQOP_MASK) != CANCTRL_REQOP_CONF)
645 return -ENODEV;
646
647 return 0;
648}
649
650static int mcp251x_hw_probe(struct spi_device *spi)

--- 164 unchanged lines hidden (view full) ---

815 mcp251x_read_2regs(spi, CANINTF, &intf, &eflag);
816
817 /* mask out flags we don't care about */
818 intf &= CANINTF_RX | CANINTF_TX | CANINTF_ERR;
819
820 /* receive buffer 0 */
821 if (intf & CANINTF_RX0IF) {
822 mcp251x_hw_rx(spi, 0);
809 /*
810 * Free one buffer ASAP
811 * (The MCP2515 does this automatically.)
823 /* Free one buffer ASAP
824 * (The MCP2515/25625 does this automatically.)
812 */
813 if (mcp251x_is_2510(spi))
814 mcp251x_write_bits(spi, CANINTF, CANINTF_RX0IF, 0x00);
815 }
816
817 /* receive buffer 1 */
818 if (intf & CANINTF_RX1IF) {
819 mcp251x_hw_rx(spi, 1);
825 */
826 if (mcp251x_is_2510(spi))
827 mcp251x_write_bits(spi, CANINTF, CANINTF_RX0IF, 0x00);
828 }
829
830 /* receive buffer 1 */
831 if (intf & CANINTF_RX1IF) {
832 mcp251x_hw_rx(spi, 1);
820 /* the MCP2515 does this automatically */
833 /* The MCP2515/25625 does this automatically. */
821 if (mcp251x_is_2510(spi))
822 clear_intf |= CANINTF_RX1IF;
823 }
824
825 /* any error or tx interrupt we need to clear? */
826 if (intf & (CANINTF_ERR | CANINTF_TX))
827 clear_intf |= intf & (CANINTF_ERR | CANINTF_TX);
828 if (clear_intf)

--- 158 unchanged lines hidden (view full) ---

987 {
988 .compatible = "microchip,mcp2510",
989 .data = (void *)CAN_MCP251X_MCP2510,
990 },
991 {
992 .compatible = "microchip,mcp2515",
993 .data = (void *)CAN_MCP251X_MCP2515,
994 },
834 if (mcp251x_is_2510(spi))
835 clear_intf |= CANINTF_RX1IF;
836 }
837
838 /* any error or tx interrupt we need to clear? */
839 if (intf & (CANINTF_ERR | CANINTF_TX))
840 clear_intf |= intf & (CANINTF_ERR | CANINTF_TX);
841 if (clear_intf)

--- 158 unchanged lines hidden (view full) ---

1000 {
1001 .compatible = "microchip,mcp2510",
1002 .data = (void *)CAN_MCP251X_MCP2510,
1003 },
1004 {
1005 .compatible = "microchip,mcp2515",
1006 .data = (void *)CAN_MCP251X_MCP2515,
1007 },
1008 {
1009 .compatible = "microchip,mcp25625",
1010 .data = (void *)CAN_MCP251X_MCP25625,
1011 },
995 { }
996};
997MODULE_DEVICE_TABLE(of, mcp251x_of_match);
998
999static const struct spi_device_id mcp251x_id_table[] = {
1000 {
1001 .name = "mcp2510",
1002 .driver_data = (kernel_ulong_t)CAN_MCP251X_MCP2510,
1003 },
1004 {
1005 .name = "mcp2515",
1006 .driver_data = (kernel_ulong_t)CAN_MCP251X_MCP2515,
1007 },
1012 { }
1013};
1014MODULE_DEVICE_TABLE(of, mcp251x_of_match);
1015
1016static const struct spi_device_id mcp251x_id_table[] = {
1017 {
1018 .name = "mcp2510",
1019 .driver_data = (kernel_ulong_t)CAN_MCP251X_MCP2510,
1020 },
1021 {
1022 .name = "mcp2515",
1023 .driver_data = (kernel_ulong_t)CAN_MCP251X_MCP2515,
1024 },
1025 {
1026 .name = "mcp25625",
1027 .driver_data = (kernel_ulong_t)CAN_MCP251X_MCP25625,
1028 },
1008 { }
1009};
1010MODULE_DEVICE_TABLE(spi, mcp251x_id_table);
1011
1012static int mcp251x_can_probe(struct spi_device *spi)
1013{
1014 const struct of_device_id *of_id = of_match_device(mcp251x_of_match,
1015 &spi->dev);

--- 224 unchanged lines hidden (view full) ---

1240 .id_table = mcp251x_id_table,
1241 .probe = mcp251x_can_probe,
1242 .remove = mcp251x_can_remove,
1243};
1244module_spi_driver(mcp251x_can_driver);
1245
1246MODULE_AUTHOR("Chris Elston <celston@katalix.com>, "
1247 "Christian Pellegrin <chripell@evolware.org>");
1029 { }
1030};
1031MODULE_DEVICE_TABLE(spi, mcp251x_id_table);
1032
1033static int mcp251x_can_probe(struct spi_device *spi)
1034{
1035 const struct of_device_id *of_id = of_match_device(mcp251x_of_match,
1036 &spi->dev);

--- 224 unchanged lines hidden (view full) ---

1261 .id_table = mcp251x_id_table,
1262 .probe = mcp251x_can_probe,
1263 .remove = mcp251x_can_remove,
1264};
1265module_spi_driver(mcp251x_can_driver);
1266
1267MODULE_AUTHOR("Chris Elston <celston@katalix.com>, "
1268 "Christian Pellegrin <chripell@evolware.org>");
1248MODULE_DESCRIPTION("Microchip 251x CAN driver");
1269MODULE_DESCRIPTION("Microchip 251x/25625 CAN driver");
1249MODULE_LICENSE("GPL v2");
1270MODULE_LICENSE("GPL v2");