Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.8.
  1/* linux/arch/arm/mach-s5pv210/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	[S5PV210_SPI_SRCCLK_PCLK] = "pclk",
 25	[S5PV210_SPI_SRCCLK_SCLK] = "sclk_spi",
 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 s5pv210_spi_cfg_gpio(struct platform_device *pdev)
 37{
 38	unsigned int base;
 39
 40	switch (pdev->id) {
 41	case 0:
 42		base = S5PV210_GPB(0);
 43		break;
 44
 45	case 1:
 46		base = S5PV210_GPB(4);
 47		break;
 48
 49	default:
 50		dev_err(&pdev->dev, "Invalid SPI Controller number!");
 51		return -EINVAL;
 52	}
 53
 54	s3c_gpio_cfgall_range(base, 3,
 55			      S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
 56
 57	return 0;
 58}
 59
 60static struct resource s5pv210_spi0_resource[] = {
 61	[0] = {
 62		.start = S5PV210_PA_SPI0,
 63		.end   = S5PV210_PA_SPI0 + 0x100 - 1,
 64		.flags = IORESOURCE_MEM,
 65	},
 66	[1] = {
 67		.start = DMACH_SPI0_TX,
 68		.end   = DMACH_SPI0_TX,
 69		.flags = IORESOURCE_DMA,
 70	},
 71	[2] = {
 72		.start = DMACH_SPI0_RX,
 73		.end   = DMACH_SPI0_RX,
 74		.flags = IORESOURCE_DMA,
 75	},
 76	[3] = {
 77		.start = IRQ_SPI0,
 78		.end   = IRQ_SPI0,
 79		.flags = IORESOURCE_IRQ,
 80	},
 81};
 82
 83static struct s3c64xx_spi_info s5pv210_spi0_pdata = {
 84	.cfg_gpio = s5pv210_spi_cfg_gpio,
 85	.fifo_lvl_mask = 0x1ff,
 86	.rx_lvl_offset = 15,
 87	.high_speed = 1,
 88	.tx_st_done = 25,
 89};
 90
 91static u64 spi_dmamask = DMA_BIT_MASK(32);
 92
 93struct platform_device s5pv210_device_spi0 = {
 94	.name		  = "s3c64xx-spi",
 95	.id		  = 0,
 96	.num_resources	  = ARRAY_SIZE(s5pv210_spi0_resource),
 97	.resource	  = s5pv210_spi0_resource,
 98	.dev = {
 99		.dma_mask		= &spi_dmamask,
100		.coherent_dma_mask	= DMA_BIT_MASK(32),
101		.platform_data = &s5pv210_spi0_pdata,
102	},
103};
104
105static struct resource s5pv210_spi1_resource[] = {
106	[0] = {
107		.start = S5PV210_PA_SPI1,
108		.end   = S5PV210_PA_SPI1 + 0x100 - 1,
109		.flags = IORESOURCE_MEM,
110	},
111	[1] = {
112		.start = DMACH_SPI1_TX,
113		.end   = DMACH_SPI1_TX,
114		.flags = IORESOURCE_DMA,
115	},
116	[2] = {
117		.start = DMACH_SPI1_RX,
118		.end   = DMACH_SPI1_RX,
119		.flags = IORESOURCE_DMA,
120	},
121	[3] = {
122		.start = IRQ_SPI1,
123		.end   = IRQ_SPI1,
124		.flags = IORESOURCE_IRQ,
125	},
126};
127
128static struct s3c64xx_spi_info s5pv210_spi1_pdata = {
129	.cfg_gpio = s5pv210_spi_cfg_gpio,
130	.fifo_lvl_mask = 0x7f,
131	.rx_lvl_offset = 15,
132	.high_speed = 1,
133	.tx_st_done = 25,
134};
135
136struct platform_device s5pv210_device_spi1 = {
137	.name		  = "s3c64xx-spi",
138	.id		  = 1,
139	.num_resources	  = ARRAY_SIZE(s5pv210_spi1_resource),
140	.resource	  = s5pv210_spi1_resource,
141	.dev = {
142		.dma_mask		= &spi_dmamask,
143		.coherent_dma_mask	= DMA_BIT_MASK(32),
144		.platform_data = &s5pv210_spi1_pdata,
145	},
146};
147
148void __init s5pv210_spi_set_info(int cntrlr, int src_clk_nr, int num_cs)
149{
150	struct s3c64xx_spi_info *pd;
151
152	/* Reject invalid configuration */
153	if (!num_cs || src_clk_nr < 0
154			|| src_clk_nr > S5PV210_SPI_SRCCLK_SCLK) {
155		printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__);
156		return;
157	}
158
159	switch (cntrlr) {
160	case 0:
161		pd = &s5pv210_spi0_pdata;
162		break;
163	case 1:
164		pd = &s5pv210_spi1_pdata;
165		break;
166	default:
167		printk(KERN_ERR "%s: Invalid SPI controller(%d)\n",
168							__func__, cntrlr);
169		return;
170	}
171
172	pd->num_cs = num_cs;
173	pd->src_clk_nr = src_clk_nr;
174	pd->src_clk_name = spi_src_clks[src_clk_nr];
175}