Commit 645f0b07 authored by Ben Dooks's avatar Ben Dooks

ARM: Merge next-jassi-spi

Merge branch 'next-jassi-spi' into next-samsung-try5
parents 44d6cef8 6a2b4111
...@@ -64,6 +64,8 @@ ...@@ -64,6 +64,8 @@
#define S3C64XX_PA_IIS1 (0x7F003000) #define S3C64XX_PA_IIS1 (0x7F003000)
#define S3C64XX_PA_TIMER (0x7F006000) #define S3C64XX_PA_TIMER (0x7F006000)
#define S3C64XX_PA_IIC0 (0x7F004000) #define S3C64XX_PA_IIC0 (0x7F004000)
#define S3C64XX_PA_SPI0 (0x7F00B000)
#define S3C64XX_PA_SPI1 (0x7F00C000)
#define S3C64XX_PA_PCM0 (0x7F009000) #define S3C64XX_PA_PCM0 (0x7F009000)
#define S3C64XX_PA_PCM1 (0x7F00A000) #define S3C64XX_PA_PCM1 (0x7F00A000)
#define S3C64XX_PA_IISV4 (0x7F00D000) #define S3C64XX_PA_IISV4 (0x7F00D000)
......
...@@ -29,6 +29,9 @@ extern struct platform_device s3c64xx_device_iis0; ...@@ -29,6 +29,9 @@ extern struct platform_device s3c64xx_device_iis0;
extern struct platform_device s3c64xx_device_iis1; extern struct platform_device s3c64xx_device_iis1;
extern struct platform_device s3c64xx_device_iisv4; extern struct platform_device s3c64xx_device_iisv4;
extern struct platform_device s3c64xx_device_spi0;
extern struct platform_device s3c64xx_device_spi1;
extern struct platform_device s3c64xx_device_pcm0; extern struct platform_device s3c64xx_device_pcm0;
extern struct platform_device s3c64xx_device_pcm1; extern struct platform_device s3c64xx_device_pcm1;
......
...@@ -47,3 +47,4 @@ obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1.o ...@@ -47,3 +47,4 @@ obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1.o
obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp.o obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp.o
obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
obj-$(CONFIG_SND_S3C24XX_SOC) += dev-audio.o obj-$(CONFIG_SND_S3C24XX_SOC) += dev-audio.o
obj-$(CONFIG_SPI_S3C64XX) += dev-spi.o
...@@ -140,6 +140,18 @@ static struct clk init_clocks_disable[] = { ...@@ -140,6 +140,18 @@ static struct clk init_clocks_disable[] = {
.parent = &clk_p, .parent = &clk_p,
.enable = s3c64xx_pclk_ctrl, .enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_SPI1, .ctrlbit = S3C_CLKCON_PCLK_SPI1,
}, {
.name = "spi_48m",
.id = 0,
.parent = &clk_48m,
.enable = s3c64xx_sclk_ctrl,
.ctrlbit = S3C_CLKCON_SCLK_SPI0_48,
}, {
.name = "spi_48m",
.id = 1,
.parent = &clk_48m,
.enable = s3c64xx_sclk_ctrl,
.ctrlbit = S3C_CLKCON_SCLK_SPI1_48,
}, { }, {
.name = "48m", .name = "48m",
.id = 0, .id = 0,
......
/* linux/arch/arm/plat-s3c64xx/dev-spi.c
*
* Copyright (C) 2009 Samsung Electronics Ltd.
* Jaswinder Singh <jassi.brar@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/kernel.h>
#include <linux/string.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <mach/dma.h>
#include <mach/map.h>
#include <mach/gpio.h>
#include <plat/spi-clocks.h>
#include <plat/s3c64xx-spi.h>
#include <plat/gpio-bank-c.h>
#include <plat/gpio-cfg.h>
#include <plat/irqs.h>
static char *spi_src_clks[] = {
[S3C64XX_SPI_SRCCLK_PCLK] = "pclk",
[S3C64XX_SPI_SRCCLK_SPIBUS] = "spi-bus",
[S3C64XX_SPI_SRCCLK_48M] = "spi_48m",
};
/* SPI Controller platform_devices */
/* Since we emulate multi-cs capability, we do not touch the GPC-3,7.
* The emulated CS is toggled by board specific mechanism, as it can
* be either some immediate GPIO or some signal out of some other
* chip in between ... or some yet another way.
* We simply do not assume anything about CS.
*/
static int s3c64xx_spi_cfg_gpio(struct platform_device *pdev)
{
switch (pdev->id) {
case 0:
s3c_gpio_cfgpin(S3C64XX_GPC(0), S3C64XX_GPC0_SPI_MISO0);
s3c_gpio_cfgpin(S3C64XX_GPC(1), S3C64XX_GPC1_SPI_CLKO);
s3c_gpio_cfgpin(S3C64XX_GPC(2), S3C64XX_GPC2_SPI_MOSIO);
s3c_gpio_setpull(S3C64XX_GPC(0), S3C_GPIO_PULL_UP);
s3c_gpio_setpull(S3C64XX_GPC(1), S3C_GPIO_PULL_UP);
s3c_gpio_setpull(S3C64XX_GPC(2), S3C_GPIO_PULL_UP);
break;
case 1:
s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C64XX_GPC4_SPI_MISO1);
s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C64XX_GPC5_SPI_CLK1);
s3c_gpio_cfgpin(S3C64XX_GPC(6), S3C64XX_GPC6_SPI_MOSI1);
s3c_gpio_setpull(S3C64XX_GPC(4), S3C_GPIO_PULL_UP);
s3c_gpio_setpull(S3C64XX_GPC(5), S3C_GPIO_PULL_UP);
s3c_gpio_setpull(S3C64XX_GPC(6), S3C_GPIO_PULL_UP);
break;
default:
dev_err(&pdev->dev, "Invalid SPI Controller number!");
return -EINVAL;
}
return 0;
}
static struct resource s3c64xx_spi0_resource[] = {
[0] = {
.start = S3C64XX_PA_SPI0,
.end = S3C64XX_PA_SPI0 + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DMACH_SPI0_TX,
.end = DMACH_SPI0_TX,
.flags = IORESOURCE_DMA,
},
[2] = {
.start = DMACH_SPI0_RX,
.end = DMACH_SPI0_RX,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = IRQ_SPI0,
.end = IRQ_SPI0,
.flags = IORESOURCE_IRQ,
},
};
static struct s3c64xx_spi_info s3c64xx_spi0_pdata = {
.cfg_gpio = s3c64xx_spi_cfg_gpio,
.fifo_lvl_mask = 0x7f,
.rx_lvl_offset = 13,
};
static u64 spi_dmamask = DMA_BIT_MASK(32);
struct platform_device s3c64xx_device_spi0 = {
.name = "s3c64xx-spi",
.id = 0,
.num_resources = ARRAY_SIZE(s3c64xx_spi0_resource),
.resource = s3c64xx_spi0_resource,
.dev = {
.dma_mask = &spi_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &s3c64xx_spi0_pdata,
},
};
EXPORT_SYMBOL(s3c64xx_device_spi0);
static struct resource s3c64xx_spi1_resource[] = {
[0] = {
.start = S3C64XX_PA_SPI1,
.end = S3C64XX_PA_SPI1 + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DMACH_SPI1_TX,
.end = DMACH_SPI1_TX,
.flags = IORESOURCE_DMA,
},
[2] = {
.start = DMACH_SPI1_RX,
.end = DMACH_SPI1_RX,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = IRQ_SPI1,
.end = IRQ_SPI1,
.flags = IORESOURCE_IRQ,
},
};
static struct s3c64xx_spi_info s3c64xx_spi1_pdata = {
.cfg_gpio = s3c64xx_spi_cfg_gpio,
.fifo_lvl_mask = 0x7f,
.rx_lvl_offset = 13,
};
struct platform_device s3c64xx_device_spi1 = {
.name = "s3c64xx-spi",
.id = 1,
.num_resources = ARRAY_SIZE(s3c64xx_spi1_resource),
.resource = s3c64xx_spi1_resource,
.dev = {
.dma_mask = &spi_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &s3c64xx_spi1_pdata,
},
};
EXPORT_SYMBOL(s3c64xx_device_spi1);
void __init s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs)
{
/* Reject invalid configuration */
if (!num_cs || src_clk_nr < 0
|| src_clk_nr > S3C64XX_SPI_SRCCLK_48M) {
printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__);
return;
}
switch (cntrlr) {
case 0:
s3c64xx_spi0_pdata.num_cs = num_cs;
s3c64xx_spi0_pdata.src_clk_nr = src_clk_nr;
s3c64xx_spi0_pdata.src_clk_name = spi_src_clks[src_clk_nr];
break;
case 1:
s3c64xx_spi1_pdata.num_cs = num_cs;
s3c64xx_spi1_pdata.src_clk_nr = src_clk_nr;
s3c64xx_spi1_pdata.src_clk_name = spi_src_clks[src_clk_nr];
break;
default:
printk(KERN_ERR "%s: Invalid SPI controller(%d)\n",
__func__, cntrlr);
return;
}
}
/* linux/arch/arm/plat-s3c64xx/include/plat/spi-clocks.h
*
* Copyright (C) 2009 Samsung Electronics Ltd.
* Jaswinder Singh <jassi.brar@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.
*/
#ifndef __S3C64XX_PLAT_SPI_CLKS_H
#define __S3C64XX_PLAT_SPI_CLKS_H __FILE__
#define S3C64XX_SPI_SRCCLK_PCLK 0
#define S3C64XX_SPI_SRCCLK_SPIBUS 1
#define S3C64XX_SPI_SRCCLK_48M 2
#endif /* __S3C64XX_PLAT_SPI_CLKS_H */
/* linux/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
*
* Copyright (C) 2009 Samsung Electronics Ltd.
* Jaswinder Singh <jassi.brar@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.
*/
#ifndef __S3C64XX_PLAT_SPI_H
#define __S3C64XX_PLAT_SPI_H
/**
* struct s3c64xx_spi_csinfo - ChipSelect description
* @fb_delay: Slave specific feedback delay.
* Refer to FB_CLK_SEL register definition in SPI chapter.
* @line: Custom 'identity' of the CS line.
* @set_level: CS line control.
*
* This is per SPI-Slave Chipselect information.
* Allocate and initialize one in machine init code and make the
* spi_board_info.controller_data point to it.
*/
struct s3c64xx_spi_csinfo {
u8 fb_delay;
unsigned line;
void (*set_level)(unsigned line_id, int lvl);
};
/**
* struct s3c64xx_spi_info - SPI Controller defining structure
* @src_clk_nr: Clock source index for the CLK_CFG[SPI_CLKSEL] field.
* @src_clk_name: Platform name of the corresponding clock.
* @num_cs: Number of CS this controller emulates.
* @cfg_gpio: Configure pins for this SPI controller.
* @fifo_lvl_mask: All tx fifo_lvl fields start at offset-6
* @rx_lvl_offset: Depends on tx fifo_lvl field and bus number
* @high_speed: If the controller supports HIGH_SPEED_EN bit
*/
struct s3c64xx_spi_info {
int src_clk_nr;
char *src_clk_name;
int num_cs;
int (*cfg_gpio)(struct platform_device *pdev);
/* Following two fields are for future compatibility */
int fifo_lvl_mask;
int rx_lvl_offset;
int high_speed;
};
/**
* s3c64xx_spi_set_info - SPI Controller configure callback by the board
* initialization code.
* @cntrlr: SPI controller number the configuration is for.
* @src_clk_nr: Clock the SPI controller is to use to generate SPI clocks.
* @num_cs: Number of elements in the 'cs' array.
*
* Call this from machine init code for each SPI Controller that
* has some chips attached to it.
*/
extern void s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
#endif /* __S3C64XX_PLAT_SPI_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment