diff options
author | Roland Stigge <stigge@antcom.de> | 2012-08-22 09:49:18 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-08-22 15:00:51 -0400 |
commit | 6d3952a7dfa80919842bbe01ac7f693d40a1eb84 (patch) | |
tree | c765e9c452f9fe92ab99bdfffc4bb27505a5bce6 /drivers/spi | |
parent | f6f46de1063c8829713cd9d5b960dd8cb66cde8b (diff) |
spi/pl022: Add devicetree support
This patch adds device tree support to the spi-pl022 driver.
Based on the initial patch by Alexandre Pereira da Silva <aletes.xgr@gmail.com>
Signed-off-by: Roland Stigge <stigge@antcom.de>
Acked-by: Alexandre Pereira da Silva <aletes.xgr@gmail.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/spi-pl022.c | 79 |
1 files changed, 70 insertions, 9 deletions
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index cf47802f00c9..959f2acff2d3 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/scatterlist.h> | 41 | #include <linux/scatterlist.h> |
42 | #include <linux/pm_runtime.h> | 42 | #include <linux/pm_runtime.h> |
43 | #include <linux/gpio.h> | 43 | #include <linux/gpio.h> |
44 | #include <linux/of_gpio.h> | ||
44 | 45 | ||
45 | /* | 46 | /* |
46 | * This macro is used to define some register default values. | 47 | * This macro is used to define some register default values. |
@@ -1778,12 +1779,14 @@ static const struct pl022_config_chip pl022_default_chip_info = { | |||
1778 | static int pl022_setup(struct spi_device *spi) | 1779 | static int pl022_setup(struct spi_device *spi) |
1779 | { | 1780 | { |
1780 | struct pl022_config_chip const *chip_info; | 1781 | struct pl022_config_chip const *chip_info; |
1782 | struct pl022_config_chip chip_info_dt; | ||
1781 | struct chip_data *chip; | 1783 | struct chip_data *chip; |
1782 | struct ssp_clock_params clk_freq = { .cpsdvsr = 0, .scr = 0}; | 1784 | struct ssp_clock_params clk_freq = { .cpsdvsr = 0, .scr = 0}; |
1783 | int status = 0; | 1785 | int status = 0; |
1784 | struct pl022 *pl022 = spi_master_get_devdata(spi->master); | 1786 | struct pl022 *pl022 = spi_master_get_devdata(spi->master); |
1785 | unsigned int bits = spi->bits_per_word; | 1787 | unsigned int bits = spi->bits_per_word; |
1786 | u32 tmp; | 1788 | u32 tmp; |
1789 | struct device_node *np = spi->dev.of_node; | ||
1787 | 1790 | ||
1788 | if (!spi->max_speed_hz) | 1791 | if (!spi->max_speed_hz) |
1789 | return -EINVAL; | 1792 | return -EINVAL; |
@@ -1806,10 +1809,32 @@ static int pl022_setup(struct spi_device *spi) | |||
1806 | chip_info = spi->controller_data; | 1809 | chip_info = spi->controller_data; |
1807 | 1810 | ||
1808 | if (chip_info == NULL) { | 1811 | if (chip_info == NULL) { |
1809 | chip_info = &pl022_default_chip_info; | 1812 | if (np) { |
1810 | /* spi_board_info.controller_data not is supplied */ | 1813 | chip_info_dt = pl022_default_chip_info; |
1811 | dev_dbg(&spi->dev, | 1814 | |
1812 | "using default controller_data settings\n"); | 1815 | chip_info_dt.hierarchy = SSP_MASTER; |
1816 | of_property_read_u32(np, "pl022,interface", | ||
1817 | &chip_info_dt.iface); | ||
1818 | of_property_read_u32(np, "pl022,com-mode", | ||
1819 | &chip_info_dt.com_mode); | ||
1820 | of_property_read_u32(np, "pl022,rx-level-trig", | ||
1821 | &chip_info_dt.rx_lev_trig); | ||
1822 | of_property_read_u32(np, "pl022,tx-level-trig", | ||
1823 | &chip_info_dt.tx_lev_trig); | ||
1824 | of_property_read_u32(np, "pl022,ctrl-len", | ||
1825 | &chip_info_dt.ctrl_len); | ||
1826 | of_property_read_u32(np, "pl022,wait-state", | ||
1827 | &chip_info_dt.wait_state); | ||
1828 | of_property_read_u32(np, "pl022,duplex", | ||
1829 | &chip_info_dt.duplex); | ||
1830 | |||
1831 | chip_info = &chip_info_dt; | ||
1832 | } else { | ||
1833 | chip_info = &pl022_default_chip_info; | ||
1834 | /* spi_board_info.controller_data not is supplied */ | ||
1835 | dev_dbg(&spi->dev, | ||
1836 | "using default controller_data settings\n"); | ||
1837 | } | ||
1813 | } else | 1838 | } else |
1814 | dev_dbg(&spi->dev, | 1839 | dev_dbg(&spi->dev, |
1815 | "using user supplied controller_data settings\n"); | 1840 | "using user supplied controller_data settings\n"); |
@@ -2006,7 +2031,8 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2006 | struct pl022_ssp_controller *platform_info = adev->dev.platform_data; | 2031 | struct pl022_ssp_controller *platform_info = adev->dev.platform_data; |
2007 | struct spi_master *master; | 2032 | struct spi_master *master; |
2008 | struct pl022 *pl022 = NULL; /*Data for this driver */ | 2033 | struct pl022 *pl022 = NULL; /*Data for this driver */ |
2009 | int status = 0, i; | 2034 | struct device_node *np = adev->dev.of_node; |
2035 | int status = 0, i, num_cs; | ||
2010 | 2036 | ||
2011 | dev_info(&adev->dev, | 2037 | dev_info(&adev->dev, |
2012 | "ARM PL022 driver, device ID: 0x%08x\n", adev->periphid); | 2038 | "ARM PL022 driver, device ID: 0x%08x\n", adev->periphid); |
@@ -2016,9 +2042,19 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2016 | goto err_no_pdata; | 2042 | goto err_no_pdata; |
2017 | } | 2043 | } |
2018 | 2044 | ||
2045 | if (platform_info->num_chipselect) { | ||
2046 | num_cs = platform_info->num_chipselect; | ||
2047 | } else if (IS_ENABLED(CONFIG_OF)) { | ||
2048 | of_property_read_u32(np, "num-cs", &num_cs); | ||
2049 | } else { | ||
2050 | dev_err(&adev->dev, "probe: no chip select defined\n"); | ||
2051 | status = -ENODEV; | ||
2052 | goto err_no_pdata; | ||
2053 | } | ||
2054 | |||
2019 | /* Allocate master with space for data */ | 2055 | /* Allocate master with space for data */ |
2020 | master = spi_alloc_master(dev, sizeof(struct pl022) + sizeof(int) * | 2056 | master = spi_alloc_master(dev, sizeof(struct pl022) + sizeof(int) * |
2021 | platform_info->num_chipselect); | 2057 | num_cs); |
2022 | if (master == NULL) { | 2058 | if (master == NULL) { |
2023 | dev_err(&adev->dev, "probe - cannot alloc SPI master\n"); | 2059 | dev_err(&adev->dev, "probe - cannot alloc SPI master\n"); |
2024 | status = -ENOMEM; | 2060 | status = -ENOMEM; |
@@ -2038,17 +2074,41 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2038 | * on this board | 2074 | * on this board |
2039 | */ | 2075 | */ |
2040 | master->bus_num = platform_info->bus_id; | 2076 | master->bus_num = platform_info->bus_id; |
2041 | master->num_chipselect = platform_info->num_chipselect; | 2077 | master->num_chipselect = num_cs; |
2042 | master->cleanup = pl022_cleanup; | 2078 | master->cleanup = pl022_cleanup; |
2043 | master->setup = pl022_setup; | 2079 | master->setup = pl022_setup; |
2044 | master->prepare_transfer_hardware = pl022_prepare_transfer_hardware; | 2080 | master->prepare_transfer_hardware = pl022_prepare_transfer_hardware; |
2045 | master->transfer_one_message = pl022_transfer_one_message; | 2081 | master->transfer_one_message = pl022_transfer_one_message; |
2046 | master->unprepare_transfer_hardware = pl022_unprepare_transfer_hardware; | 2082 | master->unprepare_transfer_hardware = pl022_unprepare_transfer_hardware; |
2047 | master->rt = platform_info->rt; | 2083 | master->rt = platform_info->rt; |
2084 | master->dev.of_node = dev->of_node; | ||
2048 | 2085 | ||
2049 | if (platform_info->num_chipselect && platform_info->chipselects) | 2086 | if (platform_info->num_chipselect && platform_info->chipselects) { |
2050 | for (i = 0; i < platform_info->num_chipselect; i++) | 2087 | for (i = 0; i < num_cs; i++) |
2051 | pl022->chipselects[i] = platform_info->chipselects[i]; | 2088 | pl022->chipselects[i] = platform_info->chipselects[i]; |
2089 | } else if (IS_ENABLED(CONFIG_OF)) { | ||
2090 | for (i = 0; i < num_cs; i++) { | ||
2091 | int cs_gpio = of_get_named_gpio(np, "cs-gpios", i); | ||
2092 | |||
2093 | if (cs_gpio == -EPROBE_DEFER) { | ||
2094 | status = -EPROBE_DEFER; | ||
2095 | goto err_no_gpio; | ||
2096 | } | ||
2097 | |||
2098 | pl022->chipselects[i] = cs_gpio; | ||
2099 | |||
2100 | if (gpio_is_valid(cs_gpio)) { | ||
2101 | if (gpio_request(cs_gpio, "ssp-pl022")) | ||
2102 | dev_err(&adev->dev, | ||
2103 | "could not request %d gpio\n", | ||
2104 | cs_gpio); | ||
2105 | else if (gpio_direction_output(cs_gpio, 1)) | ||
2106 | dev_err(&adev->dev, | ||
2107 | "could set gpio %d as output\n", | ||
2108 | cs_gpio); | ||
2109 | } | ||
2110 | } | ||
2111 | } | ||
2052 | 2112 | ||
2053 | /* | 2113 | /* |
2054 | * Supports mode 0-3, loopback, and active low CS. Transfers are | 2114 | * Supports mode 0-3, loopback, and active low CS. Transfers are |
@@ -2158,6 +2218,7 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2158 | err_no_ioremap: | 2218 | err_no_ioremap: |
2159 | amba_release_regions(adev); | 2219 | amba_release_regions(adev); |
2160 | err_no_ioregion: | 2220 | err_no_ioregion: |
2221 | err_no_gpio: | ||
2161 | spi_master_put(master); | 2222 | spi_master_put(master); |
2162 | err_no_master: | 2223 | err_no_master: |
2163 | err_no_pdata: | 2224 | err_no_pdata: |