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"); |