Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
  1/* linux/arch/arm/plat-s3c64xx/dev-spi.c
  2 *
  3 * Copyright (C) 2009 Samsung Electronics 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/kernel.h>
 12#include <linux/string.h>
 13#include <linux/platform_device.h>
 14#include <linux/dma-mapping.h>
 15#include <linux/gpio.h>
 16
 17#include <mach/dma.h>
 18#include <mach/map.h>
 19#include <mach/spi-clocks.h>
 20#include <mach/irqs.h>
 21
 22#include <plat/s3c64xx-spi.h>
 23#include <plat/gpio-cfg.h>
 24#include <plat/devs.h>
 25
 26static char *spi_src_clks[] = {
 27	[S3C64XX_SPI_SRCCLK_PCLK] = "pclk",
 28	[S3C64XX_SPI_SRCCLK_SPIBUS] = "spi-bus",
 29	[S3C64XX_SPI_SRCCLK_48M] = "spi_48m",
 30};
 31
 32/* SPI Controller platform_devices */
 33
 34/* Since we emulate multi-cs capability, we do not touch the GPC-3,7.
 35 * The emulated CS is toggled by board specific mechanism, as it can
 36 * be either some immediate GPIO or some signal out of some other
 37 * chip in between ... or some yet another way.
 38 * We simply do not assume anything about CS.
 39 */
 40static int s3c64xx_spi_cfg_gpio(struct platform_device *pdev)
 41{
 42	unsigned int base;
 43
 44	switch (pdev->id) {
 45	case 0:
 46		base = S3C64XX_GPC(0);
 47		break;
 48
 49	case 1:
 50		base = S3C64XX_GPC(4);
 51		break;
 52
 53	default:
 54		dev_err(&pdev->dev, "Invalid SPI Controller number!");
 55		return -EINVAL;
 56	}
 57
 58	s3c_gpio_cfgall_range(base, 3,
 59			      S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
 60
 61	return 0;
 62}
 63
 64static struct resource s3c64xx_spi0_resource[] = {
 65	[0] = {
 66		.start = S3C64XX_PA_SPI0,
 67		.end   = S3C64XX_PA_SPI0 + 0x100 - 1,
 68		.flags = IORESOURCE_MEM,
 69	},
 70	[1] = {
 71		.start = DMACH_SPI0_TX,
 72		.end   = DMACH_SPI0_TX,
 73		.flags = IORESOURCE_DMA,
 74	},
 75	[2] = {
 76		.start = DMACH_SPI0_RX,
 77		.end   = DMACH_SPI0_RX,
 78		.flags = IORESOURCE_DMA,
 79	},
 80	[3] = {
 81		.start = IRQ_SPI0,
 82		.end   = IRQ_SPI0,
 83		.flags = IORESOURCE_IRQ,
 84	},
 85};
 86
 87static struct s3c64xx_spi_info s3c64xx_spi0_pdata = {
 88	.cfg_gpio = s3c64xx_spi_cfg_gpio,
 89	.fifo_lvl_mask = 0x7f,
 90	.rx_lvl_offset = 13,
 91	.tx_st_done = 21,
 92};
 93
 94static u64 spi_dmamask = DMA_BIT_MASK(32);
 95
 96struct platform_device s3c64xx_device_spi0 = {
 97	.name		  = "s3c64xx-spi",
 98	.id		  = 0,
 99	.num_resources	  = ARRAY_SIZE(s3c64xx_spi0_resource),
100	.resource	  = s3c64xx_spi0_resource,
101	.dev = {
102		.dma_mask		= &spi_dmamask,
103		.coherent_dma_mask	= DMA_BIT_MASK(32),
104		.platform_data = &s3c64xx_spi0_pdata,
105	},
106};
107EXPORT_SYMBOL(s3c64xx_device_spi0);
108
109static struct resource s3c64xx_spi1_resource[] = {
110	[0] = {
111		.start = S3C64XX_PA_SPI1,
112		.end   = S3C64XX_PA_SPI1 + 0x100 - 1,
113		.flags = IORESOURCE_MEM,
114	},
115	[1] = {
116		.start = DMACH_SPI1_TX,
117		.end   = DMACH_SPI1_TX,
118		.flags = IORESOURCE_DMA,
119	},
120	[2] = {
121		.start = DMACH_SPI1_RX,
122		.end   = DMACH_SPI1_RX,
123		.flags = IORESOURCE_DMA,
124	},
125	[3] = {
126		.start = IRQ_SPI1,
127		.end   = IRQ_SPI1,
128		.flags = IORESOURCE_IRQ,
129	},
130};
131
132static struct s3c64xx_spi_info s3c64xx_spi1_pdata = {
133	.cfg_gpio = s3c64xx_spi_cfg_gpio,
134	.fifo_lvl_mask = 0x7f,
135	.rx_lvl_offset = 13,
136	.tx_st_done = 21,
137};
138
139struct platform_device s3c64xx_device_spi1 = {
140	.name		  = "s3c64xx-spi",
141	.id		  = 1,
142	.num_resources	  = ARRAY_SIZE(s3c64xx_spi1_resource),
143	.resource	  = s3c64xx_spi1_resource,
144	.dev = {
145		.dma_mask		= &spi_dmamask,
146		.coherent_dma_mask	= DMA_BIT_MASK(32),
147		.platform_data = &s3c64xx_spi1_pdata,
148	},
149};
150EXPORT_SYMBOL(s3c64xx_device_spi1);
151
152void __init s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs)
153{
154	struct s3c64xx_spi_info *pd;
155
156	/* Reject invalid configuration */
157	if (!num_cs || src_clk_nr < 0
158			|| src_clk_nr > S3C64XX_SPI_SRCCLK_48M) {
159		printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__);
160		return;
161	}
162
163	switch (cntrlr) {
164	case 0:
165		pd = &s3c64xx_spi0_pdata;
166		break;
167	case 1:
168		pd = &s3c64xx_spi1_pdata;
169		break;
170	default:
171		printk(KERN_ERR "%s: Invalid SPI controller(%d)\n",
172							__func__, cntrlr);
173		return;
174	}
175
176	pd->num_cs = num_cs;
177	pd->src_clk_nr = src_clk_nr;
178	pd->src_clk_name = spi_src_clks[src_clk_nr];
179}