Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

can: sja1000: generic OF platform bus driver

This patch adds a generic driver for SJA1000 chips on the OpenFirmware
platform bus found on embedded PowerPC systems. You need a SJA1000 node
definition in your flattened device tree source (DTS) file similar to:

can@3,100 {
compatible = "nxp,sja1000";
reg = <3 0x100 0x80>;
interrupts = <2 0>;
interrupt-parent = <&mpic>;
nxp,external-clock-frequency = <16000000>;
};

See also Documentation/powerpc/dts-bindings/can/sja1000.txt.

CC: devicetree-discuss@ozlabs.org
Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Wolfgang Grandegger and committed by
David S. Miller
d1a277c5 255a9154

+299
+53
Documentation/powerpc/dts-bindings/can/sja1000.txt
··· 1 + Memory mapped SJA1000 CAN controller from NXP (formerly Philips) 2 + 3 + Required properties: 4 + 5 + - compatible : should be "nxp,sja1000". 6 + 7 + - reg : should specify the chip select, address offset and size required 8 + to map the registers of the SJA1000. The size is usually 0x80. 9 + 10 + - interrupts: property with a value describing the interrupt source 11 + (number and sensitivity) required for the SJA1000. 12 + 13 + Optional properties: 14 + 15 + - nxp,external-clock-frequency : Frequency of the external oscillator 16 + clock in Hz. Note that the internal clock frequency used by the 17 + SJA1000 is half of that value. If not specified, a default value 18 + of 16000000 (16 MHz) is used. 19 + 20 + - nxp,tx-output-mode : operation mode of the TX output control logic: 21 + <0x0> : bi-phase output mode 22 + <0x1> : normal output mode (default) 23 + <0x2> : test output mode 24 + <0x3> : clock output mode 25 + 26 + - nxp,tx-output-config : TX output pin configuration: 27 + <0x01> : TX0 invert 28 + <0x02> : TX0 pull-down (default) 29 + <0x04> : TX0 pull-up 30 + <0x06> : TX0 push-pull 31 + <0x08> : TX1 invert 32 + <0x10> : TX1 pull-down 33 + <0x20> : TX1 pull-up 34 + <0x30> : TX1 push-pull 35 + 36 + - nxp,clock-out-frequency : clock frequency in Hz on the CLKOUT pin. 37 + If not specified or if the specified value is 0, the CLKOUT pin 38 + will be disabled. 39 + 40 + - nxp,no-comparator-bypass : Allows to disable the CAN input comperator. 41 + 42 + For futher information, please have a look to the SJA1000 data sheet. 43 + 44 + Examples: 45 + 46 + can@3,100 { 47 + compatible = "nxp,sja1000"; 48 + reg = <3 0x100 0x80>; 49 + interrupts = <2 0>; 50 + interrupt-parent = <&mpic>; 51 + nxp,external-clock-frequency = <16000000>; 52 + }; 53 +
+9
drivers/net/can/Kconfig
··· 51 51 boards from Phytec (http://www.phytec.de) like the PCM027, 52 52 PCM038. 53 53 54 + config CAN_SJA1000_OF_PLATFORM 55 + depends on CAN_SJA1000 && PPC_OF 56 + tristate "Generic OF Platform Bus based SJA1000 driver" 57 + ---help--- 58 + This driver adds support for the SJA1000 chips connected to 59 + the OpenFirmware "platform bus" found on embedded systems with 60 + OpenFirmware bindings, e.g. if you have a PowerPC based system 61 + you may want to enable this option. 62 + 54 63 config CAN_EMS_PCI 55 64 tristate "EMS CPC-PCI and CPC-PCIe Card" 56 65 depends on PCI && CAN_SJA1000
+1
drivers/net/can/sja1000/Makefile
··· 4 4 5 5 obj-$(CONFIG_CAN_SJA1000) += sja1000.o 6 6 obj-$(CONFIG_CAN_SJA1000_PLATFORM) += sja1000_platform.o 7 + obj-$(CONFIG_CAN_SJA1000_OF_PLATFORM) += sja1000_of_platform.o 7 8 obj-$(CONFIG_CAN_EMS_PCI) += ems_pci.o 8 9 obj-$(CONFIG_CAN_KVASER_PCI) += kvaser_pci.o 9 10
+233
drivers/net/can/sja1000/sja1000_of_platform.c
··· 1 + /* 2 + * Driver for SJA1000 CAN controllers on the OpenFirmware platform bus 3 + * 4 + * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the version 2 of the GNU General Public License 8 + * as published by the Free Software Foundation 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + * 15 + * You should have received a copy of the GNU General Public License 16 + * along with this program; if not, write to the Free Software Foundation, 17 + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 + */ 19 + 20 + /* This is a generic driver for SJA1000 chips on the OpenFirmware platform 21 + * bus found on embedded PowerPC systems. You need a SJA1000 CAN node 22 + * definition in your flattened device tree source (DTS) file similar to: 23 + * 24 + * can@3,100 { 25 + * compatible = "nxp,sja1000"; 26 + * reg = <3 0x100 0x80>; 27 + * interrupts = <2 0>; 28 + * interrupt-parent = <&mpic>; 29 + * nxp,external-clock-frequency = <16000000>; 30 + * }; 31 + * 32 + * See "Documentation/powerpc/dts-bindings/can/sja1000.txt" for further 33 + * information. 34 + */ 35 + 36 + #include <linux/kernel.h> 37 + #include <linux/module.h> 38 + #include <linux/interrupt.h> 39 + #include <linux/netdevice.h> 40 + #include <linux/delay.h> 41 + #include <linux/can.h> 42 + #include <linux/can/dev.h> 43 + 44 + #include <linux/of_platform.h> 45 + #include <asm/prom.h> 46 + 47 + #include "sja1000.h" 48 + 49 + #define DRV_NAME "sja1000_of_platform" 50 + 51 + MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>"); 52 + MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the OF platform bus"); 53 + MODULE_LICENSE("GPL v2"); 54 + 55 + #define SJA1000_OFP_CAN_CLOCK (16000000 / 2) 56 + 57 + #define SJA1000_OFP_OCR OCR_TX0_PULLDOWN 58 + #define SJA1000_OFP_CDR (CDR_CBP | CDR_CLK_OFF) 59 + 60 + static u8 sja1000_ofp_read_reg(const struct sja1000_priv *priv, int reg) 61 + { 62 + return in_8(priv->reg_base + reg); 63 + } 64 + 65 + static void sja1000_ofp_write_reg(const struct sja1000_priv *priv, 66 + int reg, u8 val) 67 + { 68 + out_8(priv->reg_base + reg, val); 69 + } 70 + 71 + static int __devexit sja1000_ofp_remove(struct of_device *ofdev) 72 + { 73 + struct net_device *dev = dev_get_drvdata(&ofdev->dev); 74 + struct sja1000_priv *priv = netdev_priv(dev); 75 + struct device_node *np = ofdev->node; 76 + struct resource res; 77 + 78 + dev_set_drvdata(&ofdev->dev, NULL); 79 + 80 + unregister_sja1000dev(dev); 81 + free_sja1000dev(dev); 82 + iounmap(priv->reg_base); 83 + irq_dispose_mapping(dev->irq); 84 + 85 + of_address_to_resource(np, 0, &res); 86 + release_mem_region(res.start, resource_size(&res)); 87 + 88 + return 0; 89 + } 90 + 91 + static int __devinit sja1000_ofp_probe(struct of_device *ofdev, 92 + const struct of_device_id *id) 93 + { 94 + struct device_node *np = ofdev->node; 95 + struct net_device *dev; 96 + struct sja1000_priv *priv; 97 + struct resource res; 98 + const u32 *prop; 99 + int err, irq, res_size, prop_size; 100 + void __iomem *base; 101 + 102 + err = of_address_to_resource(np, 0, &res); 103 + if (err) { 104 + dev_err(&ofdev->dev, "invalid address\n"); 105 + return err; 106 + } 107 + 108 + res_size = resource_size(&res); 109 + 110 + if (!request_mem_region(res.start, res_size, DRV_NAME)) { 111 + dev_err(&ofdev->dev, "couldn't request %#x..%#x\n", 112 + res.start, res.end); 113 + return -EBUSY; 114 + } 115 + 116 + base = ioremap_nocache(res.start, res_size); 117 + if (!base) { 118 + dev_err(&ofdev->dev, "couldn't ioremap %#x..%#x\n", 119 + res.start, res.end); 120 + err = -ENOMEM; 121 + goto exit_release_mem; 122 + } 123 + 124 + irq = irq_of_parse_and_map(np, 0); 125 + if (irq == NO_IRQ) { 126 + dev_err(&ofdev->dev, "no irq found\n"); 127 + err = -ENODEV; 128 + goto exit_unmap_mem; 129 + } 130 + 131 + dev = alloc_sja1000dev(0); 132 + if (!dev) { 133 + err = -ENOMEM; 134 + goto exit_dispose_irq; 135 + } 136 + 137 + priv = netdev_priv(dev); 138 + 139 + priv->read_reg = sja1000_ofp_read_reg; 140 + priv->write_reg = sja1000_ofp_write_reg; 141 + 142 + prop = of_get_property(np, "nxp,external-clock-frequency", &prop_size); 143 + if (prop && (prop_size == sizeof(u32))) 144 + priv->can.clock.freq = *prop / 2; 145 + else 146 + priv->can.clock.freq = SJA1000_OFP_CAN_CLOCK; /* default */ 147 + 148 + prop = of_get_property(np, "nxp,tx-output-mode", &prop_size); 149 + if (prop && (prop_size == sizeof(u32))) 150 + priv->ocr |= *prop & OCR_MODE_MASK; 151 + else 152 + priv->ocr |= OCR_MODE_NORMAL; /* default */ 153 + 154 + prop = of_get_property(np, "nxp,tx-output-config", &prop_size); 155 + if (prop && (prop_size == sizeof(u32))) 156 + priv->ocr |= (*prop << OCR_TX_SHIFT) & OCR_TX_MASK; 157 + else 158 + priv->ocr |= OCR_TX0_PULLDOWN; /* default */ 159 + 160 + prop = of_get_property(np, "nxp,clock-out-frequency", &prop_size); 161 + if (prop && (prop_size == sizeof(u32)) && *prop) { 162 + u32 divider = priv->can.clock.freq * 2 / *prop; 163 + 164 + if (divider > 1) 165 + priv->cdr |= divider / 2 - 1; 166 + else 167 + priv->cdr |= CDR_CLKOUT_MASK; 168 + } else { 169 + priv->cdr |= CDR_CLK_OFF; /* default */ 170 + } 171 + 172 + prop = of_get_property(np, "nxp,no-comparator-bypass", NULL); 173 + if (!prop) 174 + priv->cdr |= CDR_CBP; /* default */ 175 + 176 + priv->irq_flags = IRQF_SHARED; 177 + priv->reg_base = base; 178 + 179 + dev->irq = irq; 180 + 181 + dev_info(&ofdev->dev, 182 + "reg_base=0x%p irq=%d clock=%d ocr=0x%02x cdr=0x%02x\n", 183 + priv->reg_base, dev->irq, priv->can.clock.freq, 184 + priv->ocr, priv->cdr); 185 + 186 + dev_set_drvdata(&ofdev->dev, dev); 187 + SET_NETDEV_DEV(dev, &ofdev->dev); 188 + 189 + err = register_sja1000dev(dev); 190 + if (err) { 191 + dev_err(&ofdev->dev, "registering %s failed (err=%d)\n", 192 + DRV_NAME, err); 193 + goto exit_free_sja1000; 194 + } 195 + 196 + return 0; 197 + 198 + exit_free_sja1000: 199 + free_sja1000dev(dev); 200 + exit_dispose_irq: 201 + irq_dispose_mapping(irq); 202 + exit_unmap_mem: 203 + iounmap(base); 204 + exit_release_mem: 205 + release_mem_region(res.start, res_size); 206 + 207 + return err; 208 + } 209 + 210 + static struct of_device_id __devinitdata sja1000_ofp_table[] = { 211 + {.compatible = "nxp,sja1000"}, 212 + {}, 213 + }; 214 + 215 + static struct of_platform_driver sja1000_ofp_driver = { 216 + .owner = THIS_MODULE, 217 + .name = DRV_NAME, 218 + .probe = sja1000_ofp_probe, 219 + .remove = __devexit_p(sja1000_ofp_remove), 220 + .match_table = sja1000_ofp_table, 221 + }; 222 + 223 + static int __init sja1000_ofp_init(void) 224 + { 225 + return of_register_platform_driver(&sja1000_ofp_driver); 226 + } 227 + module_init(sja1000_ofp_init); 228 + 229 + static void __exit sja1000_ofp_exit(void) 230 + { 231 + return of_unregister_platform_driver(&sja1000_ofp_driver); 232 + }; 233 + module_exit(sja1000_ofp_exit);
+3
include/linux/can/platform/sja1000.h
··· 13 13 #define OCR_MODE_TEST 0x01 14 14 #define OCR_MODE_NORMAL 0x02 15 15 #define OCR_MODE_CLOCK 0x03 16 + #define OCR_MODE_MASK 0x07 16 17 #define OCR_TX0_INVERT 0x04 17 18 #define OCR_TX0_PULLDOWN 0x08 18 19 #define OCR_TX0_PULLUP 0x10 ··· 22 21 #define OCR_TX1_PULLDOWN 0x40 23 22 #define OCR_TX1_PULLUP 0x80 24 23 #define OCR_TX1_PUSHPULL 0xc0 24 + #define OCR_TX_MASK 0xfc 25 + #define OCR_TX_SHIFT 2 25 26 26 27 struct sja1000_platform_data { 27 28 u32 clock; /* CAN bus oscillator frequency in Hz */