• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/arch/arm/mach-s5p6442/
1/* linux/arch/arm/mach-s5p6442/dev-spi.c
2 *
3 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
4 *	Jaswinder Singh <jassi.brar@samsung.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/platform_device.h>
12#include <linux/dma-mapping.h>
13#include <linux/gpio.h>
14
15#include <mach/dma.h>
16#include <mach/map.h>
17#include <mach/irqs.h>
18#include <mach/spi-clocks.h>
19
20#include <plat/s3c64xx-spi.h>
21#include <plat/gpio-cfg.h>
22
23static char *spi_src_clks[] = {
24	[S5P6442_SPI_SRCCLK_PCLK] = "pclk",
25	[S5P6442_SPI_SRCCLK_SCLK] = "spi_epll",
26};
27
28/* SPI Controller platform_devices */
29
30/* Since we emulate multi-cs capability, we do not touch the CS.
31 * The emulated CS is toggled by board specific mechanism, as it can
32 * be either some immediate GPIO or some signal out of some other
33 * chip in between ... or some yet another way.
34 * We simply do not assume anything about CS.
35 */
36static int s5p6442_spi_cfg_gpio(struct platform_device *pdev)
37{
38	switch (pdev->id) {
39	case 0:
40		s3c_gpio_cfgpin(S5P6442_GPB(0), S3C_GPIO_SFN(2));
41		s3c_gpio_cfgpin(S5P6442_GPB(2), S3C_GPIO_SFN(2));
42		s3c_gpio_cfgpin(S5P6442_GPB(3), S3C_GPIO_SFN(2));
43		s3c_gpio_setpull(S5P6442_GPB(0), S3C_GPIO_PULL_UP);
44		s3c_gpio_setpull(S5P6442_GPB(2), S3C_GPIO_PULL_UP);
45		s3c_gpio_setpull(S5P6442_GPB(3), S3C_GPIO_PULL_UP);
46		break;
47
48	default:
49		dev_err(&pdev->dev, "Invalid SPI Controller number!");
50		return -EINVAL;
51	}
52
53	return 0;
54}
55
56static struct resource s5p6442_spi0_resource[] = {
57	[0] = {
58		.start = S5P6442_PA_SPI,
59		.end   = S5P6442_PA_SPI + 0x100 - 1,
60		.flags = IORESOURCE_MEM,
61	},
62	[1] = {
63		.start = DMACH_SPI0_TX,
64		.end   = DMACH_SPI0_TX,
65		.flags = IORESOURCE_DMA,
66	},
67	[2] = {
68		.start = DMACH_SPI0_RX,
69		.end   = DMACH_SPI0_RX,
70		.flags = IORESOURCE_DMA,
71	},
72	[3] = {
73		.start = IRQ_SPI0,
74		.end   = IRQ_SPI0,
75		.flags = IORESOURCE_IRQ,
76	},
77};
78
79static struct s3c64xx_spi_info s5p6442_spi0_pdata = {
80	.cfg_gpio = s5p6442_spi_cfg_gpio,
81	.fifo_lvl_mask = 0x1ff,
82	.rx_lvl_offset = 15,
83};
84
85static u64 spi_dmamask = DMA_BIT_MASK(32);
86
87struct platform_device s5p6442_device_spi = {
88	.name		  = "s3c64xx-spi",
89	.id		  = 0,
90	.num_resources	  = ARRAY_SIZE(s5p6442_spi0_resource),
91	.resource	  = s5p6442_spi0_resource,
92	.dev = {
93		.dma_mask		= &spi_dmamask,
94		.coherent_dma_mask	= DMA_BIT_MASK(32),
95		.platform_data = &s5p6442_spi0_pdata,
96	},
97};
98
99void __init s5p6442_spi_set_info(int cntrlr, int src_clk_nr, int num_cs)
100{
101	struct s3c64xx_spi_info *pd;
102
103	/* Reject invalid configuration */
104	if (!num_cs || src_clk_nr < 0
105			|| src_clk_nr > S5P6442_SPI_SRCCLK_SCLK) {
106		printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__);
107		return;
108	}
109
110	switch (cntrlr) {
111	case 0:
112		pd = &s5p6442_spi0_pdata;
113		break;
114	default:
115		printk(KERN_ERR "%s: Invalid SPI controller(%d)\n",
116							__func__, cntrlr);
117		return;
118	}
119
120	pd->num_cs = num_cs;
121	pd->src_clk_nr = src_clk_nr;
122	pd->src_clk_name = spi_src_clks[src_clk_nr];
123}
124