#include #include #include #include #include #include #include #include "ce2600-gpio.h" /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ //#define DEBUG_WLAN_DECT_CONFIG #if defined(DEBUG_WLAN_DECT_CONFIG) #define DBG_WLAN_DECT(arg...) printk(KERN_ERR arg) #else #define DBG_WLAN_DECT(arg...) #endif #define PUMA_MAX_CONFIG_ENTRIES 8 char *prom_getenv(char *name) { const char *entry = NULL; struct device_node *chosen; chosen = of_find_node_by_name(NULL, "chosen"); if(chosen){ entry = of_get_property(chosen, name, NULL ); } return (char *)entry; } EXPORT_SYMBOL(prom_getenv); static struct avm_prom_mtd_device prom_mtd; /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ int init_wlan_dect_config(struct mtd_info *mtd) { const char *entry = NULL; struct device_node *chosen; uint64_t cfg_offset; int entry_len, i, ret, result; chosen = of_find_node_by_name(NULL, "chosen"); if(!chosen){ printk(KERN_WARNING "[%s] Device tree node \"chosen\" not found\n", __func__); return -ENODEV; } entry = of_get_property(chosen, "wlan_dect_configs", &entry_len); printk(KERN_ERR "[%s] entry: %p entry_len: 0x%x\n", __func__, entry, entry_len); if(!entry || entry_len == 0 || (entry_len % sizeof(uint64_t)) != 0){ printk(KERN_WARNING "[%s] No property \"wlan_dect_configs\" found in device tree or property length invalid\n", __func__); return -EINVAL; } for (i = 0; i < entry_len; i += 8){ cfg_offset = be64_to_cpu(*(uint64_t *)&entry[i]); pr_err("[%s] %d: 0x%016llx\n", __func__, i / 8, cfg_offset); } prom_mtd.mtd = mtd; ret = avm_prom_config_add_mtd_device(&prom_mtd); if (ret) { pr_err("%s: Error registering mtd: %d\n", __func__, ret); prom_mtd.mtd = NULL; return ret; } i = result = 0; while(entry_len > 0 && i < PUMA_MAX_CONFIG_ENTRIES){ cfg_offset = of_read_number((__be32 *)entry, sizeof(uint64_t) / sizeof(uint32_t)); entry += sizeof(uint64_t); entry_len -= sizeof(uint64_t); if(cfg_offset > 0){ ret = avm_prom_load_config_entry(cfg_offset); if (ret) { result = ret; pr_err("%s: Error loading entry at offset %llu: %d\n", __func__, (unsigned long long)cfg_offset, ret); } else { DBG_WLAN_DECT("[%s] Found config entry pointer: 0x%08lx\n", __func__, cfg_offset); } ++i; } } printk(KERN_INFO "[%s] Found %d config entry pointers.\n", __func__, i); return result; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include #include /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ int x86_gpio_ctrl(unsigned int gpio_pin, enum _hw_gpio_function pin_mode, enum _hw_gpio_direction pin_dir) { struct gpio_chip *chip; /*--- printk(KERN_ERR"%s(%d) %s %s\n", __func__, gpio_pin, pin_mode == FUNCTIONAL_PIN ? "func" : "gpio", pin_dir == GPIO_OUTPUT_PIN ? "out" : "in"); ---*/ chip = intelce_get_gpio_chip(&gpio_pin); if(chip == NULL) { printk(KERN_ERR"%s(%d) failed\n", __func__, gpio_pin); return -1; } if(pin_dir == GPIO_OUTPUT_PIN) { ce2600_gpio_direction_output(chip, gpio_pin, ce2600_gpio_input(chip, gpio_pin)); } else { ce2600_gpio_direction_input(chip, gpio_pin); } return ce2600_set_multi_function(chip, gpio_pin, pin_mode == FUNCTIONAL_PIN ? 1 : 0); } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ int x86_gpio_out_bit(unsigned int gpio_pin, int value) { struct gpio_chip *chip; /*--- printk(KERN_ERR"%s(%d) set=%x\n", __func__, gpio_pin, value); ---*/ chip = intelce_get_gpio_chip(&gpio_pin); if(chip == NULL) { printk(KERN_ERR"%s(%d) failed\n", __func__, gpio_pin); return -1; } ce2600_gpio_set(chip, gpio_pin, value); return 0; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ int x86_gpio_in_bit(unsigned int gpio_pin) { struct gpio_chip *chip = intelce_get_gpio_chip(&gpio_pin); if(chip == NULL) { printk(KERN_ERR"%s(%d) failed\n", __func__, gpio_pin); return -1; } return ce2600_gpio_input(chip, gpio_pin); } /*--------------------------------------------------------------------------------*\ * liefere regbase fuer in * use bitbang-function instead \*--------------------------------------------------------------------------------*/ void __deprecated *x86_gpioin_regbase(unsigned int gpio_pin) { struct gpio_chip *chip = intelce_get_gpio_chip(&gpio_pin); struct intelce_gpio_chip *c; if(chip == NULL) { return NULL; } c = to_intelce_gpio_chip(chip); if(c == NULL) { return NULL; } return c->reg_base + CE2600_PUB_GPIO_INPUT; } EXPORT_SYMBOL(x86_gpioin_regbase); /**--------------------------------------------------------------------------------**\ \**--------------------------------------------------------------------------------**/ struct _gpio_bitbang_ctrl { void __iomem *read_base; void __iomem *setclr_base[2]; unsigned int bit_pos; }; /**--------------------------------------------------------------------------------**\ * only use x86_gpio_bitbang_in_bit() or x86_gpio_bitbang_out_bit() * you know what you do ! \**--------------------------------------------------------------------------------**/ void *x86_gpio_get_bitbang_handle(unsigned int gpio_pin) { struct _gpio_bitbang_ctrl *pfa_gpio; struct gpio_chip *chip = intelce_get_gpio_chip(&gpio_pin); struct intelce_gpio_chip *c; if(chip == NULL) { return NULL; } c = to_intelce_gpio_chip(chip); if(c == NULL) { return NULL; } pfa_gpio = kzalloc(sizeof(struct _gpio_bitbang_ctrl), GFP_ATOMIC); if(pfa_gpio == NULL) { return NULL; } pfa_gpio->read_base = c->reg_base + CE2600_PUB_GPIO_INPUT; pfa_gpio->setclr_base[0] = c->high_base + CE2600_PUB_GPIO_CLEAR; pfa_gpio->setclr_base[1] = c->high_base + CE2600_PUB_GPIO_SET; pfa_gpio->bit_pos = gpio_pin; return pfa_gpio; } EXPORT_SYMBOL(x86_gpio_get_bitbang_handle); /**--------------------------------------------------------------------------------**\ * free handle \**--------------------------------------------------------------------------------**/ void x86_gpio_put_bitbang_handle(void *handle) { if(handle) { kfree(handle); } } EXPORT_SYMBOL(x86_gpio_put_bitbang_handle); /**--------------------------------------------------------------------------------**\ \**--------------------------------------------------------------------------------**/ int x86_gpio_bitbang_in_bit(void *handle) { struct _gpio_bitbang_ctrl *pfa_gpio = (struct _gpio_bitbang_ctrl *)handle; return intelce_gpio_mmio_read32(pfa_gpio->read_base) & (1 << pfa_gpio->bit_pos) ? 1 : 0; } EXPORT_SYMBOL(x86_gpio_bitbang_in_bit); /**--------------------------------------------------------------------------------**\ \**--------------------------------------------------------------------------------**/ void x86_gpio_bitbang_out_bit(void *handle, unsigned int set) { struct _gpio_bitbang_ctrl *pfa_gpio = (struct _gpio_bitbang_ctrl *)handle; intelce_gpio_mmio_write32(1 << pfa_gpio->bit_pos, pfa_gpio->setclr_base[set ? 1 : 0]); } EXPORT_SYMBOL(x86_gpio_bitbang_out_bit); #ifdef CONFIG_PROC_FS /*--------------------------------------------------------------------------------*\ \*--------------------------------------------------------------------------------*/ static int proc_avm_gpio_read(char *page, char **start, off_t off, int count, int *eof, void *data) { return 0; } /*--------------------------------------------------------------------------------*\ \*--------------------------------------------------------------------------------*/ static int proc_avm_gpio_write(struct file *filp, const char __user *write_buffer, unsigned long write_length, void *data) { char Buffer[128], *p; int ret = 0; unsigned int gpio, val; static struct _cmd_gpio { char *cmd; unsigned int len; enum { dir, set, func, list } cmd_tag; #define SET_CMD(param) { cmd: #param, len: sizeof(#param) -1, cmd_tag: param } } *pcmd_gpio, cmd_gpio[] = { SET_CMD(dir), SET_CMD(set), SET_CMD(func), SET_CMD(list), { cmd: NULL } }; if(write_length >= sizeof(Buffer)) { write_length = sizeof(Buffer) - 1; } if(copy_from_user(Buffer, write_buffer, write_length)) { return -EFAULT; } Buffer[write_length] = '\0'; pcmd_gpio= cmd_gpio; while(pcmd_gpio->cmd) { if((p = strstr(Buffer, pcmd_gpio->cmd))) { p += pcmd_gpio->len; sscanf(p, "%d %d", &gpio, &val); switch(pcmd_gpio->cmd_tag) { case dir: printk(KERN_DEBUG "gpio_pin=%d, pin_direction=%x(%s)\n",gpio, val, val == GPIO_OUTPUT_PIN ? "out" : "in"); ret = x86_gpio_ctrl(gpio, GPIO_PIN, val); break; case set: printk(KERN_DEBUG "gpio_pin=%d, set=%x\n",gpio, val); ret = x86_gpio_out_bit(gpio, val); break; case func: { int gpio_per_bank = gpio; struct gpio_chip *chip = intelce_get_gpio_chip(&gpio_per_bank); if(chip == NULL) { ret = -1; break; } printk(KERN_DEBUG "gpio_pin=%d, func=%x\n",gpio, val); ret = ce2600_set_multi_function(chip, gpio_per_bank, val); break; } case list: break; } if(ret) { printk(KERN_ERR"failed ret=%d\n", ret); } } pcmd_gpio++; } return write_length; } /*--------------------------------------------------------------------------------*\ \*--------------------------------------------------------------------------------*/ static int __init proc_avm_gpio_init(void) { struct proc_dir_entry *res; res = create_proc_entry("avm/gpio", S_IWUSR | S_IRUGO, NULL); if (!res) return -ENOMEM; res->read_proc = proc_avm_gpio_read; res->write_proc = proc_avm_gpio_write; return 0; } __initcall(proc_avm_gpio_init); #endif /* CONFIG_PROC_FS */ EXPORT_SYMBOL(x86_gpio_ctrl); EXPORT_SYMBOL(x86_gpio_out_bit); EXPORT_SYMBOL(x86_gpio_in_bit); extern ssize_t intelce_get_arm_memsize(void); struct resource *puma6_get_arm_ram(void) { static struct resource *arm_ram = NULL; static int init_done = 0; ssize_t memsize; if(init_done == 0){ memsize = intelce_get_arm_memsize(); if(memsize > 0){ // pr_info("[%s] memsize: 0x%08x\n", __func__, memsize); arm_ram = request_mem_region((resource_size_t) 0x08000000, memsize, "ARM-RAM"); init_done = 1; } } return arm_ram; } EXPORT_SYMBOL(puma6_get_arm_ram);