summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorpopcornmix <popcornmix@gmail.com>2013-11-04 18:56:10 +0000
committerpopcornmix <popcornmix@gmail.com>2015-05-18 14:10:34 +0100
commitcefa17faebaf7574d71fedca70f066daa9d69e78 (patch)
tree2e0c839aa7824bc93f5bd1d3904a3f5e3b5a0edb /arch
parentbc0639ef79636e12ede0da9be5725072e2745830 (diff)
downloadlinux-cefa17faebaf7574d71fedca70f066daa9d69e78.tar.gz
Add Chris Boot's i2c and spi drivers.
i2c-bcm2708: fixed baudrate Fixed issue where the wrong CDIV value was set for baudrates below 3815 Hz (for 250MHz bus clock). In that case the computed CDIV value was more than 0xffff. However the CDIV register width is only 16 bits. This resulted in incorrect setting of CDIV and higher baudrate than intended. Example: 3500Hz -> CDIV=0x11704 -> CDIV(16bit)=0x1704 -> 42430Hz After correction: 3500Hz -> CDIV=0x11704 -> CDIV(16bit)=0xffff -> 3815Hz The correct baudrate is shown in the log after the cdiv > 0xffff correction. Perform I2C combined transactions when possible Perform I2C combined transactions whenever possible, within the restrictions of the Broadcomm Serial Controller. Disable DONE interrupt during TA poll Prevent interrupt from being triggered if poll is missed and transfer starts and finishes. i2c: Make combined transactions optional and disabled by default
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-bcm2708/Kconfig7
-rw-r--r--arch/arm/mach-bcm2708/bcm2708.c104
2 files changed, 109 insertions, 2 deletions
diff --git a/arch/arm/mach-bcm2708/Kconfig b/arch/arm/mach-bcm2708/Kconfig
index 9355841e58e2..e151ed4efbbb 100644
--- a/arch/arm/mach-bcm2708/Kconfig
+++ b/arch/arm/mach-bcm2708/Kconfig
@@ -31,4 +31,11 @@ config BCM2708_NOL2CACHE
help
Do not allow ARM to use GPU's L2 cache. Requires disable_l2cache in config.txt.
+config BCM2708_SPIDEV
+ bool "Bind spidev to SPI0 master"
+ depends on MACH_BCM2708
+ depends on SPI
+ default y
+ help
+ Binds spidev driver to the SPI0 master
endmenu
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
index bae8ba5b704f..752dd46cefe6 100644
--- a/arch/arm/mach-bcm2708/bcm2708.c
+++ b/arch/arm/mach-bcm2708/bcm2708.c
@@ -31,6 +31,7 @@
#include <linux/cnt32_to_63.h>
#include <linux/io.h>
#include <linux/module.h>
+#include <linux/spi/spi.h>
#include <linux/version.h>
#include <linux/clkdev.h>
@@ -205,7 +206,6 @@ static struct clk osc_clk = {
/* warning - the USB needs a clock > 34MHz */
-#ifdef CONFIG_MMC_BCM2708
static struct clk sdhost_clk = {
#ifdef CONFIG_ARCH_BCM2708_CHIPIT
.rate = 4000000, /* 4MHz */
@@ -213,7 +213,6 @@ static struct clk sdhost_clk = {
.rate = 250000000, /* 250MHz */
#endif
};
-#endif
static struct clk_lookup lookups[] = {
{ /* UART0 */
@@ -223,6 +222,15 @@ static struct clk_lookup lookups[] = {
{ /* USB */
.dev_id = "bcm2708_usb",
.clk = &osc_clk,
+ }, { /* SPI */
+ .dev_id = "bcm2708_spi.0",
+ .clk = &sdhost_clk,
+ }, { /* BSC0 */
+ .dev_id = "bcm2708_i2c.0",
+ .clk = &sdhost_clk,
+ }, { /* BSC1 */
+ .dev_id = "bcm2708_i2c.1",
+ .clk = &sdhost_clk,
}
};
@@ -499,6 +507,89 @@ static struct platform_device bcm2708_alsa_devices[] = {
},
};
+static struct resource bcm2708_spi_resources[] = {
+ {
+ .start = SPI0_BASE,
+ .end = SPI0_BASE + SZ_256 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_SPI,
+ .end = IRQ_SPI,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+
+static u64 bcm2708_spi_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);
+static struct platform_device bcm2708_spi_device = {
+ .name = "bcm2708_spi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bcm2708_spi_resources),
+ .resource = bcm2708_spi_resources,
+ .dev = {
+ .dma_mask = &bcm2708_spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON)},
+};
+
+#ifdef CONFIG_BCM2708_SPIDEV
+static struct spi_board_info bcm2708_spi_devices[] = {
+#ifdef CONFIG_SPI_SPIDEV
+ {
+ .modalias = "spidev",
+ .max_speed_hz = 500000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ }, {
+ .modalias = "spidev",
+ .max_speed_hz = 500000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .mode = SPI_MODE_0,
+ }
+#endif
+};
+#endif
+
+static struct resource bcm2708_bsc0_resources[] = {
+ {
+ .start = BSC0_BASE,
+ .end = BSC0_BASE + SZ_256 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = INTERRUPT_I2C,
+ .end = INTERRUPT_I2C,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device bcm2708_bsc0_device = {
+ .name = "bcm2708_i2c",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bcm2708_bsc0_resources),
+ .resource = bcm2708_bsc0_resources,
+};
+
+
+static struct resource bcm2708_bsc1_resources[] = {
+ {
+ .start = BSC1_BASE,
+ .end = BSC1_BASE + SZ_256 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = INTERRUPT_I2C,
+ .end = INTERRUPT_I2C,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device bcm2708_bsc1_device = {
+ .name = "bcm2708_i2c",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bcm2708_bsc1_resources),
+ .resource = bcm2708_bsc1_resources,
+};
+
static struct platform_device bcm2835_hwmon_device = {
.name = "bcm2835_hwmon",
};
@@ -619,6 +710,10 @@ void __init bcm2708_init(void)
for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++)
bcm_register_device(&bcm2708_alsa_devices[i]);
+ bcm_register_device(&bcm2708_spi_device);
+ bcm_register_device(&bcm2708_bsc0_device);
+ bcm_register_device(&bcm2708_bsc1_device);
+
bcm_register_device(&bcm2835_hwmon_device);
bcm_register_device(&bcm2835_thermal_device);
@@ -628,6 +723,11 @@ void __init bcm2708_init(void)
}
system_rev = boardrev;
system_serial_low = serial;
+
+#ifdef CONFIG_BCM2708_SPIDEV
+ spi_register_board_info(bcm2708_spi_devices,
+ ARRAY_SIZE(bcm2708_spi_devices));
+#endif
}
static void timer_set_mode(enum clock_event_mode mode,