summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-ep93xx
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-ep93xx')
-rw-r--r--arch/arm/mach-ep93xx/edb93xx.c116
-rw-r--r--arch/arm/mach-ep93xx/gpio.c33
-rw-r--r--arch/arm/mach-ep93xx/include/mach/gpio.h2
3 files changed, 145 insertions, 6 deletions
diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c
index 4b043165213..9969bb115f6 100644
--- a/arch/arm/mach-ep93xx/edb93xx.c
+++ b/arch/arm/mach-ep93xx/edb93xx.c
@@ -30,8 +30,13 @@
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
+#include <linux/spi/spi.h>
+
+#include <sound/cs4271.h>
#include <mach/hardware.h>
+#include <mach/fb.h>
+#include <mach/ep93xx_spi.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -93,6 +98,83 @@ static void __init edb93xx_register_i2c(void)
/*************************************************************************
+ * EDB93xx SPI peripheral handling
+ *************************************************************************/
+static struct cs4271_platform_data edb93xx_cs4271_data = {
+ .gpio_nreset = -EINVAL, /* filled in later */
+};
+
+static int edb93xx_cs4271_hw_setup(struct spi_device *spi)
+{
+ return gpio_request_one(EP93XX_GPIO_LINE_EGPIO6,
+ GPIOF_OUT_INIT_HIGH, spi->modalias);
+}
+
+static void edb93xx_cs4271_hw_cleanup(struct spi_device *spi)
+{
+ gpio_free(EP93XX_GPIO_LINE_EGPIO6);
+}
+
+static void edb93xx_cs4271_hw_cs_control(struct spi_device *spi, int value)
+{
+ gpio_set_value(EP93XX_GPIO_LINE_EGPIO6, value);
+}
+
+static struct ep93xx_spi_chip_ops edb93xx_cs4271_hw = {
+ .setup = edb93xx_cs4271_hw_setup,
+ .cleanup = edb93xx_cs4271_hw_cleanup,
+ .cs_control = edb93xx_cs4271_hw_cs_control,
+};
+
+static struct spi_board_info edb93xx_spi_board_info[] __initdata = {
+ {
+ .modalias = "cs4271",
+ .platform_data = &edb93xx_cs4271_data,
+ .controller_data = &edb93xx_cs4271_hw,
+ .max_speed_hz = 6000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ },
+};
+
+static struct ep93xx_spi_info edb93xx_spi_info __initdata = {
+ .num_chipselect = ARRAY_SIZE(edb93xx_spi_board_info),
+};
+
+static void __init edb93xx_register_spi(void)
+{
+ if (machine_is_edb9301() || machine_is_edb9302())
+ edb93xx_cs4271_data.gpio_nreset = EP93XX_GPIO_LINE_EGPIO1;
+ else if (machine_is_edb9302a() || machine_is_edb9307a())
+ edb93xx_cs4271_data.gpio_nreset = EP93XX_GPIO_LINE_H(2);
+ else if (machine_is_edb9315a())
+ edb93xx_cs4271_data.gpio_nreset = EP93XX_GPIO_LINE_EGPIO14;
+
+ ep93xx_register_spi(&edb93xx_spi_info, edb93xx_spi_board_info,
+ ARRAY_SIZE(edb93xx_spi_board_info));
+}
+
+
+/*************************************************************************
+ * EDB93xx I2S
+ *************************************************************************/
+static int __init edb93xx_has_audio(void)
+{
+ return (machine_is_edb9301() || machine_is_edb9302() ||
+ machine_is_edb9302a() || machine_is_edb9307a() ||
+ machine_is_edb9315a());
+}
+
+static void __init edb93xx_register_i2s(void)
+{
+ if (edb93xx_has_audio()) {
+ ep93xx_register_i2s();
+ }
+}
+
+
+/*************************************************************************
* EDB93xx pwm
*************************************************************************/
static void __init edb93xx_register_pwm(void)
@@ -111,13 +193,47 @@ static void __init edb93xx_register_pwm(void)
}
+/*************************************************************************
+ * EDB93xx framebuffer
+ *************************************************************************/
+static struct ep93xxfb_mach_info __initdata edb93xxfb_info = {
+ .num_modes = EP93XXFB_USE_MODEDB,
+ .bpp = 16,
+ .flags = 0,
+};
+
+static int __init edb93xx_has_fb(void)
+{
+ /* These platforms have an ep93xx with video capability */
+ return machine_is_edb9307() || machine_is_edb9307a() ||
+ machine_is_edb9312() || machine_is_edb9315() ||
+ machine_is_edb9315a();
+}
+
+static void __init edb93xx_register_fb(void)
+{
+ if (!edb93xx_has_fb())
+ return;
+
+ if (machine_is_edb9307a() || machine_is_edb9315a())
+ edb93xxfb_info.flags |= EP93XXFB_USE_SDCSN0;
+ else
+ edb93xxfb_info.flags |= EP93XXFB_USE_SDCSN3;
+
+ ep93xx_register_fb(&edb93xxfb_info);
+}
+
+
static void __init edb93xx_init_machine(void)
{
ep93xx_init_devices();
edb93xx_register_flash();
ep93xx_register_eth(&edb93xx_eth_data, 1);
edb93xx_register_i2c();
+ edb93xx_register_spi();
+ edb93xx_register_i2s();
edb93xx_register_pwm();
+ edb93xx_register_fb();
}
diff --git a/arch/arm/mach-ep93xx/gpio.c b/arch/arm/mach-ep93xx/gpio.c
index bec34b83495..a889fa7c3ba 100644
--- a/arch/arm/mach-ep93xx/gpio.c
+++ b/arch/arm/mach-ep93xx/gpio.c
@@ -61,7 +61,7 @@ static inline void ep93xx_gpio_int_mask(unsigned line)
gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
}
-void ep93xx_gpio_int_debounce(unsigned int irq, int enable)
+static void ep93xx_gpio_int_debounce(unsigned int irq, bool enable)
{
int line = irq_to_gpio(irq);
int port = line >> 3;
@@ -75,7 +75,6 @@ void ep93xx_gpio_int_debounce(unsigned int irq, int enable)
__raw_writeb(gpio_int_debounce[port],
EP93XX_GPIO_REG(int_debounce_register_offset[port]));
}
-EXPORT_SYMBOL(ep93xx_gpio_int_debounce);
static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc)
{
@@ -335,6 +334,20 @@ static void ep93xx_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
local_irq_restore(flags);
}
+static int ep93xx_gpio_set_debounce(struct gpio_chip *chip,
+ unsigned offset, unsigned debounce)
+{
+ int gpio = chip->base + offset;
+ int irq = gpio_to_irq(gpio);
+
+ if (irq < 0)
+ return -EINVAL;
+
+ ep93xx_gpio_int_debounce(irq, debounce ? true : false);
+
+ return 0;
+}
+
static void ep93xx_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
{
struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip);
@@ -434,6 +447,18 @@ void __init ep93xx_gpio_init(void)
EP93XX_SYSCON_DEVCFG_GONIDE |
EP93XX_SYSCON_DEVCFG_HONIDE);
- for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++)
- gpiochip_add(&ep93xx_gpio_banks[i].chip);
+ for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) {
+ struct gpio_chip *chip = &ep93xx_gpio_banks[i].chip;
+
+ /*
+ * Ports A, B, and F support input debouncing when
+ * used as interrupts.
+ */
+ if (!strcmp(chip->label, "A") ||
+ !strcmp(chip->label, "B") ||
+ !strcmp(chip->label, "F"))
+ chip->set_debounce = ep93xx_gpio_set_debounce;
+
+ gpiochip_add(chip);
+ }
}
diff --git a/arch/arm/mach-ep93xx/include/mach/gpio.h b/arch/arm/mach-ep93xx/include/mach/gpio.h
index c991b149bdf..c57152c231f 100644
--- a/arch/arm/mach-ep93xx/include/mach/gpio.h
+++ b/arch/arm/mach-ep93xx/include/mach/gpio.h
@@ -99,8 +99,6 @@
/* maximum value for irq capable line identifiers */
#define EP93XX_GPIO_LINE_MAX_IRQ EP93XX_GPIO_LINE_F(7)
-extern void ep93xx_gpio_int_debounce(unsigned int irq, int enable);
-
/* new generic GPIO API - see Documentation/gpio.txt */
#include <asm-generic/gpio.h>