int __init device_init_stb840_promSvyaz(int ver) { struct sysconf_field *sc; stx7105_configure_sata(0); /* Set SPI Boot pads as inputs to avoid contention with SSC1 */ gpio_request(stm_gpio(15, 0), "SPI Boot CLK"); gpio_direction_input(stm_gpio(15, 0)); gpio_request(stm_gpio(15, 1), "SPI Boot DOUT"); gpio_direction_input(stm_gpio(15, 1)); gpio_request(stm_gpio(15, 2), "SPI Boot NOTCS"); gpio_direction_input(stm_gpio(15, 2)); gpio_request(stm_gpio(15, 3), "SPI Boot DIN"); gpio_direction_input(stm_gpio(15, 3)); /* * Fix the reset chain so it correct to start with in case the * watchdog expires or we trigger a reset. */ sc = sysconf_claim(SYS_CFG, 9, 27, 28, "reset_chain"); sysconf_write(sc, 0); /* Release the sysconf bits so the coprocessor driver can claim them */ sysconf_release(sc); /* I2C_xxxA - HDMI */ stx7105_configure_ssc_i2c(0, &(struct stx7105_ssc_config) { .routing.ssc0.sclk = stx7105_ssc0_sclk_pio2_2, .routing.ssc0.mtsr = stx7105_ssc0_mtsr_pio2_3, });
int stpio_flagged_request_irq(struct stpio_pin *pin, int comp, void (*handler)(struct stpio_pin *pin, void *dev), void *dev, unsigned long flags) { int irq; const char *owner; int result; /* stpio style interrupt handling doesn't allow sharing. */ BUG_ON(pin->func); irq = stpio_pin_to_irq(pin); pin->func = handler; pin->dev = dev; owner = stm_pad_get_gpio_owner(stm_gpio(pin->port_no, pin->pin_no)); set_irq_type(irq, comp ? IRQ_TYPE_LEVEL_LOW : IRQ_TYPE_LEVEL_HIGH); result = request_irq(irq, stpio_irq_wrapper, 0, owner, pin); BUG_ON(result); if (flags & IRQ_DISABLED) { /* This is a race condition waiting to happen... */ disable_irq(irq); } return 0; }
static int stm_gpio_port_restore(struct stm_gpio_port *port) { int pin_no; for (pin_no = 0; pin_no < port->gpio_chip.ngpio; ++pin_no) { struct stm_gpio_pin *pin = &port->pins[pin_no]; if (!platform_allow_pm_gpio( stm_gpio(port - stm_gpio_ports, pin_no), 0)) continue; /* * Direction can not be zero! Zero means 'un-claimed' */ if (!gpio_pm_get_direction(pin)) { /* * On some chip the reset value ins't DIRECTION_IN... */ __stm_gpio_direction(port, pin_no, STM_GPIO_DIRECTION_IN); /* reset again to say 'un-claimed' as it was */ gpio_pm_set_direction(pin, 0); continue; } /* * In case of Direction_Out set the Out value */ if (STM_GPIO_DIRECTION_OUT == gpio_pm_get_direction(pin)) __stm_gpio_set(port, pin_no, gpio_pm_get_value(pin)); __stm_gpio_direction(port, pin_no, gpio_pm_get_direction(pin)); } return 0; }
struct stpio_pin *__stpio_request_pin(unsigned int port_no, unsigned int pin_no, const char *name, int direction, int __set_value, unsigned int value) { struct stm_gpio_port *port; struct stm_gpio_pin *gpio_pin; int num_ports = stm_gpio_num / STM_GPIO_PINS_PER_PORT; if (port_no >= num_ports || pin_no >= STM_GPIO_PINS_PER_PORT) return NULL; port = &stm_gpio_ports[port_no]; gpio_pin = &port->pins[pin_no]; if (stm_pad_claim_gpio(stm_gpio(port_no, pin_no)) != 0) return NULL; if (__set_value) __stm_gpio_set(port, pin_no, value); __stm_gpio_direction(port, pin_no, direction); gpio_pin->stpio.port_no = port_no; gpio_pin->stpio.pin_no = pin_no; return &gpio_pin->stpio; }
static int stm_gpio_port_suspend(struct stm_gpio_port *port) { int port_no = port - stm_gpio_ports; int pin_no; /* Enable the wakeup pin IRQ if required */ for (pin_no = 0; pin_no < port->gpio_chip.ngpio; ++pin_no) { int irq = gpio_to_irq(stm_gpio(port_no, pin_no)); struct irq_desc *desc = irq_to_desc(irq); if (IRQ_WAKEUP & desc->status) stm_gpio_irq_chip_enable(irq); else stm_gpio_irq_chip_disable(irq); } return 0; }
#define HDK7105_GPIO_FLASH_WP stm_gpio(6, 4) static struct platform_device pdk7105_leds = { .name = "leds-gpio", .id = 0, .dev.platform_data = &(struct gpio_led_platform_data) { .num_leds = 2, .leds = (struct gpio_led[]) { /* The schematics actually describes these PIOs * the other way round, but all tested boards * had the bi-colour LED fitted like below... */ { .name = "GREEN", /* This is also frontpanel LED */ .gpio = stm_gpio(7, 0), .active_low = 1, }, { .name = "RED", .default_trigger = "heartbeat", .gpio = stm_gpio(7, 1), .active_low = 1, }, }, }, }; static struct tm1668_key hdk7105_front_panel_keys[] = { {0x80000000, KEY_POWER, "FP POWER"}, };
static void stig125_spi_tel_cs(struct spi_device *spi, int value) { gpio_set_value(stm_gpio(16, 3), (spi->mode & SPI_CS_HIGH) ? value : !value); }
#include <linux/mtd/partitions.h> #include <mach/soc-stig125.h> #include <mach/hardware.h> static struct platform_device b2078_leds = { .name = "leds-gpio", .id = -1, .dev.platform_data = &(struct gpio_led_platform_data) { .num_leds = 5, .leds = (struct gpio_led[]) { { .name = "LED0_RED", .default_trigger = "none", .active_low = true, .gpio = stm_gpio(4, 0), }, { .name = "LED1_RED", .default_trigger = "none", .active_low = true, .gpio = stm_gpio(4, 1), }, { .name = "LED2_YELLOW", .default_trigger = "heartbeat", .active_low = true, .gpio = stm_gpio(4, 2), }, { .name = "LED3_GREEN", .default_trigger = "default-on", .active_low = true, .gpio = stm_gpio(4, 3),
}; #define EXTENDER_GPIO(port, pin) (EXTENDER_BASE + (port * 8) + (pin)) /* Heartbeat led (LD12-T) */ static struct platform_device mb520_hb_led = { .name = "leds-gpio", .id = -1, .dev.platform_data = &(struct gpio_led_platform_data) { .num_leds = 1, .leds = (struct gpio_led[]) { { .name = "HB", .default_trigger = "heartbeat", .gpio = stm_gpio(4, 7), .active_low = 1, }, }, }, }; #ifdef CONFIG_SND /* Audio peripherals * * The recommended audio setup of MB520 is as follows: * 1. Remove R93 (located near SW4 and IC18) * 2. Set SW3[1..4] to [OFF, OFF, ON, ON] * 3. Set SW5[1..4] to [OFF, ON, ON, OFF]
static void stm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) { struct stm_gpio_port *port = to_stm_gpio_port(chip); int port_no = chip->base / STM_GPIO_PINS_PER_PORT; int pin_no; for (pin_no = 0; pin_no < STM_GPIO_PINS_PER_PORT; pin_no++) { unsigned gpio = stm_gpio(port_no, pin_no); const char *owner, *direction; seq_printf(s, " %-3d: PIO%d.%d: ", gpio, port_no, pin_no); switch (get__PIO_PCx(port->base, pin_no)) { case value__PIO_PCx__INPUT_WEAK_PULL_UP(): direction = "input (weak pull up)"; break; case value__PIO_PCx__BIDIR_OPEN_DRAIN(): case value__PIO_PCx__BIDIR_OPEN_DRAIN__alt(): direction = "bidirectional (open drain)"; break; case value__PIO_PCx__OUTPUT_PUSH_PULL(): direction = "output (push-pull)"; break; case value__PIO_PCx__INPUT_HIGH_IMPEDANCE(): case value__PIO_PCx__INPUT_HIGH_IMPEDANCE__alt(): direction = "input (high impedance)"; break; case value__PIO_PCx__ALTERNATIVE_OUTPUT_PUSH_PULL(): direction = "alternative function output " "(push-pull)"; break; case value__PIO_PCx__ALTERNATIVE_BIDIR_OPEN_DRAIN(): direction = "alternative function bidirectional " "(open drain)"; break; default: /* Should never get here... */ __WARN(); direction = "unknown configuration"; break; } seq_printf(s, "%s, ", direction); owner = gpiochip_is_requested(chip, pin_no); if (owner) { unsigned irq = gpio_to_irq(gpio); struct irq_desc *desc = irq_desc + irq; seq_printf(s, "allocated by GPIO to '%s'", owner); /* This races with request_irq(), set_irq_type(), * and set_irq_wake() ... but those are "rare". * * More significantly, trigger type flags aren't * currently maintained by genirq. */ if (desc->action) { char *trigger; switch (desc->status & IRQ_TYPE_SENSE_MASK) { case IRQ_TYPE_NONE: trigger = "default"; break; case IRQ_TYPE_EDGE_FALLING: trigger = "edge-falling"; break; case IRQ_TYPE_EDGE_RISING: trigger = "edge-rising"; break; case IRQ_TYPE_EDGE_BOTH: trigger = "edge-both"; break; case IRQ_TYPE_LEVEL_HIGH: trigger = "level-high"; break; case IRQ_TYPE_LEVEL_LOW: trigger = "level-low"; break; default: __WARN(); trigger = "unknown"; break; } seq_printf(s, " and IRQ %d (%s trigger%s)", irq, trigger, (desc->status & IRQ_WAKEUP) ? " wakeup" : ""); } seq_printf(s, "\n"); } else { owner = stm_pad_get_gpio_owner(stm_gpio(port_no, pin_no)); if (owner) { seq_printf(s, "allocated by pad manager " "to '%s'\n", owner); } else { seq_printf(s, "unused\n"); } } } }
void stpio_free_pin(struct stpio_pin *pin) { stm_pad_release_gpio(stm_gpio(pin->port_no, pin->pin_no)); }
static inline int stpio_pin_to_irq(struct stpio_pin *pin) { return gpio_to_irq(stm_gpio(pin->port_no, pin->pin_no)); }
static void __stm_gpio_irq_handler(const struct stm_gpio_port *port) { int port_no = port - stm_gpio_ports; int pin_no; unsigned long port_in, port_mask, port_comp, port_active; unsigned long port_level_mask = port->irq_level_mask; /* We don't want to mask the INTC2/ILC first level interrupt here, * and as these are both level based, there is no need to ack. */ port_in = get__PIO_PIN(port->base); port_comp = get__PIO_PCOMP(port->base); port_mask = get__PIO_PMASK(port->base); port_active = (port_in ^ port_comp) & port_mask; pr_debug("level_mask = 0x%08lx\n", port_level_mask); /* Level sensitive interrupts we can mask for the duration */ set__PIO_CLR_PMASK(port->base, port_level_mask); /* Edge sensitive we want to know about if they change */ set__PIO_CLR_PCOMP(port->base, ~port_level_mask & port_active & port_comp); set__PIO_SET_PCOMP(port->base, ~port_level_mask & port_active & ~port_comp); while ((pin_no = ffs(port_active)) != 0) { unsigned gpio; struct stm_gpio_pin *pin; unsigned int pin_irq; struct irq_desc *pin_irq_desc; unsigned long pin_mask; pin_no--; pr_debug("active = %ld pinno = %d\n", port_active, pin_no); gpio = stm_gpio(port_no, pin_no); pin_irq = gpio_to_irq(gpio); pin_irq_desc = &irq_desc[pin_irq]; pin = get_irq_chip_data(pin_irq); pin_mask = 1 << pin_no; port_active &= ~pin_mask; if (pin->flags & PIN_FAKE_EDGE) { int value = gpio_get_value(gpio); pr_debug("pinno %d PIN_FAKE_EDGE val %d\n", pin_no, value); if (value) set__PIO_SET_PCOMP(port->base, pin_mask); else set__PIO_CLR_PCOMP(port->base, pin_mask); if ((pin->flags & PIN_IGNORE_EDGE_MASK) == (PIN_IGNORE_EDGE_FLAG | (value ^ 1))) continue; } if (unlikely(pin_irq_desc->status & (IRQ_INPROGRESS | IRQ_DISABLED))) { set__PIO_CLR_PMASK(port->base, pin_mask); /* The unmasking will be done by enable_irq in * case it is disabled or after returning from * the handler if it's already running. */ if (pin_irq_desc->status & IRQ_INPROGRESS) { /* Level triggered interrupts won't * ever be reentered */ BUG_ON(port_level_mask & pin_mask); pin_irq_desc->status |= IRQ_PENDING; } continue; } else { pin_irq_desc->handle_irq(pin_irq, pin_irq_desc); /* If our handler has disabled interrupts, * then don't re-enable them */ if (pin_irq_desc->status & IRQ_DISABLED) { pr_debug("handler has disabled interrupts!\n"); port_mask &= ~pin_mask; } } if (unlikely((pin_irq_desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING)) { pin_irq_desc->status &= ~IRQ_PENDING; set__PIO_SET_PMASK(port->base, pin_mask); } } /* Re-enable level */ set__PIO_SET_PMASK(port->base, port_level_mask & port_mask); /* Do we need a software level as well, to cope with interrupts * which get disabled during the handler execution? */ pr_debug("exiting\n"); }