embox

Форк
0
/
omap3_gpio.c 
157 строк · 4.0 Кб
1
/**
2
 * @file
3
 * @brief OMAP3 GPIO driver
4
 *
5
 * @date 1.11.13
6
 * @author Alexander Kalmuk
7
 */
8

9
#include <assert.h>
10
#include <string.h>
11
#include <stdio.h>
12
#include <embox/unit.h>
13
#include <hal/reg.h>
14
#include <kernel/printk.h>
15
#include <drivers/pins.h>
16
#include <drivers/gpio/gpio_driver.h>
17
#include "omap3_gpio.h"
18

19
#define GPIO_CHIP_ID OPTION_GET(NUMBER,gpio_chip_id)
20

21
EMBOX_UNIT_INIT(gpio_init);
22

23
static struct gpio_chip omap3_gpio_chip;
24

25
static pin_mask_t gpio_get_pin_changed(unsigned char port) {
26
	return (int) gpio_reg_read(GPIO_BASE_ADDRESS(port + 1),
27
		GPIO_IRQSTATUS1);
28
}
29

30
static int omap3_gpio_setup_mode(unsigned char port, gpio_mask_t mask,
31
		int mode) {
32
	uint32_t l;
33
	uint32_t gpio_base = GPIO_BASE_ADDRESS(port + 1);
34

35
	/* check if mode is incorrect */
36
	if (((mode & GPIO_MODE_OUT_SECTION) && (mode & GPIO_MODE_IN_SECTION)) ||
37
		((mode & GPIO_MODE_IN_INT_EN) && (mode & GPIO_MODE_IN_INT_DIS))) {
38
		return -1;
39
	}
40

41
	if (mode & GPIO_MODE_IN) {
42
		gpio_reg_write(gpio_base, GPIO_OE, mask);
43
	} else if (mode & GPIO_MODE_OUT) {
44
		l = gpio_reg_read(gpio_base, GPIO_OE);
45
		gpio_reg_write(gpio_base, GPIO_OE, l & ~mask);
46
	}
47

48
	/* interrupt disable */
49
	if (mode & GPIO_MODE_IN_INT_DIS) {
50
		/* clear front and level detect register, if you need */
51
		if (mode & GPIO_MODE_INT_MODE_RISING) {
52
			l = gpio_reg_read(gpio_base, GPIO_RISINGDETECT);
53
			gpio_reg_write(gpio_base, GPIO_RISINGDETECT, l & ~mask);
54
		}
55

56
		if (mode & GPIO_MODE_INT_MODE_FALLING) {
57
			l = gpio_reg_read(gpio_base, GPIO_FALLINGDETECT);
58
			gpio_reg_write(gpio_base, GPIO_FALLINGDETECT, l & ~mask);
59
		}
60

61
		if (mode & GPIO_MODE_INT_MODE_LEVEL0) {
62
			l = gpio_reg_read(gpio_base, GPIO_LEVELDETECT0);
63
			gpio_reg_write(gpio_base, GPIO_LEVELDETECT0, l & ~mask);
64
		}
65

66
		if (mode & GPIO_MODE_INT_MODE_LEVEL1) {
67
			l = gpio_reg_read(gpio_base, GPIO_LEVELDETECT1);
68
			gpio_reg_write(gpio_base, GPIO_LEVELDETECT1, l & ~mask);
69
		}
70
		/* clear oe flags */
71
		l = gpio_reg_read(gpio_base, GPIO_IRQENABLE1);
72
		gpio_reg_write(gpio_base, GPIO_IRQENABLE1, l & ~mask);
73

74
		return 0;
75
	}
76

77
	/* set interrupt mode, if needed */
78
	if (mode & GPIO_MODE_INT_MODE_RISING) {
79
		gpio_reg_write(gpio_base, GPIO_RISINGDETECT, mask);
80
	}
81

82
	if (mode & GPIO_MODE_INT_MODE_FALLING) {
83
		gpio_reg_write(gpio_base, GPIO_FALLINGDETECT, mask);
84
	}
85

86
	if (mode & GPIO_MODE_INT_MODE_LEVEL0) {
87
		gpio_reg_write(gpio_base, GPIO_LEVELDETECT0, mask);
88
	}
89

90
	if (mode & GPIO_MODE_INT_MODE_LEVEL1) {
91
		gpio_reg_write(gpio_base, GPIO_LEVELDETECT1, mask);
92
	}
93

94
	/* enable interrupt */
95
	if (mode & GPIO_MODE_IN_INT_EN) {
96
		gpio_reg_write(gpio_base, GPIO_IRQENABLE1, mask);
97
	}
98

99
	return 0;
100
}
101

102
static void omap3_gpio_set(unsigned char port, gpio_mask_t mask, char level) {
103
	uint32_t l;
104
	uint32_t gpio_base = GPIO_BASE_ADDRESS(port + 1);
105

106
	assert((mask & ~((1 << 16) - 1)) == 0);
107

108
	if (level) {
109
		l = gpio_reg_read(gpio_base, GPIO_DATAOUT);
110
		gpio_reg_write(gpio_base, GPIO_DATAOUT, l | mask);
111
	} else {
112
		l = gpio_reg_read(gpio_base, GPIO_CLEARDATAOUT);
113
		gpio_reg_write(gpio_base, GPIO_CLEARDATAOUT, l | mask);
114
	}
115
}
116

117
gpio_mask_t omap3_gpio_get(unsigned char port, gpio_mask_t mask){
118
	uint32_t gpio_base = GPIO_BASE_ADDRESS(port + 1);
119
	return mask & (gpio_reg_read(gpio_base, GPIO_DATAIN));
120
}
121

122
irq_return_t irq_gpio_handler(unsigned int irq_nr, void *data) {
123
	int changed;
124
	unsigned char port = GPIO_NUM_BY_IRQ(irq_nr) - 1;
125
	uint32_t gpio_base = GPIO_BASE_ADDRESS(port + 1);
126

127
	changed = gpio_get_pin_changed(port);
128
	gpio_reg_write(gpio_base, GPIO_IRQSTATUS1, changed);
129
	gpio_reg_write(gpio_base, GPIO_IRQSTATUS2, changed);
130

131
	gpio_handle_irq(&omap3_gpio_chip, port, changed);
132

133
	return IRQ_HANDLED;
134
}
135

136
static struct gpio_chip omap3_gpio_chip = {
137
	.setup_mode = omap3_gpio_setup_mode,
138
	.get = omap3_gpio_get,
139
	.set = omap3_gpio_set,
140
	.nports = GPIO_MODULE_CNT
141
};
142

143
static int gpio_init(void) {
144
	int i, ret;
145
	char str[32];
146

147
	for (i = 0; i < GPIO_MODULE_CNT; i++) {
148
		sprintf(str,"OMAP_GPIO%d", i);
149

150
		if (0 != (ret = irq_attach(GPIO_IRQ(i + 1),
151
				irq_gpio_handler, 0, NULL, str))) {
152
			return ret;
153
		}
154
	}
155

156
	return gpio_register_chip(&omap3_gpio_chip, GPIO_CHIP_ID);
157
}
158

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.