Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1/*
  2 *  Loongson-2F/3A/3B GPIO Support
  3 *
  4 *  Copyright (c) 2008 Richard Liu,  STMicroelectronics	 <richard.liu@st.com>
  5 *  Copyright (c) 2008-2010 Arnaud Patard <apatard@mandriva.com>
  6 *  Copyright (c) 2013 Hongbing Hu <huhb@lemote.com>
  7 *  Copyright (c) 2014 Huacai Chen <chenhc@lemote.com>
  8 *
  9 *  This program is free software; you can redistribute it and/or modify
 10 *  it under the terms of the GNU General Public License as published by
 11 *  the Free Software Foundation; either version 2 of the License, or
 12 *  (at your option) any later version.
 13 */
 14
 15#include <linux/kernel.h>
 16#include <linux/init.h>
 17#include <linux/module.h>
 18#include <linux/spinlock.h>
 19#include <linux/err.h>
 20#include <asm/types.h>
 21#include <loongson.h>
 22#include <linux/gpio.h>
 23
 24#define STLS2F_N_GPIO		4
 25#define STLS3A_N_GPIO		16
 26
 27#ifdef CONFIG_CPU_LOONGSON3
 28#define LOONGSON_N_GPIO	STLS3A_N_GPIO
 29#else
 30#define LOONGSON_N_GPIO	STLS2F_N_GPIO
 31#endif
 32
 33#define LOONGSON_GPIO_IN_OFFSET	16
 34
 35static DEFINE_SPINLOCK(gpio_lock);
 36
 37static int loongson_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
 38{
 39	u32 temp;
 40	u32 mask;
 41
 42	spin_lock(&gpio_lock);
 43	mask = 1 << gpio;
 44	temp = LOONGSON_GPIOIE;
 45	temp |= mask;
 46	LOONGSON_GPIOIE = temp;
 47	spin_unlock(&gpio_lock);
 48
 49	return 0;
 50}
 51
 52static int loongson_gpio_direction_output(struct gpio_chip *chip,
 53		unsigned gpio, int level)
 54{
 55	u32 temp;
 56	u32 mask;
 57
 58	gpio_set_value(gpio, level);
 59	spin_lock(&gpio_lock);
 60	mask = 1 << gpio;
 61	temp = LOONGSON_GPIOIE;
 62	temp &= (~mask);
 63	LOONGSON_GPIOIE = temp;
 64	spin_unlock(&gpio_lock);
 65
 66	return 0;
 67}
 68
 69static int loongson_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
 70{
 71	u32 val;
 72	u32 mask;
 73
 74	mask = 1 << (gpio + LOONGSON_GPIO_IN_OFFSET);
 75	spin_lock(&gpio_lock);
 76	val = LOONGSON_GPIODATA;
 77	spin_unlock(&gpio_lock);
 78
 79	return (val & mask) != 0;
 80}
 81
 82static void loongson_gpio_set_value(struct gpio_chip *chip,
 83		unsigned gpio, int value)
 84{
 85	u32 val;
 86	u32 mask;
 87
 88	mask = 1 << gpio;
 89
 90	spin_lock(&gpio_lock);
 91	val = LOONGSON_GPIODATA;
 92	if (value)
 93		val |= mask;
 94	else
 95		val &= (~mask);
 96	LOONGSON_GPIODATA = val;
 97	spin_unlock(&gpio_lock);
 98}
 99
100static struct gpio_chip loongson_chip = {
101	.label                  = "Loongson-gpio-chip",
102	.direction_input        = loongson_gpio_direction_input,
103	.get                    = loongson_gpio_get_value,
104	.direction_output       = loongson_gpio_direction_output,
105	.set                    = loongson_gpio_set_value,
106	.base			= 0,
107	.ngpio                  = LOONGSON_N_GPIO,
108	.can_sleep		= false,
109};
110
111static int __init loongson_gpio_setup(void)
112{
113	return gpiochip_add_data(&loongson_chip, NULL);
114}
115postcore_initcall(loongson_gpio_setup);