diff options
Diffstat (limited to 'arch/arm/mach-exynos/board-smdk5250-spi.c')
-rw-r--r-- | arch/arm/mach-exynos/board-smdk5250-spi.c | 176 |
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 |