Path: blob/master/arch/mips/loongson/common/gpio.c
10818 views
/*1* STLS2F GPIO Support2*3* Copyright (c) 2008 Richard Liu, STMicroelectronics <[email protected]>4* Copyright (c) 2008-2010 Arnaud Patard <[email protected]>5*6* This program is free software; you can redistribute it and/or modify7* it under the terms of the GNU General Public License as published by8* the Free Software Foundation; either version 2 of the License, or9* (at your option) any later version.10*/1112#include <linux/kernel.h>13#include <linux/init.h>14#include <linux/module.h>15#include <linux/spinlock.h>16#include <linux/err.h>17#include <asm/types.h>18#include <loongson.h>19#include <linux/gpio.h>2021#define STLS2F_N_GPIO 422#define STLS2F_GPIO_IN_OFFSET 162324static DEFINE_SPINLOCK(gpio_lock);2526int gpio_get_value(unsigned gpio)27{28u32 val;29u32 mask;3031if (gpio >= STLS2F_N_GPIO)32return __gpio_get_value(gpio);3334mask = 1 << (gpio + STLS2F_GPIO_IN_OFFSET);35spin_lock(&gpio_lock);36val = LOONGSON_GPIODATA;37spin_unlock(&gpio_lock);3839return ((val & mask) != 0);40}41EXPORT_SYMBOL(gpio_get_value);4243void gpio_set_value(unsigned gpio, int state)44{45u32 val;46u32 mask;4748if (gpio >= STLS2F_N_GPIO) {49__gpio_set_value(gpio, state);50return ;51}5253mask = 1 << gpio;5455spin_lock(&gpio_lock);56val = LOONGSON_GPIODATA;57if (state)58val |= mask;59else60val &= (~mask);61LOONGSON_GPIODATA = val;62spin_unlock(&gpio_lock);63}64EXPORT_SYMBOL(gpio_set_value);6566int gpio_cansleep(unsigned gpio)67{68if (gpio < STLS2F_N_GPIO)69return 0;70else71return __gpio_cansleep(gpio);72}73EXPORT_SYMBOL(gpio_cansleep);7475static int ls2f_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)76{77u32 temp;78u32 mask;7980if (gpio >= STLS2F_N_GPIO)81return -EINVAL;8283spin_lock(&gpio_lock);84mask = 1 << gpio;85temp = LOONGSON_GPIOIE;86temp |= mask;87LOONGSON_GPIOIE = temp;88spin_unlock(&gpio_lock);8990return 0;91}9293static int ls2f_gpio_direction_output(struct gpio_chip *chip,94unsigned gpio, int level)95{96u32 temp;97u32 mask;9899if (gpio >= STLS2F_N_GPIO)100return -EINVAL;101102gpio_set_value(gpio, level);103spin_lock(&gpio_lock);104mask = 1 << gpio;105temp = LOONGSON_GPIOIE;106temp &= (~mask);107LOONGSON_GPIOIE = temp;108spin_unlock(&gpio_lock);109110return 0;111}112113static int ls2f_gpio_get_value(struct gpio_chip *chip, unsigned gpio)114{115return gpio_get_value(gpio);116}117118static void ls2f_gpio_set_value(struct gpio_chip *chip,119unsigned gpio, int value)120{121gpio_set_value(gpio, value);122}123124static struct gpio_chip ls2f_chip = {125.label = "ls2f",126.direction_input = ls2f_gpio_direction_input,127.get = ls2f_gpio_get_value,128.direction_output = ls2f_gpio_direction_output,129.set = ls2f_gpio_set_value,130.base = 0,131.ngpio = STLS2F_N_GPIO,132};133134static int __init ls2f_gpio_setup(void)135{136return gpiochip_add(&ls2f_chip);137}138arch_initcall(ls2f_gpio_setup);139140141