aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-exynos/board-smdk5250-spi.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-exynos/board-smdk5250-spi.c')
-rw-r--r--arch/arm/mach-exynos/board-smdk5250-spi.c176
1 files changed, 176 insertions, 0 deletions
diff --git a/arch/arm/mach-exynos/board-smdk5250-spi.c b/arch/arm/mach-exynos/board-smdk5250-spi.c
new file mode 100644
index 0000000..0d149de
--- /dev/null
+++ b/arch/arm/mach-exynos/board-smdk5250-spi.c
@@ -0,0 +1,176 @@
+/* linux/arch/arm/mach-exynos/board-smdk5250-spi.c
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/clk.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/gpio.h>
+#include <linux/err.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/s3c64xx-spi.h>
+
+#include <mach/spi-clocks.h>
+
+#include "board-smdk5250.h"
+
+#if defined(CONFIG_S3C64XX_DEV_SPI)
+static struct s3c64xx_spi_csinfo spi0_csi[] = {
+ [0] = {
+ .line = EXYNOS5_GPA2(1),
+ .set_level = gpio_set_value,
+ .fb_delay = 0x2,
+ },
+};
+
+static struct spi_board_info spi0_board_info[] __initdata = {
+ {
+ .modalias = "spidev",
+ .platform_data = NULL,
+ .max_speed_hz = 10*1000*1000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ .controller_data = &spi0_csi[0],
+ }
+};
+
+static struct s3c64xx_spi_csinfo spi1_csi[] = {
+ [0] = {
+ .line = EXYNOS5_GPA2(5),
+ .set_level = gpio_set_value,
+ .fb_delay = 0x2,
+ },
+};
+
+static struct spi_board_info spi1_board_info[] __initdata = {
+ {
+ .modalias = "spidev",
+ .platform_data = NULL,
+ .max_speed_hz = 10*1000*1000,
+ .bus_num = 1,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ .controller_data = &spi1_csi[0],
+ }
+};
+
+static struct s3c64xx_spi_csinfo spi2_csi[] = {
+ [0] = {
+ .line = EXYNOS5_GPB1(2),
+ .set_level = gpio_set_value,
+ .fb_delay = 0x2,
+ },
+};
+
+static struct spi_board_info spi2_board_info[] __initdata = {
+ {
+ .modalias = "spidev",
+ .platform_data = NULL,
+ .max_speed_hz = 10*1000*1000,
+ .bus_num = 2,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ .controller_data = &spi2_csi[0],
+ }
+};
+
+static struct platform_device *smdk5250_spi_devices[] __initdata = {
+ &exynos_device_spi0,
+ &exynos_device_spi1,
+ &exynos_device_spi2,
+};
+
+void __init exynos5_smdk5250_spi_init(void)
+{
+ struct clk *sclk = NULL;
+ struct clk *prnt = NULL;
+ struct device *spi0_dev = &exynos_device_spi0.dev;
+ struct device *spi1_dev = &exynos_device_spi1.dev;
+ struct device *spi2_dev = &exynos_device_spi2.dev;
+
+ sclk = clk_get(spi0_dev, "sclk_spi0");
+ if (IS_ERR(sclk))
+ dev_err(spi0_dev, "failed to get sclk for SPI-0\n");
+ prnt = clk_get(spi0_dev, "mout_mpll_user");
+ if (IS_ERR(prnt))
+ dev_err(spi0_dev, "failed to get prnt\n");
+ if (clk_set_parent(sclk, prnt))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ prnt->name, sclk->name);
+
+ clk_set_rate(sclk, 800 * 1000 * 1000);
+ clk_put(sclk);
+ clk_put(prnt);
+
+ if (!gpio_request(EXYNOS5_GPA2(1), "SPI_CS0")) {
+ gpio_direction_output(EXYNOS5_GPA2(1), 1);
+ s3c_gpio_cfgpin(EXYNOS5_GPA2(1), S3C_GPIO_SFN(1));
+ s3c_gpio_setpull(EXYNOS5_GPA2(1), S3C_GPIO_PULL_UP);
+ exynos_spi_set_info(0, EXYNOS_SPI_SRCCLK_SCLK,
+ ARRAY_SIZE(spi0_csi));
+ }
+
+ spi_register_board_info(spi0_board_info, ARRAY_SIZE(spi0_board_info));
+
+ sclk = clk_get(spi1_dev, "sclk_spi1");
+ if (IS_ERR(sclk))
+ dev_err(spi1_dev, "failed to get sclk for SPI-1\n");
+ prnt = clk_get(spi1_dev, "mout_mpll_user");
+ if (IS_ERR(prnt))
+ dev_err(spi1_dev, "failed to get prnt\n");
+ if (clk_set_parent(sclk, prnt))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ prnt->name, sclk->name);
+
+ clk_set_rate(sclk, 800 * 1000 * 1000);
+ clk_put(sclk);
+ clk_put(prnt);
+
+ if (!gpio_request(EXYNOS5_GPA2(5), "SPI_CS1")) {
+ gpio_direction_output(EXYNOS5_GPA2(5), 1);
+ s3c_gpio_cfgpin(EXYNOS5_GPA2(5), S3C_GPIO_SFN(1));
+ s3c_gpio_setpull(EXYNOS5_GPA2(5), S3C_GPIO_PULL_UP);
+ exynos_spi_set_info(1, EXYNOS_SPI_SRCCLK_SCLK,
+ ARRAY_SIZE(spi1_csi));
+ }
+
+ spi_register_board_info(spi1_board_info, ARRAY_SIZE(spi1_board_info));
+
+ sclk = clk_get(spi2_dev, "sclk_spi2");
+ if (IS_ERR(sclk))
+ dev_err(spi2_dev, "failed to get sclk for SPI-2\n");
+ prnt = clk_get(spi2_dev, "mout_mpll_user");
+ if (IS_ERR(prnt))
+ dev_err(spi2_dev, "failed to get prnt\n");
+ if (clk_set_parent(sclk, prnt))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ prnt->name, sclk->name);
+
+ clk_set_rate(sclk, 800 * 1000 * 1000);
+ clk_put(sclk);
+ clk_put(prnt);
+
+ if (!gpio_request(EXYNOS5_GPB1(2), "SPI_CS2")) {
+ gpio_direction_output(EXYNOS5_GPB1(2), 1);
+ s3c_gpio_cfgpin(EXYNOS5_GPB1(2), S3C_GPIO_SFN(1));
+ s3c_gpio_setpull(EXYNOS5_GPB1(2), S3C_GPIO_PULL_UP);
+ exynos_spi_set_info(2, EXYNOS_SPI_SRCCLK_SCLK,
+ ARRAY_SIZE(spi2_csi));
+ }
+
+ spi_register_board_info(spi2_board_info, ARRAY_SIZE(spi2_board_info));
+
+ platform_add_devices(smdk5250_spi_devices,
+ ARRAY_SIZE(smdk5250_spi_devices));
+}
+#endif