aboutsummaryrefslogtreecommitdiff
path: root/drivers/mfd/glamo/glamo-gpio.c
blob: 45d0bf91268ea59810fa1c6dcb2f22e60262397b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/io.h>

#include <linux/glamo-gpio.h>

#include "glamo-core.h"
#include "glamo-regs.h"

void glamo_gpio_setpin(struct glamo_core *glamo, unsigned int pin,
		       unsigned int value)
{
	unsigned int reg = REG_OF_GPIO(pin);
	u_int16_t tmp;

	spin_lock(&glamo->lock);
	tmp = readw(glamo->base + reg);
	if (value)
		tmp |= OUTPUT_BIT(pin);
	else
		tmp &= ~OUTPUT_BIT(pin);
	writew(tmp, glamo->base + reg);
	spin_unlock(&glamo->lock);
}
EXPORT_SYMBOL(glamo_gpio_setpin);

int glamo_gpio_getpin(struct glamo_core *glamo, unsigned int pin)
{
	return readw(REG_OF_GPIO(pin)) & INPUT_BIT(pin) ? 1 : 0;
}
EXPORT_SYMBOL(glamo_gpio_getpin);

void glamo_gpio_cfgpin(struct glamo_core *glamo, unsigned int pinfunc)
{
	unsigned int reg = REG_OF_GPIO(pinfunc);
	u_int16_t tmp;

	spin_lock(&glamo->lock);
	tmp = readw(glamo->base + reg);

	if ((pinfunc & 0x00f0) == GLAMO_GPIO_F_FUNC) {
		/* pin is a function pin: clear gpio bit */
		tmp &= ~FUNC_BIT(pinfunc);
	} else {
		/* pin is gpio: set gpio bit */
		tmp |= FUNC_BIT(pinfunc);

		if (pinfunc & GLAMO_GPIO_F_IN) {
			/* gpio input: set bit to disable output mode */
			tmp |= GPIO_OUT_BIT(pinfunc);
		} else if (pinfunc & GLAMO_GPIO_F_OUT) {
			/* gpio output: clear bit to enable output mode */
			tmp &= ~GPIO_OUT_BIT(pinfunc);
		}
	}
	writew(tmp, glamo->base + reg);
	spin_unlock(&glamo->lock);
}
EXPORT_SYMBOL(glamo_gpio_cfgpin);