--- zzzz-none-000/linux-3.10.107/arch/mips/ath79/gpio.c 2017-06-27 09:49:32.000000000 +0000 +++ vr9-7490-729/linux-3.10.107/arch/mips/ath79/gpio.c 2021-11-10 11:53:53.000000000 +0000 @@ -1,244 +1,795 @@ -/* - * Atheros AR71XX/AR724X/AR913X GPIO API support - * - * Copyright (C) 2010-2011 Jaiganesh Narayanan - * Copyright (C) 2008-2011 Gabor Juhos - * Copyright (C) 2008 Imre Kaloz - * - * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP - * - * 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 EXPORT_SYMTAB +#define EXPORT_SYMTAB +#endif +//#include #include -#include #include -#include -#include -#include -#include -#include - -#include -#include -#include "common.h" - -static void __iomem *ath79_gpio_base; -static unsigned long ath79_gpio_count; -static DEFINE_SPINLOCK(ath79_gpio_lock); - -static void __ath79_gpio_set_value(unsigned gpio, int value) -{ - void __iomem *base = ath79_gpio_base; - - if (value) - __raw_writel(1 << gpio, base + AR71XX_GPIO_REG_SET); - else - __raw_writel(1 << gpio, base + AR71XX_GPIO_REG_CLEAR); -} +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -static int __ath79_gpio_get_value(unsigned gpio) -{ - return (__raw_readl(ath79_gpio_base + AR71XX_GPIO_REG_IN) >> gpio) & 1; -} -static int ath79_gpio_get_value(struct gpio_chip *chip, unsigned offset) -{ - return __ath79_gpio_get_value(offset); -} +#define GPIO_FUNCTION_TABLE +#include -static void ath79_gpio_set_value(struct gpio_chip *chip, - unsigned offset, int value) -{ - __ath79_gpio_set_value(offset, value); -} +#include +#include +#include -static int ath79_gpio_direction_input(struct gpio_chip *chip, - unsigned offset) -{ - void __iomem *base = ath79_gpio_base; - unsigned long flags; - spin_lock_irqsave(&ath79_gpio_lock, flags); +struct _hw_gpio_irqhandle *ath_avm_gpio_first_handle; +static struct _gpio_function *current_gpio_table; +static unsigned int current_gpio_table_size; +unsigned int ath_gpio_int_both_edge; +unsigned int ath_gpio_int_active_low; +unsigned int ath_gpio_shiftreg_size = 0; +unsigned int ath_gpio_shiftreg_clk_pin = -1; +unsigned int ath_gpio_shiftreg_din_pin = -1; - __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << offset), - base + AR71XX_GPIO_REG_OE); +void avmnet_gpio(unsigned int gpio, unsigned int on) __attribute__ ((weak)); - spin_unlock_irqrestore(&ath79_gpio_lock, flags); +void ath_avm_gpio_dump_registers(const char *prefix); - return 0; +/*------------------------------------------------------------------------------------------*\ + * LOW LEVEL GPIO ACCESS FUNCTIONS +\*------------------------------------------------------------------------------------------*/ +void ath_gpio_config_output(int gpio) { + if(soc_is_ar934x() || soc_is_qca953x() || soc_is_qca955x() || soc_is_qca956x() ) + ath_reg_rmw_clear(ATH_GPIO_OE, (1 << gpio)); + else + ath_reg_rmw_set(ATH_GPIO_OE, (1 << gpio)); } -static int ath79_gpio_direction_output(struct gpio_chip *chip, - unsigned offset, int value) +void ath_gpio_config_input(int gpio) { - void __iomem *base = ath79_gpio_base; - unsigned long flags; - - spin_lock_irqsave(&ath79_gpio_lock, flags); - - if (value) - __raw_writel(1 << offset, base + AR71XX_GPIO_REG_SET); - else - __raw_writel(1 << offset, base + AR71XX_GPIO_REG_CLEAR); + if(soc_is_ar934x() || soc_is_qca953x() || soc_is_qca955x() || soc_is_qca956x() ) + ath_reg_rmw_set(ATH_GPIO_OE, (1 << gpio)); + else + ath_reg_rmw_clear(ATH_GPIO_OE, (1 << gpio)); +} - __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << offset), - base + AR71XX_GPIO_REG_OE); +#define gpio_ath_reg_wr(_phys, _val) ((*(volatile ath_reg_t *)KSEG1ADDR(_phys)) = (_val)) - spin_unlock_irqrestore(&ath79_gpio_lock, flags); +static inline void ath_gpio_out_val(int gpio, int val) { + if (val) { + gpio_ath_reg_wr(ATH_GPIO_SET, (1 << gpio)); + } else { + gpio_ath_reg_wr(ATH_GPIO_CLEAR, (1 << gpio)); + } + wmb(); +} - return 0; +static inline int ath_gpio_in_val(int gpio) { +#if 0 + printk(KERN_ERR "[%s] \n\tgpio_val =0x%08x\n" + "\tactive_low=0x%08x\n" + "\tboth_edge =0x%08x\n" + "\treturn_val=0x%08x (active %s)\n", __FUNCTION__, + (1 << gpio) & ath_reg_rd(ATH_GPIO_IN), + ath_gpio_int_active_low, + ath_gpio_int_both_edge, + ((1 << gpio) & ~ath_gpio_int_active_low & ath_gpio_int_both_edge) ? + ((1 << gpio) & ath_reg_rd(ATH_GPIO_IN)) : + ((1 << gpio) & (ath_reg_rd(ATH_GPIO_IN) ^ ath_gpio_int_both_edge)), + (ath_reg_rd(ATH_GPIO_INT_POLARITY) & (1 << gpio)) ? "high" : "low"); +#endif +#ifdef CONFIG_SOC_QCA955X + /*--- Bei Both-Edges-Interrupts den Active-High Wert bei Scorpion nicht invertieren ---*/ + if((1 << gpio) & ~ath_gpio_int_active_low & ath_gpio_int_both_edge) { + return (1 << gpio) & ath_reg_rd(ATH_GPIO_IN); + } +#endif + return (1 << gpio) & (ath_reg_rd(ATH_GPIO_IN) ^ ath_gpio_int_both_edge); } -static int ar934x_gpio_direction_input(struct gpio_chip *chip, unsigned offset) +/*------------------------------------------------------------------------------------------*\ +\*------------------------------------------------------------------------------------------*/ +static void ath_gpio_intr_enable(struct irq_data *data) { - void __iomem *base = ath79_gpio_base; - unsigned long flags; - - spin_lock_irqsave(&ath79_gpio_lock, flags); - - __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << offset), - base + AR71XX_GPIO_REG_OE); - - spin_unlock_irqrestore(&ath79_gpio_lock, flags); - - return 0; + ath_reg_rmw_set(ATH_GPIO_INT_MASK, (1 << (data->irq - ATH79_GPIO_IRQ_BASE))); + irqd_irq_masked(data); } -static int ar934x_gpio_direction_output(struct gpio_chip *chip, unsigned offset, - int value) +static void ath_gpio_intr_unmask(struct irq_data *data) { - void __iomem *base = ath79_gpio_base; - unsigned long flags; - - spin_lock_irqsave(&ath79_gpio_lock, flags); - - if (value) - __raw_writel(1 << offset, base + AR71XX_GPIO_REG_SET); - else - __raw_writel(1 << offset, base + AR71XX_GPIO_REG_CLEAR); + ath_reg_rmw_set(ATH_GPIO_INT_MASK, (1 << (data->irq - ATH79_GPIO_IRQ_BASE))); +} - __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << offset), - base + AR71XX_GPIO_REG_OE); +static void ath_gpio_intr_mask(struct irq_data *data) +{ + ath_reg_rmw_clear(ATH_GPIO_INT_MASK, (1 << (data->irq - ATH79_GPIO_IRQ_BASE))); +} - spin_unlock_irqrestore(&ath79_gpio_lock, flags); +static void ath_gpio_intr_disable(struct irq_data *data) +{ + ath_reg_rmw_clear(ATH_GPIO_INT_MASK, (1 << (data->irq - ATH79_GPIO_IRQ_BASE))); +} +static unsigned int ath_gpio_intr_startup(struct irq_data *data) +{ + ath_reg_rmw_set(ATH_GPIO_INT_ENABLE, (1 << (data->irq - ATH79_GPIO_IRQ_BASE))); + ath_gpio_intr_enable(data); return 0; } -static struct gpio_chip ath79_gpio_chip = { - .label = "ath79", - .get = ath79_gpio_get_value, - .set = ath79_gpio_set_value, - .direction_input = ath79_gpio_direction_input, - .direction_output = ath79_gpio_direction_output, - .base = 0, -}; - -static void __iomem *ath79_gpio_get_function_reg(void) +static void ath_gpio_intr_shutdown(struct irq_data *data) { - u32 reg = 0; - - if (soc_is_ar71xx() || - soc_is_ar724x() || - soc_is_ar913x() || - soc_is_ar933x()) - reg = AR71XX_GPIO_REG_FUNC; - else if (soc_is_ar934x()) - reg = AR934X_GPIO_REG_FUNC; - else - BUG(); - - return ath79_gpio_base + reg; + ath_gpio_intr_disable(data); } -void ath79_gpio_function_setup(u32 set, u32 clear) +static void ath_gpio_intr_ack(struct irq_data *data) { - void __iomem *reg = ath79_gpio_get_function_reg(); - unsigned long flags; + unsigned int gpio_bit = (1 << (data->irq - ATH79_GPIO_IRQ_BASE)); - spin_lock_irqsave(&ath79_gpio_lock, flags); + if(unlikely(ath_gpio_int_both_edge & gpio_bit)) { + ath_reg_wr(ATH_GPIO_INT_POLARITY, ath_reg_rd(ATH_GPIO_INT_POLARITY) ^ gpio_bit); + ath_reg_rd(ATH_GPIO_INT_POLARITY); + } +} + +static void ath_gpio_intr_end(struct irq_data *data) +{ + /*--- if (!(irq_desc[data->irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) ---*/ + if ( ! (irqd_irq_disabled(data) || irqd_irq_inprogress(data))) + ath_gpio_intr_enable(data); +} + +/*------------------------------------------------------------------------------------------*\ +\*------------------------------------------------------------------------------------------*/ +int ath_gpio_intr_set_type(struct irq_data *data, unsigned int flow_type) +{ + unsigned int gpio_bit; + struct irq_desc *desc = &irq_desc[data->irq]; + unsigned int irq = data->irq; + + gpio_bit = 1 << (irq - ATH79_GPIO_IRQ_BASE); + /*--- printk(KERN_ERR "[%s]: irq %d trigger type %d\n", __func__, irq, flow_type); ---*/ + + switch (flow_type) { + case IRQF_TRIGGER_NONE: + printk(KERN_ERR "[%s %d]: Assuming IRQ%d level triggered are already configured!\n", __func__, __LINE__, irq); + ath_gpio_int_both_edge &= ~gpio_bit; + raw_spin_unlock(&desc->lock); /*--- wir dürfen den Lock nicht behalten sonst haben wir einen deadlock ---*/ + __irq_set_handler_locked(irq, handle_level_irq); + raw_spin_lock(&desc->lock); + break; + case IRQF_TRIGGER_RISING: + /* edge triggered & active high */ + ath_gpio_int_both_edge &= ~gpio_bit; + ath_reg_rmw_clear(ATH_GPIO_INT_TYPE, gpio_bit); + ath_reg_rmw_set (ATH_GPIO_INT_POLARITY, gpio_bit); + raw_spin_unlock(&desc->lock); /*--- wir dürfen den Lock nicht behalten sonst haben wir einen deadlock ---*/ + __irq_set_handler_locked(irq, handle_edge_irq); + raw_spin_lock(&desc->lock); + break; + case IRQF_TRIGGER_FALLING: + /* edge triggered & active low */ + ath_gpio_int_both_edge &= ~gpio_bit; + ath_reg_rmw_clear(ATH_GPIO_INT_TYPE, gpio_bit); + ath_reg_rmw_clear(ATH_GPIO_INT_POLARITY, gpio_bit); + raw_spin_unlock(&desc->lock); /*--- wir dürfen den Lock nicht behalten sonst haben wir einen deadlock ---*/ + __irq_set_handler_locked(irq, handle_edge_irq); + raw_spin_lock(&desc->lock); + break; + case IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_HIGH: + /* both edge triggered & active high (emuliert, initial wie IRQF_TRIGGER_RISING) */ + ath_gpio_int_both_edge |= gpio_bit; + ath_gpio_int_active_low &= ~gpio_bit; + /*--- printk(KERN_ERR "[%s] IRQF_TRIGGER_HIGH gpio_bit=0x%x both_edge=0x%x", __FUNCTION__, gpio_bit, ath_gpio_int_both_edge); ---*/ + ath_reg_rmw_clear(ATH_GPIO_INT_TYPE, gpio_bit); + ath_reg_rmw_set (ATH_GPIO_INT_POLARITY, gpio_bit); + raw_spin_unlock(&desc->lock); /*--- wir dürfen den Lock nicht behalten sonst haben wir einen deadlock ---*/ + __irq_set_handler_locked(irq, handle_edge_irq); + raw_spin_lock(&desc->lock); + break; + case IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW: + /* both edge triggered & active high (emuliert, initial wie IRQF_TRIGGER_FALLING) */ + ath_gpio_int_both_edge |= gpio_bit; + ath_gpio_int_active_low |= gpio_bit; + /*--- printk(KERN_ERR "[%s] IRQF_TRIGGER_LOW gpio_bit=0x%x both_edge=0x%x", __FUNCTION__, gpio_bit, ath_gpio_int_both_edge); ---*/ + ath_reg_rmw_clear(ATH_GPIO_INT_TYPE, gpio_bit); + ath_reg_rmw_clear (ATH_GPIO_INT_POLARITY, gpio_bit); + raw_spin_unlock(&desc->lock); /*--- wir dürfen den Lock nicht behalten sonst haben wir einen deadlock ---*/ + __irq_set_handler_locked(irq, handle_edge_irq); + raw_spin_lock(&desc->lock); + break; + case IRQF_TRIGGER_HIGH: + /* level sensitive & active high */ + ath_gpio_int_both_edge &= ~gpio_bit; + ath_gpio_int_active_low &= ~gpio_bit; + ath_reg_rmw_set(ATH_GPIO_INT_TYPE, gpio_bit); + ath_reg_rmw_set (ATH_GPIO_INT_POLARITY, gpio_bit); + raw_spin_unlock(&desc->lock); /*--- wir dürfen den Lock nicht behalten sonst haben wir einen deadlock ---*/ + __irq_set_handler_locked(irq, handle_level_irq); + raw_spin_lock(&desc->lock); + break; + case IRQF_TRIGGER_LOW: + /* level sensitive & active low */ + ath_gpio_int_both_edge &= ~gpio_bit; + ath_gpio_int_active_low |= gpio_bit; + ath_reg_rmw_set(ATH_GPIO_INT_TYPE, gpio_bit); + ath_reg_rmw_clear(ATH_GPIO_INT_POLARITY, gpio_bit); + raw_spin_unlock(&desc->lock); /*--- wir dürfen den Lock nicht behalten sonst haben wir einen deadlock ---*/ + __irq_set_handler_locked(irq, handle_level_irq); + raw_spin_lock(&desc->lock); + break; + default: + printk(KERN_ERR "[%s %d]: Invalid irq %d trigger type %d\n", __func__, __LINE__, irq, flow_type); + break; + } + + return 0; +} + +/*------------------------------------------------------------------------------------------*\ +\*------------------------------------------------------------------------------------------*/ +struct irq_chip /* hw_interrupt_type */ ath_gpio_intr_controller = { + .name = "ATH GPIO", + .irq_set_type = ath_gpio_intr_set_type, + .irq_startup = ath_gpio_intr_startup, + .irq_shutdown = ath_gpio_intr_shutdown, + .irq_enable = ath_gpio_intr_enable, + .irq_disable = ath_gpio_intr_disable, + .irq_mask = ath_gpio_intr_mask, + .irq_unmask = ath_gpio_intr_unmask, + .irq_ack = ath_gpio_intr_ack, + .irq_eoi = ath_gpio_intr_end, +}; - __raw_writel((__raw_readl(reg) & ~clear) | set, reg); - /* flush write */ - __raw_readl(reg); +void __init ath_gpio_irq_init(int irq_base) { - spin_unlock_irqrestore(&ath79_gpio_lock, flags); + int i; + ath_gpio_int_both_edge = 0; + ath_gpio_int_active_low = 0; + for (i = irq_base; i < irq_base + ATH79_GPIO_IRQ_COUNT; i++) { + irq_set_chip_and_handler(i, &ath_gpio_intr_controller, handle_level_irq); + } + printk(KERN_ERR "[%s] done\n", __FUNCTION__); } -void ath79_gpio_function_enable(u32 mask) -{ - ath79_gpio_function_setup(mask, 0); -} -void ath79_gpio_function_disable(u32 mask) -{ - ath79_gpio_function_setup(0, mask); -} +/*------------------------------------------------------------------------------------------*\ + * AVM GPIO API +\*------------------------------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------------------------------*\ +\*------------------------------------------------------------------------------------------*/ +void ath_avm_gpio_dump_registers(const char *prefix) { + printk( KERN_ERR "[%s] GPIO register dump:\n", prefix ? prefix : ""); + printk( KERN_ERR " ATH_GPIO_OE(%08x) = 0x%08x\n", KSEG1ADDR(ATH_GPIO_OE), ath_reg_rd(ATH_GPIO_OE)); + printk( KERN_ERR " ATH_GPIO_IN(%08x) = 0x%08x\n", KSEG1ADDR(ATH_GPIO_IN), ath_reg_rd(ATH_GPIO_IN)); + printk( KERN_ERR " ATH_GPIO_OUT(%08x) = 0x%08x\n", KSEG1ADDR(ATH_GPIO_OUT), ath_reg_rd(ATH_GPIO_OUT)); + printk( KERN_ERR " ATH_GPIO_INT_ENABLE(%08x) = 0x%08x\n", KSEG1ADDR(ATH_GPIO_INT_ENABLE), ath_reg_rd(ATH_GPIO_INT_ENABLE)); + printk( KERN_ERR " ATH_GPIO_INT_TYPE(%08x) = 0x%08x\n", KSEG1ADDR(ATH_GPIO_INT_TYPE), ath_reg_rd(ATH_GPIO_INT_TYPE)); + printk( KERN_ERR " ATH_GPIO_INT_POLARITY(%08x) = 0x%08x\n", KSEG1ADDR(ATH_GPIO_INT_POLARITY), ath_reg_rd(ATH_GPIO_INT_POLARITY)); + printk( KERN_ERR " ATH_GPIO_INT_PENDING(%08x) = 0x%08x\n", KSEG1ADDR(ATH_GPIO_INT_PENDING), ath_reg_rd(ATH_GPIO_INT_PENDING)); + printk( KERN_ERR " ATH_GPIO_INT_MASK(%08x) = 0x%08x\n", KSEG1ADDR(ATH_GPIO_INT_MASK), ath_reg_rd(ATH_GPIO_INT_MASK)); +#ifdef CONFIG_SOC_AR724X + printk( KERN_ERR " ATH_GPIO_FUNCTIONS(%08x) = 0x%08x\n", KSEG1ADDR(ATH_GPIO_FUNCTIONS), ath_reg_rd(ATH_GPIO_FUNCTIONS)); + printk( KERN_ERR " ATH_GPIO_FUNCTION_2 = 0x%08x\n", ath_reg_rd(ATH_GPIO_FUNCTION_2)); +#endif /*--- #ifdef CONFIG_SOC_AR724X ---*/ +#if defined(CONFIG_SOC_AR934X) || defined(CONFIG_SOC_QCA955X) + printk( KERN_ERR " ATH_GPIO_IN_ETH_SWITCH_LED(%08x)= 0x%08x\n", KSEG1ADDR(ATH_GPIO_IN_ETH_SWITCH_LED), ath_reg_rd(ATH_GPIO_IN_ETH_SWITCH_LED)); + printk( KERN_ERR " ATH_GPIO_OUT_FUNCTION0(%08x) = 0x%08x (gpio 0-3)\n", KSEG1ADDR(ATH_GPIO_OUT_FUNCTION0), ath_reg_rd(ATH_GPIO_OUT_FUNCTION0)); + printk( KERN_ERR " ATH_GPIO_OUT_FUNCTION1(%08x) = 0x%08x (gpio 4-7)\n", KSEG1ADDR(ATH_GPIO_OUT_FUNCTION1), ath_reg_rd(ATH_GPIO_OUT_FUNCTION1)); + printk( KERN_ERR " ATH_GPIO_OUT_FUNCTION2(%08x) = 0x%08x (gpio 8-11)\n", KSEG1ADDR(ATH_GPIO_OUT_FUNCTION2), ath_reg_rd(ATH_GPIO_OUT_FUNCTION2)); + printk( KERN_ERR " ATH_GPIO_OUT_FUNCTION3(%08x) = 0x%08x (gpio 12-15)\n", KSEG1ADDR(ATH_GPIO_OUT_FUNCTION3), ath_reg_rd(ATH_GPIO_OUT_FUNCTION3)); + printk( KERN_ERR " ATH_GPIO_OUT_FUNCTION4(%08x) = 0x%08x (gpio 16-19)\n", KSEG1ADDR(ATH_GPIO_OUT_FUNCTION4), ath_reg_rd(ATH_GPIO_OUT_FUNCTION4)); + printk( KERN_ERR " ATH_GPIO_OUT_FUNCTION5(%08x) = 0x%08x (gpio 20-23)\n", KSEG1ADDR(ATH_GPIO_OUT_FUNCTION5), ath_reg_rd(ATH_GPIO_OUT_FUNCTION5)); + printk( KERN_ERR " ATH_GPIO_IN_ENABLE0(%08x) = 0x%08x (UART0/SPI)\n", KSEG1ADDR(ATH_GPIO_IN_ENABLE0), ath_reg_rd(ATH_GPIO_IN_ENABLE0)); + printk( KERN_ERR " ATH_GPIO_IN_ENABLE1(%08x) = 0x%08x (I2S)\n", KSEG1ADDR(ATH_GPIO_IN_ENABLE1), ath_reg_rd(ATH_GPIO_IN_ENABLE1)); + printk( KERN_ERR " ATH_GPIO_IN_ENABLE2(%08x) = 0x%08x (ETHRX)\n", KSEG1ADDR(ATH_GPIO_IN_ENABLE2), ath_reg_rd(ATH_GPIO_IN_ENABLE2)); + printk( KERN_ERR " ATH_GPIO_IN_ENABLE3(%08x) = 0x%08x (MDIO)\n", KSEG1ADDR(ATH_GPIO_IN_ENABLE3), ath_reg_rd(ATH_GPIO_IN_ENABLE3)); + printk( KERN_ERR " ATH_GPIO_IN_ENABLE4(%08x) = 0x%08x (SLIC)\n", KSEG1ADDR(ATH_GPIO_IN_ENABLE4), ath_reg_rd(ATH_GPIO_IN_ENABLE4)); + printk( KERN_ERR " ATH_GPIO_IN_ENABLE5(%08x) = 0x%08x (I2C)\n", KSEG1ADDR(ATH_GPIO_IN_ENABLE5), ath_reg_rd(ATH_GPIO_IN_ENABLE5)); + printk( KERN_ERR " ATH_GPIO_IN_ENABLE6(%08x) = 0x%08x (?)\n", KSEG1ADDR(ATH_GPIO_IN_ENABLE6), ath_reg_rd(ATH_GPIO_IN_ENABLE6)); + printk( KERN_ERR " ATH_GPIO_IN_ENABLE7(%08x) = 0x%08x (?)\n", KSEG1ADDR(ATH_GPIO_IN_ENABLE7), ath_reg_rd(ATH_GPIO_IN_ENABLE7)); + printk( KERN_ERR " ATH_GPIO_IN_ENABLE8(%08x) = 0x%08x (?)\n", KSEG1ADDR(ATH_GPIO_IN_ENABLE8), ath_reg_rd(ATH_GPIO_IN_ENABLE8)); + printk( KERN_ERR " ATH_GPIO_IN_ENABLE9(%08x) = 0x%08x (UART1)\n", KSEG1ADDR(ATH_GPIO_IN_ENABLE9), ath_reg_rd(ATH_GPIO_IN_ENABLE9)); + printk( KERN_ERR " ATH_GPIO_FUNCTIONS(%08x) = 0x%08x\n", KSEG1ADDR(ATH_GPIO_FUNCTIONS), ath_reg_rd(ATH_GPIO_FUNCTIONS)); +#endif +} +EXPORT_SYMBOL(ath_avm_gpio_dump_registers); + +#if defined(CONFIG_SOC_AR934X) || defined(CONFIG_SOC_QCA953X) || defined(CONFIG_SOC_QCA955X) || defined(CONFIG_SOC_QCA956X) +/*--------------------------------------------------------------------------------*\ + * mbahr: Doppelbelegung erlaubt ? + * was sind ATH_GPIO_IN_ENABLE5 - ATH_GPIO_IN_ENABLE8 ?? +\*--------------------------------------------------------------------------------*/ +static void ath_infunction_clear(unsigned int gpio_pin) { + unsigned int inaddr, i; + for(inaddr = ATH_GPIO_IN_ENABLE (0); inaddr <= ATH_GPIO_IN_ENABLE (9); inaddr += sizeof(unsigned int)) { + unsigned int funcin_val; + if((inaddr >= ATH_GPIO_IN_ENABLE (4)) && (inaddr != ATH_GPIO_IN_ENABLE (9))) { + /*--- undokumentiert ? ---*/ + continue; + } + funcin_val = ath_reg_rd(inaddr); + for(i = 0; i < 32; i += 8) { + if(((funcin_val >> i) & 0xff) == gpio_pin) { + /*--- printk(KERN_ERR "warning[%d]: %08x %08x contain gpio_pin %d\n", i, inaddr, funcin_val, gpio_pin); ---*/ + funcin_val = (funcin_val & ~(0xff << i)); + ath_reg_wr(inaddr, funcin_val); + } + } + } +} + +/*------------------------------------------------------------------------------------------*\ +\*------------------------------------------------------------------------------------------*/ +void __gpio_infunction_set(unsigned int gpio_pin, int func) +{ + unsigned int val; +#if 0 + if(((func == GPIO_IN_SPI_MISO) || (func == GPIO_IN_UART0_SIN)) && (gpio_pin > 17)) { + printk("[%s] error: invalid GPIO %d for input function %d (only gpio pin < 18 allowed)\n",__FUNCTION__, gpio_pin, func); + return; + } +#endif + ath_infunction_clear(gpio_pin); + if(func == NO_FUNCTION) { + /*--- printk("[%s] Clear input function register for gpio %d\n", __FUNCTION__, gpio_pin); ---*/ + return; + } + val = ath_reg_rd(ATH_GPIO_IN_ENABLE_REG(func)); + val = ATH_GPIO_IN_ENABLE_SET(val, func, gpio_pin); + ath_reg_wr(ATH_GPIO_IN_ENABLE_REG(func), val); + /*--- printk("[%s] Set input function register for gpio %u to func %d (reg=0x%x, val=0x%x)\n", __FUNCTION__, ---*/ + /*--- gpio_pin, func, GPIO_IN_ENABLE_REG(func), val); ---*/ +} + +/*------------------------------------------------------------------------------------------*\ +\*------------------------------------------------------------------------------------------*/ +void __gpio_outfunction_set(unsigned int gpio_pin, int func) +{ + unsigned int val; + if(func == NO_FUNCTION) + func = 0; + val = ath_reg_rd(ATH_GPIO_OUT_FUNC_REG(gpio_pin)); + val = ATH_GPIO_OUT_FUNC_SET(val, func, gpio_pin); + ath_reg_wr(ATH_GPIO_OUT_FUNC_REG(gpio_pin), val); + /*--- printk("[%s] Set output function register for gpio %u to func %d (reg=0x%x, val=0x%x)\n", __FUNCTION__, ---*/ + /*--- gpio_pin, func, GPIO_OUT_FUNC_REG(gpio_pin), val); ---*/ +} + +static inline void ath_avm_gpio_infunction_set(unsigned int gpio_pin, int func) +{ + __gpio_outfunction_set(gpio_pin, NO_FUNCTION); + __gpio_infunction_set(gpio_pin, func); +} +static inline void ath_avm_gpio_outfunction_set(unsigned int gpio_pin, int func) +{ + __gpio_infunction_set(gpio_pin, NO_FUNCTION); + __gpio_outfunction_set(gpio_pin, func); +} +static inline void ath_avm_gpio_inoutfunction_set(unsigned int gpio_pin, int func) +{ + __gpio_infunction_set(gpio_pin, func & 0xFFFF); + __gpio_outfunction_set(gpio_pin, func >> 16); +} +#endif + +/*------------------------------------------------------------------------------------------*\ +\*------------------------------------------------------------------------------------------*/ +void ath_avm_gpio_init_functions(void) +{ + unsigned int hwrev = 0, pin/*, i*/; + char *s, *p; + + s = prom_getenv("HWRevision"); + if (s) { + hwrev = simple_strtoul(s, &p, 10); + } else { + printk("[%s] error: no HWRevision detected in environment variables\n", __func__); + BUG_ON(1); + } + + current_gpio_table = g_gpio_table; + current_gpio_table_size = g_gpio_table_size; + + for(pin = 0; pin < current_gpio_table_size; pin++) { + if(current_gpio_table[pin].func == IGNORE_FUNCTION) + continue; + +#if defined CONFIG_SOC_QCA956X + if ((pin >= 14) && (pin <= 17)) +#else + if(pin < 4) +#endif + ath_reg_rmw_set(ATH_GPIO_FUNCTIONS, ATH_GPIO_FUNCTION_JTAG_DISABLE); + + switch (current_gpio_table[pin].dir) { + case GPIO_INPUT_PIN: +#if defined(CONFIG_SOC_AR934X) || defined(CONFIG_SOC_QCA953X) || defined(CONFIG_SOC_QCA955X) || defined(CONFIG_SOC_QCA956X) + ath_avm_gpio_infunction_set(pin, current_gpio_table[pin].func); +#endif + ath_gpio_config_input(pin); + + break; + + case GPIO_OUTPUT_PIN: +#if defined(CONFIG_SOC_AR934X) || defined(CONFIG_SOC_QCA953X) || defined(CONFIG_SOC_QCA955X) || defined(CONFIG_SOC_QCA956X) + ath_avm_gpio_outfunction_set(pin, current_gpio_table[pin].func); +#endif + ath_gpio_config_output(pin); + + break; + + case GPIO_OUTPUT_INPUT_PIN: +#if defined(CONFIG_SOC_AR934X) || defined(CONFIG_SOC_QCA953X) || defined(CONFIG_SOC_QCA955X) || defined(CONFIG_SOC_QCA956X) + ath_avm_gpio_inoutfunction_set(pin, current_gpio_table[pin].func); +#endif + ath_gpio_config_output(pin); + + break; + } + } +} + +/*------------------------------------------------------------------------------------------*\ +\*------------------------------------------------------------------------------------------*/ +void ath_gpio_shift_register_load(unsigned int mask, unsigned int values) { + unsigned int i, clk, din, dataout; + static unsigned int ath_gpio_shiftreg_value = 0; + + clk = 1 << ath_gpio_shiftreg_clk_pin; + din = 1 << ath_gpio_shiftreg_din_pin; + +#if 0 + printk(KERN_ERR "[%s] current=0x%x mask=0x%x values=0x%x new=0x%x\n",__FUNCTION__, + ath_gpio_shiftreg_value, mask, values, (ath_gpio_shiftreg_value & ~mask) | (mask & values)); +#endif + + ath_gpio_shiftreg_value &= ~mask; + ath_gpio_shiftreg_value |= mask & values; + ath_gpio_shiftreg_value |= 1 << (ath_gpio_shiftreg_size - 1); /*--- muss zum Reset gesetzt sein ---*/ + + for(i = ath_gpio_shiftreg_size; i; i-- ) { +#if 0 + printk(KERN_ERR "[%s] current=0x%x & 0x%x => 0x%x\n", __FUNCTION__, + ath_gpio_shiftreg_value, (1 << (i - 1)), (ath_gpio_shiftreg_value & (1 << (i - 1))) ? 1 : 0); +#endif + dataout = (ath_gpio_shiftreg_value & (1 << (i - 1))) ? 1 : 0; + + gpio_ath_reg_wr(ATH_GPIO_CLEAR, clk); + + if (dataout) + gpio_ath_reg_wr(ATH_GPIO_SET, din); + else + gpio_ath_reg_wr(ATH_GPIO_CLEAR, din); + gpio_ath_reg_wr(ATH_GPIO_SET, clk); + udelay(1); + wmb(); + } + + gpio_ath_reg_wr(ATH_GPIO_CLEAR, clk|din); +} + +/*------------------------------------------------------------------------------------------*\ +\*------------------------------------------------------------------------------------------*/ +int ath_gpio_setup_pin_mode(unsigned int gpio_pin, enum _hw_gpio_function pin_mode, enum _hw_gpio_direction pin_dir) +{ +#if defined(CONFIG_SOC_AR724X) + unsigned int bits = 0; + unsigned int bits2 = 0; +#elif defined(CONFIG_SOC_AR934X) || defined(CONFIG_SOC_QCA955X) + unsigned int function = NO_FUNCTION; +#endif + +#if defined(CONFIG_SOC_AR724X) + switch (gpio_pin) { + case 0: + /* SPI Chip select on GPIO_0 [Bit 13] */ + bits |= ATH_GPIO_FUNCTION_SPI_CS_0_EN; + /* Enables I2S_WS on GPIO_0 [FUNC_2 Bit 4] */ + bits2 |= ATH_GPIO_FUNCTION_2_EN_I2WS_ON_0; + break; + case 1: + /* SPI Chip select on GPIO_1 [Bit 14] */ + bits |= ATH_GPIO_FUNCTION_SPI_CS_1_EN; + /* Enables I2S_CK Out on GPIO_1 [FUNC_2 Bit 3] */ + bits2 |= ATH_GPIO_FUNCTION_2_EN_I2SCK_ON_1; + break; + case 2: + case 3: + case 4: + case 5: + /* SPI Chip select on GPIO_2 - GPIO_5 [Bit 18] */ + bits |= ATH_GPIO_FUNCTION_SPI_EN; + break; + case 6: + case 7: + case 8: + /*--- case 11: ---*/ + /*--- case 12: ---*/ + /* I2S on GPIO_6-8 and 11-12 [Bit 26] */ + bits |= ATH_GPIO_FUNCTION_I2S0_EN; + break; + case 9: + case 10: + /* Enables UART on GPIO_11 and GPIO_12 [Bit 1] */ + bits |= ATH_GPIO_FUNCTION_UART_EN; + break; + case 11: + if( pin_mode == GPIO_PIN ) { + /* Master Audio CLK_MCK on GPIO_11 (only if Bit 26 is set) [Bit 27] - clear only! */ + bits |= ATH_GPIO_FUNCTION_I2S_MCKEN; + /* Disable undocumented Function [Bit 20] (otherwise GPIO mode won't work) */ + bits |= ATH_GPIO_FUNCTION_CLK_OBS6_ENABLE; + } + case 12: + /* Enables UART RTS/CTS on GPIO_11 and GPIO_12 [Bit 2] - default */ + bits |= ATH_GPIO_FUNCTION_UART_RTS_CTS_EN; + /* I2S on GPIO_6-8 and 11-12 [Bit 26] - clear only! */ + if( pin_mode == GPIO_PIN ) + bits |= ATH_GPIO_FUNCTION_I2S0_EN; + if(gpio_pin == 12) { + /* Enables I2S_SD on GPIO_12 [FUNC_2 Bit 5] */ + bits2 |= ATH_GPIO_FUNCTION_2_EN_I2WS_ON_0; + } + break; + case 13: + /* Enables Ethernet LED on GPIO_13 [Bit 13] */ + bits |= ATH_GPIO_FUNCTION_ETH_SWITCH_LED0_EN; + if( pin_mode == GPIO_PIN ) + /* Disable undocumented Function [Bit 8] (otherwise GPIO mode won't work) */ + bits |= ATH_GPIO_FUNCTION_CLK_OBS1_ENABLE; + if( pin_mode == GPIO_PIN ) + /* Disable TCK as SPDIF Serial out on GPIO_13 [Bit 30] - clear only! */ + bits |= ATH_GPIO_FUNCTION_SPDIF_EN; + break; + case 14: + case 15: + case 16: + /* Enables I2C LED on GPIO_14 - 16 [FUNC_2 Bit 1] */ + bits2 |= ATH_GPIO_FUNCTION_2_I2S_ON_LED; + break; + default: + return -1; + } + if ( pin_mode == GPIO_PIN ) { + if(bits) + ath_reg_rmw_clear(ATH_GPIO_FUNCTIONS, bits); + if(bits2) + ath_reg_rmw_clear(ATH_GPIO_FUNCTION_2, bits2); + } else { + if(bits) + ath_reg_rmw_set(ATH_GPIO_FUNCTIONS, bits); + if(bits2) + ath_reg_rmw_set(ATH_GPIO_FUNCTION_2, bits2); + } +#elif defined(CONFIG_SOC_AR934X) || defined(CONFIG_SOC_QCA955X) + /*--- die rein generische Loesung: ---*/ + switch(pin_mode) { + /*--- Sonderfaelle: ---*/ + case FUNCTION_TDM_FS: + function = (pin_dir == GPIO_INPUT_PIN) ? GPIO_IN_SLIC_PCM_FS : GPIO_OUT_SLIC_PCM_FS; + break; + case FUNCTION_TDM_CLK: + /*--- IN: SLIC_PCM_DCL (Doppelfunktion mit I2S_MCLK) ---*/ + function = (pin_dir == GPIO_INPUT_PIN) ? GPIO_IN_I2S_MCLK : GPIO_OUT_SLIC_PCM_CLK; + break; + case FUNCTION_SPDIF_OUT: + function = GPIO_OUT_SPDIF_OUT; + /*--- function = GPIO_OUT_SPDIF_OUT_23; ---*/ + /*--- printk(KERN_ERR"%s: pin=%d pin_mode=%d function=%x\n", __func__, gpio_pin, pin_mode, function); ---*/ + ath_reg_rmw_set(ATH_GPIO_FUNCTIONS, ATH_GPIO_FUNCTION_SPDIF_EN | ATH_GPIO_FUNCTION_STEREO_EN); + /*--- printk(KERN_ERR "%s: pin=%d function=%d - > %x \n", __func__, gpio_pin, function, ath_reg_rd(ATH_GPIO_FUNCTIONS)); ---*/ + break; + /*--- Funktion aus der hw-gpio-table ---*/ + case FUNCTION_PIN: + if((current_gpio_table_size > gpio_pin) && + (current_gpio_table[gpio_pin].func != IGNORE_FUNCTION)) { + function = current_gpio_table[gpio_pin].func; + } + if(function == NO_FUNCTION) { + printk(KERN_ERR "%s: error: no function-mode in gpio_table (%d)\n", __func__, gpio_pin); + } + /*--- printk(KERN_ERR "%s: pin=%d function=%d\n", __func__, gpio_pin, function); ---*/ + /*--- Sonderfall I2S: AudioClock enablen ---*/ + switch(function) { + case GPIO_OUT_I2S_MCK: + ath_reg_rmw_set(ATH_GPIO_FUNCTIONS, ATH_GPIO_FUNCTION_I2S_MCKEN); +/*--- printk(KERN_ERR "%s: pin=%d function=%d - > %x \n", __func__, gpio_pin, function, ath_reg_rd(ATH_GPIO_FUNCTIONS)); ---*/ + break; + case GPIO_OUT_I2S_CLK: + ath_reg_rmw_set(ATH_GPIO_FUNCTIONS, ATH_GPIO_FUNCTION_I2S_REFCLKEN); +/*--- printk(KERN_ERR "%s: pin=%d function=%d - > %x \n", __func__, gpio_pin, function, ath_reg_rd(ATH_GPIO_FUNCTIONS)); ---*/ + break; + case GPIO_OUT_I2S_SD: + ath_reg_rmw_set(ATH_GPIO_FUNCTIONS, ATH_GPIO_FUNCTION_I2S0_EN); +/*--- printk(KERN_ERR "%s: pin=%d function=%d - > %x \n", __func__, gpio_pin, function, ath_reg_rd(ATH_GPIO_FUNCTIONS)); ---*/ + break; + case GPIO_OUT_I2S_WS: + default: + break; + } + break; + case GPIO_PIN: break; + default: + printk(KERN_ERR "%s: error: no configuration exist for pin_mode=%d\n", __func__, pin_mode); + break; + } + if(pin_dir == GPIO_INPUT_PIN) { + ath_avm_gpio_infunction_set(gpio_pin, function); + ath_gpio_config_input(gpio_pin); + } else { + ath_avm_gpio_outfunction_set(gpio_pin, function); + ath_gpio_config_output(gpio_pin); + } +#endif /*--- #ifdef CONFIG_SOC_AR724X ---*/ -void __init ath79_gpio_init(void) -{ - int err; + return 0; +} - if (soc_is_ar71xx()) - ath79_gpio_count = AR71XX_GPIO_COUNT; - else if (soc_is_ar7240()) - ath79_gpio_count = AR7240_GPIO_COUNT; - else if (soc_is_ar7241() || soc_is_ar7242()) - ath79_gpio_count = AR7241_GPIO_COUNT; - else if (soc_is_ar913x()) - ath79_gpio_count = AR913X_GPIO_COUNT; - else if (soc_is_ar933x()) - ath79_gpio_count = AR933X_GPIO_COUNT; - else if (soc_is_ar934x()) - ath79_gpio_count = AR934X_GPIO_COUNT; - else if (soc_is_qca955x()) - ath79_gpio_count = QCA955X_GPIO_COUNT; - else - BUG(); +/*------------------------------------------------------------------------------------------*\ +\*------------------------------------------------------------------------------------------*/ +int ath_avm_gpio_ctrl(unsigned int gpio_pin, enum _hw_gpio_function pin_mode, enum _hw_gpio_direction pin_dir) +{ + if (gpio_pin > ATH79_GPIO_IRQ_COUNT) { + if ((gpio_pin >= 100) && (gpio_pin < 100 + ath_gpio_shiftreg_size)) { + return (pin_dir == GPIO_INPUT_PIN) ? -1 : 0; // input on shift register not supported + } + if ((gpio_pin >= 200) && (gpio_pin < 300)) { + return (pin_dir == GPIO_INPUT_PIN) ? -1 : 0; // input on lanphy-gpio not supported + } + return -1; + } +#if 0 + printk("[%s] gpio=%u as %s(%d) direction=%s\n", __FUNCTION__, gpio_pin, + pin_mode == GPIO_PIN ? "gpio" : "function", pin_mode, + pin_dir == GPIO_INPUT_PIN ? "input" : "output"); +#endif + ath_gpio_setup_pin_mode(gpio_pin, pin_mode, pin_dir); + + if(pin_mode == GPIO_PIN) { + if (pin_dir == GPIO_INPUT_PIN) + ath_gpio_config_input( gpio_pin ); + else + ath_gpio_config_output( gpio_pin ); + } + /*--- ath_avm_gpio_dump_registers(__func__); ---*/ + return 0; +} + +/*------------------------------------------------------------------------------------------*\ +\*------------------------------------------------------------------------------------------*/ +int ath_avm_gpio_out_bit(unsigned int gpio_pin, int value) { + + /*--- printk(KERN_ERR "{%s} gpio_pin %d value 0x%x\n", __func__, gpio_pin, value); ---*/ + + if ((gpio_pin >= 100) && (gpio_pin < 200)) { + if (gpio_pin >= 100 + ath_gpio_shiftreg_size) { + /*--- printk(KERN_ERR "{%s} error: invalid shift gpio %d\n", __func__, gpio_pin); ---*/ + return -1; + } + + if((gpio_pin >= 100) && ath_gpio_shiftreg_size) { + /*--- printk(KERN_ERR "{%s} avmnet_gpio %d value 0x%x\n", __func__, gpio_pin, value); ---*/ + gpio_pin -= 100; + ath_gpio_shift_register_load(1 << gpio_pin, (value ? 1 : 0) << gpio_pin); + return 0; + } + } + if ((gpio_pin >= 200) && (gpio_pin < 300)) { + /*--- printk(KERN_ERR "{%s} avmnet_gpio %d value 0x%x\n", __func__, gpio_pin, value); ---*/ + avmnet_gpio(gpio_pin - 200, value); + } - ath79_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE); - ath79_gpio_chip.ngpio = ath79_gpio_count; - if (soc_is_ar934x() || soc_is_qca955x()) { - ath79_gpio_chip.direction_input = ar934x_gpio_direction_input; - ath79_gpio_chip.direction_output = ar934x_gpio_direction_output; + if (gpio_pin > ATH79_GPIO_IRQ_COUNT) { + return -1; } - err = gpiochip_add(&ath79_gpio_chip); - if (err) - panic("cannot add AR71xx GPIO chip, error=%d", err); + ath_gpio_out_val(gpio_pin, value); + return 0; } -int gpio_get_value(unsigned gpio) -{ +/*------------------------------------------------------------------------------------------*\ +\*------------------------------------------------------------------------------------------*/ +int ath_avm_gpio_in_bit(unsigned int gpio_pin){ + /* wird von sammel-treiber verwendet */ + if (gpio_pin > ATH79_GPIO_IRQ_COUNT) { + return -1; // Invalid pin or shift register (input not supported) + } + return ath_gpio_in_val( gpio_pin ) ? 1 : 0; +} + +/*------------------------------------------------------------------------------------------*\ +\*------------------------------------------------------------------------------------------*/ +unsigned int ath_avm_gpio_in_value(void){ + return ath_reg_rd(ATH_GPIO_IN); +} + +/*------------------------------------------------------------------------------------------*\ +\*------------------------------------------------------------------------------------------*/ +void ath_avm_gpio_set_bitmask(unsigned int mask, unsigned int value){ + /* wird von sammel-treiber verwendet */ + ath_reg_rmw_clear(ATH_GPIO_OUT, mask); + ath_reg_rmw_set(ATH_GPIO_OUT, (value & mask)); +} + +/*------------------------------------------------------------------------------------------*\ +\*------------------------------------------------------------------------------------------*/ +int gpio_get_value(unsigned gpio) { +#if 0 if (gpio < ath79_gpio_count) return __ath79_gpio_get_value(gpio); return __gpio_get_value(gpio); +#else + return ath_avm_gpio_in_bit(gpio); +#endif } -EXPORT_SYMBOL(gpio_get_value); -void gpio_set_value(unsigned gpio, int value) -{ +/*------------------------------------------------------------------------------------------*\ +\*------------------------------------------------------------------------------------------*/ +void gpio_set_value(unsigned gpio, int value) { +#if 0 if (gpio < ath79_gpio_count) __ath79_gpio_set_value(gpio, value); else __gpio_set_value(gpio, value); +#else + ath_avm_gpio_out_bit(gpio, value); +#endif +} + +/*------------------------------------------------------------------------------------------*\ +\*------------------------------------------------------------------------------------------*/ +int ath_avm_gpio_init(void){ + +#if defined(CONFIG_SOC_AR934X) || defined(CONFIG_SOC_QCA953X) || defined(CONFIG_SOC_QCA955X) || defined(CONFIG_SOC_QCA956X) + int gpio; +#endif + + /*--- ath_avm_gpio_dump_registers(__func__); ---*/ + ath_avm_gpio_first_handle = NULL; + ath_avm_gpio_init_functions(); + +#if defined (CONFIG_SOC_AR934X) || defined (CONFIG_SOC_QCA953X) || defined (CONFIG_SOC_QCA955X) || defined (CONFIG_SOC_QCA956X) + avm_get_hw_config(AVM_HW_CONFIG_VERSION, "gpio_avm_shift_clk", &ath_gpio_shiftreg_clk_pin, NULL); + avm_get_hw_config(AVM_HW_CONFIG_VERSION, "gpio_avm_shift_din", &ath_gpio_shiftreg_din_pin, NULL); + avm_get_hw_config(AVM_HW_CONFIG_VERSION, "shift_register_size", &ath_gpio_shiftreg_size, NULL); + + if(avm_get_hw_config(AVM_HW_CONFIG_VERSION, "gpio_avm_spi_cs_dis_dac", &gpio, NULL) == 0) { + pr_debug("disable spi_cs_dac\n"); + ath_avm_gpio_out_bit(gpio, 0); /*--- disable SPI_CS1-Access (or'd with SPDIF_OUT) ---*/ + } + + if(avm_get_hw_config(AVM_HW_CONFIG_VERSION, "gpio_avm_peregrine_reset", &gpio, NULL) == 0) { + pr_debug("Peregrine out of reset\n"); + ath_avm_gpio_out_bit(gpio, 1); /*--- disable RESET ---*/ + } + + if(avm_get_hw_config(AVM_HW_CONFIG_VERSION, "gpio_avm_usb_reset", &gpio, NULL) == 0) { + ath_avm_gpio_out_bit(gpio, 0); /*--- enable RESET ---*/ + } + +#endif + return 0; } +postcore_initcall(ath_avm_gpio_init); + EXPORT_SYMBOL(gpio_set_value); +EXPORT_SYMBOL(gpio_get_value); -int gpio_to_irq(unsigned gpio) -{ - /* FIXME */ - return -EINVAL; -} -EXPORT_SYMBOL(gpio_to_irq); +EXPORT_SYMBOL(ath_avm_gpio_init); +EXPORT_SYMBOL(ath_avm_gpio_ctrl); +EXPORT_SYMBOL(ath_avm_gpio_out_bit); +EXPORT_SYMBOL(ath_avm_gpio_in_bit); +EXPORT_SYMBOL(ath_avm_gpio_in_value); +EXPORT_SYMBOL(ath_avm_gpio_set_bitmask); -int irq_to_gpio(unsigned irq) -{ - /* FIXME */ - return -EINVAL; -} -EXPORT_SYMBOL(irq_to_gpio);