diff options
author | Lorenzo Miori <memoryS60@gmail.com> | 2015-01-04 15:13:41 +0100 |
---|---|---|
committer | Gerrit Rockbox <gerrit@rockbox.org> | 2015-01-29 20:28:59 +0100 |
commit | f35d63bc216e59ba1eecfb138e23915521716128 (patch) | |
tree | 2c0566993b6a417850355dea8c3ed202ac44e2fd /firmware | |
parent | 6879dec6ece3c0797c5df16c9dd494b3dc3a1329 (diff) | |
download | rockbox-f35d63bc216e59ba1eecfb138e23915521716128.tar.gz rockbox-f35d63bc216e59ba1eecfb138e23915521716128.zip |
ypr0/ypr1: GPIO handling API refactoring
The GPIO APIs for ypr0 and ypr1 targets was messy, requiring a
direct communication via several ioctls calls.
Since it is planned to add support to other devices, more GPIO are
going to be used. For that reason the functions shall be clear and
easy to use.
Change-Id: Ia2304335e1fed1305cc2c4320bd4c097e13079be
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/target/hosted/samsungypr/gpio-ypr.c | 94 | ||||
-rw-r--r-- | firmware/target/hosted/samsungypr/gpio-ypr.h | 25 | ||||
-rw-r--r-- | firmware/target/hosted/samsungypr/ypr0/button-ypr0.c | 27 | ||||
-rw-r--r-- | firmware/target/hosted/samsungypr/ypr0/system-ypr0.c | 7 | ||||
-rw-r--r-- | firmware/target/hosted/samsungypr/ypr1/button-ypr1.c | 15 |
5 files changed, 139 insertions, 29 deletions
diff --git a/firmware/target/hosted/samsungypr/gpio-ypr.c b/firmware/target/hosted/samsungypr/gpio-ypr.c index e5abc4cdc9..d6a19da34f 100644 --- a/firmware/target/hosted/samsungypr/gpio-ypr.c +++ b/firmware/target/hosted/samsungypr/gpio-ypr.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * | 8 | * |
9 | * Module wrapper for GPIO, using kernel module of Samsung YP-R0/YP-R1 | 9 | * Module wrapper for GPIO, using kernel module of Samsung YP-R0/YP-R1 |
10 | * | 10 | * |
11 | * Copyright (c) 2011 Lorenzo Miori | 11 | * Copyright (c) 2011-2015 Lorenzo Miori |
12 | * | 12 | * |
13 | * This program is free software; you can redistribute it and/or | 13 | * This program is free software; you can redistribute it and/or |
14 | * modify it under the terms of the GNU General Public License | 14 | * modify it under the terms of the GNU General Public License |
@@ -23,16 +23,42 @@ | |||
23 | #include <stdio.h> | 23 | #include <stdio.h> |
24 | #include <unistd.h> | 24 | #include <unistd.h> |
25 | #include <fcntl.h> | 25 | #include <fcntl.h> |
26 | #include <gpio-ypr.h> /* includes common ioctl device definitions */ | ||
27 | #include <sys/ioctl.h> | 26 | #include <sys/ioctl.h> |
28 | 27 | ||
28 | #include "panic.h" | ||
29 | #include "gpio-ypr.h" /* includes common ioctl device definitions */ | ||
30 | |||
29 | static int gpio_dev = 0; | 31 | static int gpio_dev = 0; |
30 | 32 | ||
33 | #ifdef GPIO_DEBUG | ||
34 | // 3 banks of 32 pins | ||
35 | static const char *pin_use[3][32]; | ||
36 | |||
37 | void gpio_acquire(unsigned bank, unsigned pin, const char *name) | ||
38 | { | ||
39 | if(pin_use[bank][pin] != NULL && pin_use[bank][pin] != name) | ||
40 | panicf("acquire B%dP%02d for %s, was %s!", bank, pin, name, pin_use[bank][pin]); | ||
41 | pin_use[bank][pin] = name; | ||
42 | } | ||
43 | |||
44 | void gpio_release(unsigned bank, unsigned pin, const char *name) | ||
45 | { | ||
46 | if(pin_use[bank][pin] != NULL && pin_use[bank][pin] != name) | ||
47 | panicf("release B%dP%02d for %s: was %s!", bank, pin, name, pin_use[bank][pin]); | ||
48 | pin_use[bank][pin] = NULL; | ||
49 | } | ||
50 | |||
51 | const char *gpio_blame(unsigned bank, unsigned pin) | ||
52 | { | ||
53 | return pin_use[bank][pin]; | ||
54 | } | ||
55 | #endif | ||
56 | |||
31 | void gpio_init(void) | 57 | void gpio_init(void) |
32 | { | 58 | { |
33 | gpio_dev = open(GPIO_DEVICE, O_RDONLY); | 59 | gpio_dev = open(GPIO_DEVICE, O_RDONLY); |
34 | if (gpio_dev < 0) | 60 | if (gpio_dev < 0) |
35 | printf("GPIO device open error!"); | 61 | panicf("GPIO device open error!"); |
36 | } | 62 | } |
37 | 63 | ||
38 | void gpio_close(void) | 64 | void gpio_close(void) |
@@ -41,8 +67,68 @@ void gpio_close(void) | |||
41 | close(gpio_dev); | 67 | close(gpio_dev); |
42 | } | 68 | } |
43 | 69 | ||
44 | int gpio_control(int request, int num, int mode, int val) | 70 | static int gpio_control(int request, int num, int mode, int val) |
45 | { | 71 | { |
46 | struct gpio_info r = { .num = num, .mode = mode, .val = val, }; | 72 | struct gpio_info r = { .num = num, .mode = mode, .val = val, }; |
47 | return ioctl(gpio_dev, request, &r); | 73 | return ioctl(gpio_dev, request, &r); |
48 | } | 74 | } |
75 | |||
76 | void gpio_set_iomux(int pin, int iomux) | ||
77 | { | ||
78 | if (gpio_control(DEV_CTRL_GPIO_SET_MUX, pin, iomux, 0) != 0) | ||
79 | { | ||
80 | panicf("Unable to set iomux to pin %d", pin); | ||
81 | } | ||
82 | } | ||
83 | |||
84 | void gpio_free_iomux(int pin, int iomux) | ||
85 | { | ||
86 | if (gpio_control(DEV_CTRL_GPIO_UNSET_MUX, pin, iomux, 0) != 0) | ||
87 | { | ||
88 | panicf("Unable to free iomux to pin %d", pin); | ||
89 | } | ||
90 | } | ||
91 | |||
92 | void gpio_set_pad(int pin, int type) | ||
93 | { | ||
94 | if (gpio_control(DEV_CTRL_GPIO_SET_TYPE, pin, type, 0) != 0) | ||
95 | { | ||
96 | panicf("Unable to set pad to pin %d", pin); | ||
97 | } | ||
98 | } | ||
99 | |||
100 | void gpio_direction_output(int pin) | ||
101 | { | ||
102 | if (gpio_control(DEV_CTRL_GPIO_SET_OUTPUT, pin, 0, 0) != 0) | ||
103 | { | ||
104 | panicf("Unable to set output direction to pin %d", pin); | ||
105 | } | ||
106 | } | ||
107 | |||
108 | void gpio_direction_input(int pin) | ||
109 | { | ||
110 | if (gpio_control(DEV_CTRL_GPIO_SET_INPUT, pin, 0, 0) != 0) | ||
111 | { | ||
112 | panicf("Unable to set input direction to pin %d", pin); | ||
113 | } | ||
114 | } | ||
115 | |||
116 | bool gpio_get(int pin) | ||
117 | { | ||
118 | return gpio_control(DEV_CTRL_GPIO_GET_VAL, pin, 0, 0); | ||
119 | } | ||
120 | |||
121 | void gpio_set(int pin, bool value) | ||
122 | { | ||
123 | int ret = -1; | ||
124 | |||
125 | if (value) | ||
126 | ret = gpio_control(DEV_CTRL_GPIO_SET_HIGH, pin, 0, 0); | ||
127 | else | ||
128 | ret = gpio_control(DEV_CTRL_GPIO_SET_LOW, pin, 0, 0); | ||
129 | |||
130 | if (ret != 0) | ||
131 | { | ||
132 | panicf("Unable to set input direction to pin %d", pin); | ||
133 | } | ||
134 | } | ||
diff --git a/firmware/target/hosted/samsungypr/gpio-ypr.h b/firmware/target/hosted/samsungypr/gpio-ypr.h index c10991e20c..c7214de6c0 100644 --- a/firmware/target/hosted/samsungypr/gpio-ypr.h +++ b/firmware/target/hosted/samsungypr/gpio-ypr.h | |||
@@ -24,6 +24,20 @@ | |||
24 | /* Specifies device name and ioctl magic */ | 24 | /* Specifies device name and ioctl magic */ |
25 | #include "gpio-target.h" | 25 | #include "gpio-target.h" |
26 | #include "sys/ioctl.h" | 26 | #include "sys/ioctl.h" |
27 | #include "stdbool.h" | ||
28 | |||
29 | // set to debug pinctrl use | ||
30 | #define GPIO_DEBUG | ||
31 | |||
32 | #ifdef GPIO_DEBUG | ||
33 | void imx233_pinctrl_acquire(unsigned bank, unsigned pin, const char *name); | ||
34 | void imx233_pinctrl_release(unsigned bank, unsigned pin, const char *name); | ||
35 | const char *imx233_pinctrl_blame(unsigned bank, unsigned pin); | ||
36 | #else | ||
37 | #define imx233_pinctrl_acquire(...) | ||
38 | #define imx233_pinctrl_release(...) | ||
39 | #define imx233_pinctrl_get_pin_use(...) NULL | ||
40 | #endif | ||
27 | 41 | ||
28 | struct gpio_info { | 42 | struct gpio_info { |
29 | int num; | 43 | int num; |
@@ -193,9 +207,16 @@ enum | |||
193 | PAD_CTL_DRV_VOT_HIGH = 0x1 << 13, | 207 | PAD_CTL_DRV_VOT_HIGH = 0x1 << 13, |
194 | }; | 208 | }; |
195 | 209 | ||
210 | /* Driver-related functions */ | ||
196 | void gpio_init(void); | 211 | void gpio_init(void); |
197 | void gpio_close(void); | 212 | void gpio_close(void); |
198 | int gpio_control_struct(int request, struct gpio_info pin); | ||
199 | int gpio_control(int request, int num, int mode, int val); | ||
200 | 213 | ||
214 | /* Exported API */ | ||
215 | void gpio_set_iomux(int pin, int iomux); | ||
216 | void gpio_free_iomux(int pin, int iomux); | ||
217 | void gpio_set_pad(int pin, int type); | ||
218 | void gpio_direction_output(int pin); | ||
219 | void gpio_direction_input(int pin); | ||
220 | bool gpio_get(int pin); | ||
221 | void gpio_set(int pin, bool value); | ||
201 | #endif | 222 | #endif |
diff --git a/firmware/target/hosted/samsungypr/ypr0/button-ypr0.c b/firmware/target/hosted/samsungypr/ypr0/button-ypr0.c index 08aacd18c6..860ad50cae 100644 --- a/firmware/target/hosted/samsungypr/ypr0/button-ypr0.c +++ b/firmware/target/hosted/samsungypr/ypr0/button-ypr0.c | |||
@@ -31,31 +31,31 @@ int button_read_device(void) | |||
31 | int key = BUTTON_NONE; | 31 | int key = BUTTON_NONE; |
32 | 32 | ||
33 | /* Check for all the keys */ | 33 | /* Check for all the keys */ |
34 | if (!gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_USER_KEY, 0, 0)) { | 34 | if (!gpio_get(GPIO_USER_KEY)) { |
35 | key |= BUTTON_USER; | 35 | key |= BUTTON_USER; |
36 | } | 36 | } |
37 | if (!gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_CENTRAL_KEY, 0, 0)) { | 37 | if (!gpio_get(GPIO_CENTRAL_KEY)) { |
38 | key |= BUTTON_SELECT; | 38 | key |= BUTTON_SELECT; |
39 | } | 39 | } |
40 | if (!gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_UP_KEY, 0, 0)) { | 40 | if (!gpio_get(GPIO_UP_KEY)) { |
41 | key |= BUTTON_UP; | 41 | key |= BUTTON_UP; |
42 | } | 42 | } |
43 | if (!gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_DOWN_KEY, 0, 0)) { | 43 | if (!gpio_get(GPIO_DOWN_KEY)) { |
44 | key |= BUTTON_DOWN; | 44 | key |= BUTTON_DOWN; |
45 | } | 45 | } |
46 | if (!gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_LEFT_KEY, 0, 0)) { | 46 | if (!gpio_get(GPIO_LEFT_KEY)) { |
47 | key |= BUTTON_LEFT; | 47 | key |= BUTTON_LEFT; |
48 | } | 48 | } |
49 | if (!gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_RIGHT_KEY, 0, 0)) { | 49 | if (!gpio_get(GPIO_RIGHT_KEY)) { |
50 | key |= BUTTON_RIGHT; | 50 | key |= BUTTON_RIGHT; |
51 | } | 51 | } |
52 | if (!gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_MENU_KEY, 0, 0)) { | 52 | if (!gpio_get(GPIO_MENU_KEY)) { |
53 | key |= BUTTON_MENU; | 53 | key |= BUTTON_MENU; |
54 | } | 54 | } |
55 | if (!gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_BACK_KEY, 0, 0)) { | 55 | if (!gpio_get(GPIO_BACK_KEY)) { |
56 | key |= BUTTON_BACK; | 56 | key |= BUTTON_BACK; |
57 | } | 57 | } |
58 | if (gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_POWER_KEY, 0, 0)) { | 58 | if (gpio_get(GPIO_POWER_KEY)) { |
59 | key |= BUTTON_POWER; | 59 | key |= BUTTON_POWER; |
60 | } | 60 | } |
61 | 61 | ||
@@ -65,14 +65,15 @@ int button_read_device(void) | |||
65 | bool headphones_inserted(void) | 65 | bool headphones_inserted(void) |
66 | { | 66 | { |
67 | /* GPIO low - 0 - means headphones inserted */ | 67 | /* GPIO low - 0 - means headphones inserted */ |
68 | return !gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_HEADPHONE_SENSE, 0, 0); | 68 | return !gpio_get(GPIO_HEADPHONE_SENSE); |
69 | } | 69 | } |
70 | 70 | ||
71 | void button_init_device(void) | 71 | void button_init_device(void) |
72 | { | 72 | { |
73 | /* Setup GPIO pin for headphone sense, copied from OF */ | 73 | /* Setup GPIO pin for headphone sense, copied from OF */ |
74 | gpio_control(DEV_CTRL_GPIO_SET_MUX, GPIO_HEADPHONE_SENSE, CONFIG_SION, PAD_CTL_47K_PU); | 74 | gpio_set_iomux(GPIO_HEADPHONE_SENSE, CONFIG_GPIO); |
75 | gpio_control(DEV_CTRL_GPIO_SET_INPUT, GPIO_HEADPHONE_SENSE, CONFIG_SION, PAD_CTL_47K_PU); | 75 | gpio_set_pad(GPIO_HEADPHONE_SENSE, PAD_CTL_47K_PU); |
76 | gpio_direction_input(GPIO_HEADPHONE_SENSE); | ||
76 | 77 | ||
77 | /* No need to initialize any GPIO pin, since this is done loading the r0Btn module */ | 78 | /* No need to initialize any GPIO pin, since this is done loading the r0Btn module */ |
78 | } | 79 | } |
@@ -82,6 +83,6 @@ void button_init_device(void) | |||
82 | void button_close_device(void) | 83 | void button_close_device(void) |
83 | { | 84 | { |
84 | /* Don't know the precise meaning, but it's done as in the OF, so copied there */ | 85 | /* Don't know the precise meaning, but it's done as in the OF, so copied there */ |
85 | gpio_control(DEV_CTRL_GPIO_UNSET_MUX, GPIO_HEADPHONE_SENSE, CONFIG_SION, 0); | 86 | gpio_free_iomux(GPIO_HEADPHONE_SENSE, CONFIG_GPIO); |
86 | } | 87 | } |
87 | #endif /* BUTTON_DRIVER_CLOSE */ | 88 | #endif /* BUTTON_DRIVER_CLOSE */ |
diff --git a/firmware/target/hosted/samsungypr/ypr0/system-ypr0.c b/firmware/target/hosted/samsungypr/ypr0/system-ypr0.c index 9cc307073b..2544174252 100644 --- a/firmware/target/hosted/samsungypr/ypr0/system-ypr0.c +++ b/firmware/target/hosted/samsungypr/ypr0/system-ypr0.c | |||
@@ -88,7 +88,7 @@ bool hostfs_present(IF_MD_NONVOID(int drive)) | |||
88 | { | 88 | { |
89 | #ifdef HAVE_MULTIDRIVE | 89 | #ifdef HAVE_MULTIDRIVE |
90 | if (drive > 0) /* Active LOW */ | 90 | if (drive > 0) /* Active LOW */ |
91 | return (!gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_SD_SENSE, 0, 0)); | 91 | return (!gpio_get(GPIO_SD_SENSE)); |
92 | else | 92 | else |
93 | #endif | 93 | #endif |
94 | return true; /* internal: always present */ | 94 | return true; /* internal: always present */ |
@@ -229,8 +229,9 @@ static void NORETURN_ATTR sd_thread(void) | |||
229 | int hostfs_init(void) | 229 | int hostfs_init(void) |
230 | { | 230 | { |
231 | /* Setup GPIO pin for microSD sense, copied from OF */ | 231 | /* Setup GPIO pin for microSD sense, copied from OF */ |
232 | gpio_control(DEV_CTRL_GPIO_SET_MUX, GPIO_SD_SENSE, CONFIG_DEFAULT, 0); | 232 | gpio_set_iomux(GPIO_SD_SENSE, CONFIG_DEFAULT); |
233 | gpio_control(DEV_CTRL_GPIO_SET_INPUT, GPIO_SD_SENSE, CONFIG_DEFAULT, 0); | 233 | gpio_set_pad(GPIO_SD_SENSE, PAD_CTL_SRE_SLOW); |
234 | gpio_direction_input(GPIO_SD_SENSE); | ||
234 | #ifdef HAVE_MULTIDRIVE | 235 | #ifdef HAVE_MULTIDRIVE |
235 | if (storage_present(IF_MD(1))) | 236 | if (storage_present(IF_MD(1))) |
236 | mount_sd(); | 237 | mount_sd(); |
diff --git a/firmware/target/hosted/samsungypr/ypr1/button-ypr1.c b/firmware/target/hosted/samsungypr/ypr1/button-ypr1.c index d12b8486b6..26755716f4 100644 --- a/firmware/target/hosted/samsungypr/ypr1/button-ypr1.c +++ b/firmware/target/hosted/samsungypr/ypr1/button-ypr1.c | |||
@@ -45,13 +45,13 @@ int button_read_device(int *data) | |||
45 | struct mcs5000_raw_data touchpad_data; | 45 | struct mcs5000_raw_data touchpad_data; |
46 | 46 | ||
47 | /* Check for all the keys */ | 47 | /* Check for all the keys */ |
48 | if (!gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_VOL_UP_KEY, 0, 0)) { | 48 | if (!gpio_get(GPIO_VOL_UP_KEY)) { |
49 | key |= BUTTON_VOL_UP; | 49 | key |= BUTTON_VOL_UP; |
50 | } | 50 | } |
51 | if (!gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_VOL_DOWN_KEY, 0, 0)) { | 51 | if (!gpio_get(GPIO_VOL_DOWN_KEY)) { |
52 | key |= BUTTON_VOL_DOWN; | 52 | key |= BUTTON_VOL_DOWN; |
53 | } | 53 | } |
54 | if (gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_POWER_KEY, 0, 0)) { | 54 | if (gpio_get(GPIO_POWER_KEY)) { |
55 | key |= BUTTON_POWER; | 55 | key |= BUTTON_POWER; |
56 | } | 56 | } |
57 | 57 | ||
@@ -99,7 +99,7 @@ void touchscreen_enable_device(bool en) | |||
99 | bool headphones_inserted(void) | 99 | bool headphones_inserted(void) |
100 | { | 100 | { |
101 | /* GPIO low - 0 - means headphones inserted */ | 101 | /* GPIO low - 0 - means headphones inserted */ |
102 | return !gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_HEADPHONE_SENSE, 0, 0); | 102 | return !gpio_get(GPIO_HEADPHONE_SENSE); |
103 | } | 103 | } |
104 | 104 | ||
105 | void button_init_device(void) | 105 | void button_init_device(void) |
@@ -107,8 +107,9 @@ void button_init_device(void) | |||
107 | /* Setup GPIO pin for headphone sense, copied from OF | 107 | /* Setup GPIO pin for headphone sense, copied from OF |
108 | * Pins for the other buttons are already set up by OF button module | 108 | * Pins for the other buttons are already set up by OF button module |
109 | */ | 109 | */ |
110 | gpio_control(DEV_CTRL_GPIO_SET_MUX, GPIO_HEADPHONE_SENSE, 4, 0); | 110 | gpio_set_iomux(GPIO_HEADPHONE_SENSE, CONFIG_ALT4); |
111 | gpio_control(DEV_CTRL_GPIO_SET_INPUT, GPIO_HEADPHONE_SENSE, 4, 0); | 111 | gpio_set_pad(GPIO_HEADPHONE_SENSE, PAD_CTL_SRE_SLOW); |
112 | gpio_direction_input(GPIO_HEADPHONE_SENSE); | ||
112 | 113 | ||
113 | /* Turn on touchscreen */ | 114 | /* Turn on touchscreen */ |
114 | mcs5000_init(); | 115 | mcs5000_init(); |
@@ -120,7 +121,7 @@ void button_init_device(void) | |||
120 | /* I'm not sure it's called at shutdown...give a check! */ | 121 | /* I'm not sure it's called at shutdown...give a check! */ |
121 | void button_close_device(void) | 122 | void button_close_device(void) |
122 | { | 123 | { |
123 | gpio_control(DEV_CTRL_GPIO_UNSET_MUX, GPIO_HEADPHONE_SENSE, 0, 0); | 124 | gpio_free_iomux(GPIO_HEADPHONE_SENSE, CONFIG_ALT4); |
124 | 125 | ||
125 | /* Turn off touchscreen device */ | 126 | /* Turn off touchscreen device */ |
126 | mcs5000_shutdown(); | 127 | mcs5000_shutdown(); |