int gpio_kernel_api(unsigned int cmd, unsigned int mask, unsigned int val) { if (gpio_init_flag != 1) { if (gpio_init() != 0) return -EFAULT; } switch (cmd) { case 0: sb_gpioout(gpio_sbh, mask, val, GPIO_HI_PRIORITY); break; case 1: sb_gpioouten(gpio_sbh, mask, val, GPIO_HI_PRIORITY); break; case 3: sb_gpioreserve(gpio_sbh, mask, GPIO_HI_PRIORITY); break; default: printk("Unknown gpio_kenerl_api command\n"); break; } return 0; }
static ssize_t gpio_read(struct file *file, char *buf, size_t count, loff_t *ppos) { u32 val; switch (MINOR(file->f_dentry->d_inode->i_rdev)) { case 0: val = sb_gpioin(gpio_sbh); break; case 1: val = sb_gpioout(gpio_sbh, 0, 0, GPIO_DRV_PRIORITY); break; case 2: val = sb_gpioouten(gpio_sbh, 0, 0, GPIO_DRV_PRIORITY); break; case 3: val = sb_gpiocontrol(gpio_sbh, 0, 0, GPIO_DRV_PRIORITY); break; default: return -ENODEV; } if (put_user(val, (u32 *) buf)) return -EFAULT; return sizeof(val); }
static ssize_t gpio_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { u32 val; if (get_user(val, (u32 *) buf)) return -EFAULT; switch (MINOR(file->f_dentry->d_inode->i_rdev)) { case 0: return -EACCES; case 1: sb_gpioout(gpio_sbh, ~0, val, GPIO_DRV_PRIORITY); break; case 2: sb_gpioouten(gpio_sbh, ~0, val, GPIO_DRV_PRIORITY); break; case 3: sb_gpiocontrol(gpio_sbh, ~0, val, GPIO_DRV_PRIORITY); break; default: return -ENODEV; } return sizeof(val); }
static int __init gpio_init(void) { int i; if (!(gpio_sbh = sb_kattach(SB_OSH))) return -ENODEV; sb_gpiosetcore(gpio_sbh); if ((gpio_major = devfs_register_chrdev(0, "gpio", &gpio_fops)) < 0) return gpio_major; gpio_dir = devfs_mk_dir(NULL, "gpio", NULL); for (i = 0; i < ARRAYSIZE(gpio_file); i++) { gpio_file[i].handle = devfs_register(gpio_dir, gpio_file[i].name, DEVFS_FL_DEFAULT, gpio_major, i, S_IFCHR | S_IRUGO | S_IWUGO, &gpio_fops, NULL); } gpio_init_flag = 1; if (iswrt350n) { // printk(KERN_EMERG "WRT350N GPIO Init\n"); /* For WRT350N USB LED control */ sb_gpioreserve(gpio_sbh, 0x400, GPIO_HI_PRIORITY); sb_gpioouten(gpio_sbh, 0x400, 0x400, GPIO_HI_PRIORITY); sb_gpioreserve(gpio_sbh, 0x800, GPIO_HI_PRIORITY); sb_gpioouten(gpio_sbh, 0x800, 0x800, GPIO_HI_PRIORITY); //if (nvram_match("disabled_5397", "1")) { // printk("5397 switch GPIO-Reset \n"); sb_gpioreserve(gpio_sbh, 0x4, GPIO_HI_PRIORITY); sb_gpioouten(gpio_sbh, 0x4, 0x4, GPIO_HI_PRIORITY); sb_gpioout(gpio_sbh, 0x4, 0x4, GPIO_HI_PRIORITY); //} USB_SET_LED(USB_DISCONNECT); //2005-02-24 by kanki for USB LED } return 0; }
/* Enable outputs with specified value to the chip */ static void adm_enout(__u8 pins, __u8 val) { /* Prepare GPIO output value */ sb_gpioout(sbh, pins, val); /* Enable GPIO outputs */ sb_gpioouten(sbh, pins, pins); udelay(EECK_EDGE_TIME); }
static int proc_reset(ctl_table *table, int write, struct file *filp, void *buffer, size_t *lenp) { if (reset_gpio) { sb_gpiocontrol(sbh,reset_gpio,reset_gpio,0); sb_gpioouten(sbh,reset_gpio,0,0); reset=!(sb_gpioin(sbh)&reset_gpio); if (reset_polarity) reset=!reset; } else { reset=0; } return proc_dointvec(table, write, filp, buffer, lenp); }
static bool nvram_reset(void *sbh) { chipcregs_t *cc; char *value; uint32 watchdog = 0, gpio; uint idx, msec; idx = sb_coreidx(sbh); /* Check if we were soft reset */ if ((cc = sb_setcore(sbh, SB_CC, 0))) { watchdog = R_REG(&cc->intstatus) & 0x80000000; sb_setcoreidx(sbh, idx); } if (watchdog) return FALSE; value = nvram_get("reset_gpio"); if (!value) return FALSE; gpio = (uint32) bcm_atoi(value); if (gpio > 7) return FALSE; /* Setup GPIO input */ sb_gpioouten(sbh, (1 << gpio), 0); /* GPIO reset is asserted low */ for (msec = 0; msec < 5000; msec++) { if (sb_gpioin(sbh) & (1 << gpio)) return FALSE; OSL_DELAY(1000); } return TRUE; }
static int gpio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct gpio_ioctl gpioioc; if (copy_from_user(&gpioioc, (struct gpio_ioctl *)arg, sizeof(struct gpio_ioctl))) return -EFAULT; switch(cmd) { case GPIO_IOC_RESERVE: gpioioc.val = sb_gpioreserve(gpio_sbh, gpioioc.mask, GPIO_APP_PRIORITY); break; case GPIO_IOC_RELEASE: /* * releasing the gpio doesn't change the current * value on the GPIO last write value * persists till some one overwrites it */ gpioioc.val = sb_gpiorelease(gpio_sbh, gpioioc.mask, GPIO_APP_PRIORITY); break; case GPIO_IOC_OUT: gpioioc.val = sb_gpioout(gpio_sbh, gpioioc.mask, gpioioc.val,GPIO_APP_PRIORITY); break; case GPIO_IOC_OUTEN: gpioioc.val = sb_gpioouten(gpio_sbh, gpioioc.mask, gpioioc.val, GPIO_APP_PRIORITY); break; case GPIO_IOC_IN: gpioioc.val = sb_gpioin(gpio_sbh); break; default: break; } if (copy_to_user((struct gpio_ioctl *)arg, &gpioioc , sizeof(struct gpio_ioctl))) return -EFAULT; return 0; }
static void set_gpio(uint32 mask, uint32 value) { sb_gpiocontrol(sbh,mask,0,0); sb_gpioouten(sbh,mask,mask,0); sb_gpioout(sbh,mask,value,0); }
/* Disable outputs to the chip */ static void adm_disout(__u8 pins) { /* Disable GPIO outputs */ sb_gpioouten(sbh, pins, 0); udelay(EECK_EDGE_TIME); }