Blame view

drivers/of/of_spi.c 2.37 KB
284b01897   Grant Likely   spi: Add OF bindi...
1
2
3
4
5
6
7
  /*
   * SPI OF support routines
   * Copyright (C) 2008 Secret Lab Technologies Ltd.
   *
   * Support routines for deriving SPI device attachments from the device
   * tree.
   */
48a9e412b   Paul Gortmaker   drivers/of: Add m...
8
  #include <linux/module.h>
284b01897   Grant Likely   spi: Add OF bindi...
9
10
11
  #include <linux/of.h>
  #include <linux/device.h>
  #include <linux/spi/spi.h>
e38734449   Grant Likely   of/irq: Move irq_...
12
  #include <linux/of_irq.h>
284b01897   Grant Likely   spi: Add OF bindi...
13
14
15
16
17
  #include <linux/of_spi.h>
  
  /**
   * of_register_spi_devices - Register child devices onto the SPI bus
   * @master:	Pointer to spi_master device
284b01897   Grant Likely   spi: Add OF bindi...
18
   *
12b15e832   Anatolij Gustschin   of/spi: call of_r...
19
   * Registers an spi_device for each child node of master node which has a 'reg'
284b01897   Grant Likely   spi: Add OF bindi...
20
21
   * property.
   */
12b15e832   Anatolij Gustschin   of/spi: call of_r...
22
  void of_register_spi_devices(struct spi_master *master)
284b01897   Grant Likely   spi: Add OF bindi...
23
24
25
  {
  	struct spi_device *spi;
  	struct device_node *nc;
337148812   Jeremy Kerr   of: assume big-en...
26
  	const __be32 *prop;
284b01897   Grant Likely   spi: Add OF bindi...
27
28
  	int rc;
  	int len;
12b15e832   Anatolij Gustschin   of/spi: call of_r...
29
30
31
32
  	if (!master->dev.of_node)
  		return;
  
  	for_each_child_of_node(master->dev.of_node, nc) {
284b01897   Grant Likely   spi: Add OF bindi...
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
  		/* Alloc an spi_device */
  		spi = spi_alloc_device(master);
  		if (!spi) {
  			dev_err(&master->dev, "spi_device alloc error for %s
  ",
  				nc->full_name);
  			spi_dev_put(spi);
  			continue;
  		}
  
  		/* Select device driver */
  		if (of_modalias_node(nc, spi->modalias,
  				     sizeof(spi->modalias)) < 0) {
  			dev_err(&master->dev, "cannot find modalias for %s
  ",
  				nc->full_name);
  			spi_dev_put(spi);
  			continue;
  		}
  
  		/* Device address */
  		prop = of_get_property(nc, "reg", &len);
  		if (!prop || len < sizeof(*prop)) {
  			dev_err(&master->dev, "%s has no 'reg' property
  ",
  				nc->full_name);
  			spi_dev_put(spi);
  			continue;
  		}
337148812   Jeremy Kerr   of: assume big-en...
62
  		spi->chip_select = be32_to_cpup(prop);
284b01897   Grant Likely   spi: Add OF bindi...
63
64
65
66
67
68
  
  		/* Mode (clock phase/polarity/etc.) */
  		if (of_find_property(nc, "spi-cpha", NULL))
  			spi->mode |= SPI_CPHA;
  		if (of_find_property(nc, "spi-cpol", NULL))
  			spi->mode |= SPI_CPOL;
f618ebfcb   Wolfgang Ocker   of/spi: Support s...
69
70
  		if (of_find_property(nc, "spi-cs-high", NULL))
  			spi->mode |= SPI_CS_HIGH;
284b01897   Grant Likely   spi: Add OF bindi...
71
72
73
74
75
76
77
78
79
80
  
  		/* Device speed */
  		prop = of_get_property(nc, "spi-max-frequency", &len);
  		if (!prop || len < sizeof(*prop)) {
  			dev_err(&master->dev, "%s has no 'spi-max-frequency' property
  ",
  				nc->full_name);
  			spi_dev_put(spi);
  			continue;
  		}
337148812   Jeremy Kerr   of: assume big-en...
81
  		spi->max_speed_hz = be32_to_cpup(prop);
284b01897   Grant Likely   spi: Add OF bindi...
82
83
84
85
86
87
  
  		/* IRQ */
  		spi->irq = irq_of_parse_and_map(nc, 0);
  
  		/* Store a pointer to the node in the device structure */
  		of_node_get(nc);
d706c1b05   Grant Likely   driver-core: Add ...
88
  		spi->dev.of_node = nc;
284b01897   Grant Likely   spi: Add OF bindi...
89
90
91
92
93
94
95
96
97
98
99
100
101
102
  
  		/* Register the new device */
  		request_module(spi->modalias);
  		rc = spi_add_device(spi);
  		if (rc) {
  			dev_err(&master->dev, "spi_device register error %s
  ",
  				nc->full_name);
  			spi_dev_put(spi);
  		}
  
  	}
  }
  EXPORT_SYMBOL(of_register_spi_devices);