aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAndres Salomon <dilinger@queued.net>2011-01-12 20:00:11 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-13 11:03:13 -0500
commit7637c9259f7b6dd841471ccf1120d484b7364f99 (patch)
tree1284edad0917aafa6b9fab7e2f98f460b671d2dc /drivers
parent1b912c1bca5c162e611384fe7d39c916e081701a (diff)
drivers/staging/olpc_dcon: convert to new cs5535 gpio API
Drop the old geode_gpio crud, as well as the raw outl() calls; instead, use the Linux GPIO API where possible, and the cs5535_gpio API in other places. Note that we don't actually clean up the driver properly yet (once loaded, it always remains loaded). That'll come later.. This patch is necessary for building the driver. Signed-off-by: Andres Salomon <dilinger@queued.net> Cc: Greg KH <greg@kroah.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/olpc_dcon/TODO1
-rw-r--r--drivers/staging/olpc_dcon/olpc_dcon.c3
-rw-r--r--drivers/staging/olpc_dcon/olpc_dcon.h20
-rw-r--r--drivers/staging/olpc_dcon/olpc_dcon_xo_1.c168
-rw-r--r--drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c4
5 files changed, 103 insertions, 93 deletions
diff --git a/drivers/staging/olpc_dcon/TODO b/drivers/staging/olpc_dcon/TODO
index ac2d3d023715..35f9cda7be11 100644
--- a/drivers/staging/olpc_dcon/TODO
+++ b/drivers/staging/olpc_dcon/TODO
@@ -1,6 +1,5 @@
1TODO: 1TODO:
2 - checkpatch.pl cleanups 2 - checkpatch.pl cleanups
3 - port geode gpio calls to newer cs5535 API
4 - see if vx855 gpio API can be made similar enough to cs5535 so we can 3 - see if vx855 gpio API can be made similar enough to cs5535 so we can
5 share more code 4 share more code
6 - allow simultaneous XO-1 and XO-1.5 support 5 - allow simultaneous XO-1 and XO-1.5 support
diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c
index 4ca45ec7fd84..da040c12fbf9 100644
--- a/drivers/staging/olpc_dcon/olpc_dcon.c
+++ b/drivers/staging/olpc_dcon/olpc_dcon.c
@@ -27,7 +27,6 @@
27#include <asm/uaccess.h> 27#include <asm/uaccess.h>
28#include <linux/ctype.h> 28#include <linux/ctype.h>
29#include <linux/reboot.h> 29#include <linux/reboot.h>
30#include <linux/gpio.h>
31#include <asm/tsc.h> 30#include <asm/tsc.h>
32#include <asm/olpc.h> 31#include <asm/olpc.h>
33 32
@@ -49,7 +48,7 @@ struct dcon_platform_data {
49 int (*init)(void); 48 int (*init)(void);
50 void (*bus_stabilize_wiggle)(void); 49 void (*bus_stabilize_wiggle)(void);
51 void (*set_dconload)(int); 50 void (*set_dconload)(int);
52 int (*read_status)(void); 51 u8 (*read_status)(void);
53}; 52};
54 53
55static struct dcon_platform_data *pdata; 54static struct dcon_platform_data *pdata;
diff --git a/drivers/staging/olpc_dcon/olpc_dcon.h b/drivers/staging/olpc_dcon/olpc_dcon.h
index 6453ca4ba0ee..e566d213da2a 100644
--- a/drivers/staging/olpc_dcon/olpc_dcon.h
+++ b/drivers/staging/olpc_dcon/olpc_dcon.h
@@ -29,26 +29,6 @@
29#define DCON_REG_SCAN_INT 9 29#define DCON_REG_SCAN_INT 9
30#define DCON_REG_BRIGHT 10 30#define DCON_REG_BRIGHT 10
31 31
32/* GPIO registers (CS5536) */
33
34#define MSR_LBAR_GPIO 0x5140000C
35
36#define GPIOx_OUT_VAL 0x00
37#define GPIOx_OUT_EN 0x04
38#define GPIOx_IN_EN 0x20
39#define GPIOx_INV_EN 0x24
40#define GPIOx_IN_FLTR_EN 0x28
41#define GPIOx_EVNTCNT_EN 0x2C
42#define GPIOx_READ_BACK 0x30
43#define GPIOx_EVNT_EN 0x38
44#define GPIOx_NEGEDGE_EN 0x44
45#define GPIOx_NEGEDGE_STS 0x4C
46#define GPIO_FLT7_AMNT 0xD8
47#define GPIO_MAP_X 0xE0
48#define GPIO_MAP_Y 0xE4
49#define GPIO_FE7_SEL 0xF7
50
51
52/* Status values */ 32/* Status values */
53 33
54#define DCONSTAT_SCANINT 0 34#define DCONSTAT_SCANINT 0
diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c
index 779fb7d7b30c..043198dc6ff7 100644
--- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c
+++ b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c
@@ -10,54 +10,70 @@
10 * modify it under the terms of version 2 of the GNU General Public 10 * modify it under the terms of version 2 of the GNU General Public
11 * License as published by the Free Software Foundation. 11 * License as published by the Free Software Foundation.
12 */ 12 */
13 13#include <linux/cs5535.h>
14#include <linux/gpio.h>
14#include <asm/olpc.h> 15#include <asm/olpc.h>
15 16
16#include "olpc_dcon.h" 17#include "olpc_dcon.h"
17 18
18/* Base address of the GPIO registers */
19static unsigned long gpio_base;
20
21/*
22 * List of GPIOs that we care about:
23 * (in) GPIO12 -- DCONBLANK
24 * (in) GPIO[56] -- DCONSTAT[01]
25 * (out) GPIO11 -- DCONLOAD
26 */
27
28#define IN_GPIOS ((1<<5) | (1<<6) | (1<<7) | (1<<12))
29#define OUT_GPIOS (1<<11)
30
31static int dcon_init_xo_1(void) 19static int dcon_init_xo_1(void)
32{ 20{
33 unsigned long lo, hi;
34 unsigned char lob; 21 unsigned char lob;
35 22
36 rdmsr(MSR_LBAR_GPIO, lo, hi); 23 if (gpio_request(OLPC_GPIO_DCON_STAT0, "OLPC-DCON")) {
37 24 printk(KERN_ERR "olpc-dcon: failed to request STAT0 GPIO\n");
38 /* Check the mask and whether GPIO is enabled (sanity check) */ 25 return -EIO;
39 if (hi != 0x0000f001) { 26 }
40 printk(KERN_ERR "GPIO not enabled -- cannot use DCON\n"); 27 if (gpio_request(OLPC_GPIO_DCON_STAT1, "OLPC-DCON")) {
41 return -ENODEV; 28 printk(KERN_ERR "olpc-dcon: failed to request STAT1 GPIO\n");
29 goto err_gp_stat1;
30 }
31 if (gpio_request(OLPC_GPIO_DCON_IRQ, "OLPC-DCON")) {
32 printk(KERN_ERR "olpc-dcon: failed to request IRQ GPIO\n");
33 goto err_gp_irq;
34 }
35 if (gpio_request(OLPC_GPIO_DCON_LOAD, "OLPC-DCON")) {
36 printk(KERN_ERR "olpc-dcon: failed to request LOAD GPIO\n");
37 goto err_gp_load;
38 }
39 if (gpio_request(OLPC_GPIO_DCON_BLANK, "OLPC-DCON")) {
40 printk(KERN_ERR "olpc-dcon: failed to request BLANK GPIO\n");
41 goto err_gp_blank;
42 } 42 }
43
44 /* Mask off the IO base address */
45 gpio_base = lo & 0x0000ff00;
46 43
47 /* Turn off the event enable for GPIO7 just to be safe */ 44 /* Turn off the event enable for GPIO7 just to be safe */
48 outl(1 << (16+7), gpio_base + GPIOx_EVNT_EN); 45 cs5535_gpio_clear(OLPC_GPIO_DCON_IRQ, GPIO_EVENTS_ENABLE);
46
47 /*
48 * Determine the current state by reading the GPIO bit; earlier
49 * stages of the boot process have established the state.
50 *
51 * Note that we read GPIO_OUPUT_VAL rather than GPIO_READ_BACK here;
52 * this is because OFW will disable input for the pin and set a value..
53 * READ_BACK will only contain a valid value if input is enabled and
54 * then a value is set. So, future readings of the pin can use
55 * READ_BACK, but the first one cannot. Awesome, huh?
56 */
57 dcon_source = cs5535_gpio_isset(OLPC_GPIO_DCON_LOAD, GPIO_OUTPUT_VAL)
58 ? DCON_SOURCE_CPU
59 : DCON_SOURCE_DCON;
60 dcon_pending = dcon_source;
49 61
50 /* Set the directions for the GPIO pins */ 62 /* Set the directions for the GPIO pins */
51 outl(OUT_GPIOS | (IN_GPIOS << 16), gpio_base + GPIOx_OUT_EN); 63 gpio_direction_input(OLPC_GPIO_DCON_STAT0);
52 outl(IN_GPIOS | (OUT_GPIOS << 16), gpio_base + GPIOx_IN_EN); 64 gpio_direction_input(OLPC_GPIO_DCON_STAT1);
65 gpio_direction_input(OLPC_GPIO_DCON_IRQ);
66 gpio_direction_input(OLPC_GPIO_DCON_BLANK);
67 gpio_direction_output(OLPC_GPIO_DCON_LOAD,
68 dcon_source == DCON_SOURCE_CPU);
53 69
54 /* Set up the interrupt mappings */ 70 /* Set up the interrupt mappings */
55 71
56 /* Set the IRQ to pair 2 */ 72 /* Set the IRQ to pair 2 */
57 geode_gpio_event_irq(OLPC_GPIO_DCON_IRQ, 2); 73 cs5535_gpio_setup_event(OLPC_GPIO_DCON_IRQ, 2, 0);
58 74
59 /* Enable group 2 to trigger the DCON interrupt */ 75 /* Enable group 2 to trigger the DCON interrupt */
60 geode_gpio_set_irq(2, DCON_IRQ); 76 cs5535_gpio_set_irq(2, DCON_IRQ);
61 77
62 /* Select edge level for interrupt (in PIC) */ 78 /* Select edge level for interrupt (in PIC) */
63 lob = inb(0x4d0); 79 lob = inb(0x4d0);
@@ -65,52 +81,61 @@ static int dcon_init_xo_1(void)
65 outb(lob, 0x4d0); 81 outb(lob, 0x4d0);
66 82
67 /* Register the interupt handler */ 83 /* Register the interupt handler */
68 if (request_irq(DCON_IRQ, &dcon_interrupt, 0, "DCON", &dcon_driver)) 84 if (request_irq(DCON_IRQ, &dcon_interrupt, 0, "DCON", &dcon_driver)) {
69 return -EIO; 85 printk(KERN_ERR "olpc-dcon: failed to request DCON's irq\n");
86 goto err_req_irq;
87 }
70 88
71 /* Clear INV_EN for GPIO7 (DCONIRQ) */ 89 /* Clear INV_EN for GPIO7 (DCONIRQ) */
72 outl((1<<(16+7)), gpio_base + GPIOx_INV_EN); 90 cs5535_gpio_clear(OLPC_GPIO_DCON_IRQ, GPIO_INPUT_INVERT);
73 91
74 /* Enable filter for GPIO12 (DCONBLANK) */ 92 /* Enable filter for GPIO12 (DCONBLANK) */
75 outl(1<<(12), gpio_base + GPIOx_IN_FLTR_EN); 93 cs5535_gpio_set(OLPC_GPIO_DCON_BLANK, GPIO_INPUT_FILTER);
76 94
77 /* Disable filter for GPIO7 */ 95 /* Disable filter for GPIO7 */
78 outl(1<<(16+7), gpio_base + GPIOx_IN_FLTR_EN); 96 cs5535_gpio_clear(OLPC_GPIO_DCON_IRQ, GPIO_INPUT_FILTER);
79 97
80 /* Disable event counter for GPIO7 (DCONIRQ) and GPIO12 (DCONBLANK) */ 98 /* Disable event counter for GPIO7 (DCONIRQ) and GPIO12 (DCONBLANK) */
81 99 cs5535_gpio_clear(OLPC_GPIO_DCON_IRQ, GPIO_INPUT_EVENT_COUNT);
82 outl(1<<(16+7), gpio_base + GPIOx_EVNTCNT_EN); 100 cs5535_gpio_clear(OLPC_GPIO_DCON_BLANK, GPIO_INPUT_EVENT_COUNT);
83 outl(1<<(16+12), gpio_base + GPIOx_EVNTCNT_EN);
84 101
85 /* Add GPIO12 to the Filter Event Pair #7 */ 102 /* Add GPIO12 to the Filter Event Pair #7 */
86 outb(12, gpio_base + GPIO_FE7_SEL); 103 cs5535_gpio_set(OLPC_GPIO_DCON_BLANK, GPIO_FE7_SEL);
87 104
88 /* Turn off negative Edge Enable for GPIO12 */ 105 /* Turn off negative Edge Enable for GPIO12 */
89 outl(1<<(16+12), gpio_base + GPIOx_NEGEDGE_EN); 106 cs5535_gpio_clear(OLPC_GPIO_DCON_BLANK, GPIO_NEGATIVE_EDGE_EN);
90 107
91 /* Enable negative Edge Enable for GPIO7 */ 108 /* Enable negative Edge Enable for GPIO7 */
92 outl(1<<7, gpio_base + GPIOx_NEGEDGE_EN); 109 cs5535_gpio_set(OLPC_GPIO_DCON_IRQ, GPIO_NEGATIVE_EDGE_EN);
93 110
94 /* Zero the filter amount for Filter Event Pair #7 */ 111 /* Zero the filter amount for Filter Event Pair #7 */
95 outw(0, gpio_base + GPIO_FLT7_AMNT); 112 cs5535_gpio_set(0, GPIO_FLTR7_AMOUNT);
96 113
97 /* Clear the negative edge status for GPIO7 and GPIO12 */ 114 /* Clear the negative edge status for GPIO7 and GPIO12 */
98 outl((1<<7) | (1<<12), gpio_base+0x4c); 115 cs5535_gpio_set(OLPC_GPIO_DCON_IRQ, GPIO_NEGATIVE_EDGE_STS);
116 cs5535_gpio_set(OLPC_GPIO_DCON_BLANK, GPIO_NEGATIVE_EDGE_STS);
99 117
100 /* FIXME: Clear the posiitive status as well, just to be sure */ 118 /* FIXME: Clear the posiitive status as well, just to be sure */
101 outl((1<<7) | (1<<12), gpio_base+0x48); 119 cs5535_gpio_set(OLPC_GPIO_DCON_IRQ, GPIO_POSITIVE_EDGE_STS);
120 cs5535_gpio_set(OLPC_GPIO_DCON_BLANK, GPIO_POSITIVE_EDGE_STS);
102 121
103 /* Enable events for GPIO7 (DCONIRQ) and GPIO12 (DCONBLANK) */ 122 /* Enable events for GPIO7 (DCONIRQ) and GPIO12 (DCONBLANK) */
104 outl((1<<(7))|(1<<12), gpio_base + GPIOx_EVNT_EN); 123 cs5535_gpio_set(OLPC_GPIO_DCON_IRQ, GPIO_EVENTS_ENABLE);
105 124 cs5535_gpio_set(OLPC_GPIO_DCON_BLANK, GPIO_EVENTS_ENABLE);
106 /* Determine the current state by reading the GPIO bit */
107 /* Earlier stages of the boot process have established the state */
108 dcon_source = inl(gpio_base + GPIOx_OUT_VAL) & (1<<11)
109 ? DCON_SOURCE_CPU
110 : DCON_SOURCE_DCON;
111 dcon_pending = dcon_source;
112 125
113 return 0; 126 return 0;
127
128err_req_irq:
129 gpio_free(OLPC_GPIO_DCON_BLANK);
130err_gp_blank:
131 gpio_free(OLPC_GPIO_DCON_LOAD);
132err_gp_load:
133 gpio_free(OLPC_GPIO_DCON_IRQ);
134err_gp_irq:
135 gpio_free(OLPC_GPIO_DCON_STAT1);
136err_gp_stat1:
137 gpio_free(OLPC_GPIO_DCON_STAT0);
138 return -EIO;
114} 139}
115 140
116static void dcon_wiggle_xo_1(void) 141static void dcon_wiggle_xo_1(void)
@@ -128,37 +153,44 @@ static void dcon_wiggle_xo_1(void)
128 * simultaneously set AUX1 IN/OUT to GPIO14; ditto for SMB_DATA and 153 * simultaneously set AUX1 IN/OUT to GPIO14; ditto for SMB_DATA and
129 * GPIO15. 154 * GPIO15.
130 */ 155 */
131 geode_gpio_set(OLPC_GPIO_SMB_CLK|OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_VAL); 156 cs5535_gpio_set(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_VAL);
132 geode_gpio_set(OLPC_GPIO_SMB_CLK|OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_ENABLE); 157 cs5535_gpio_set(OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_VAL);
133 geode_gpio_clear(OLPC_GPIO_SMB_CLK|OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_AUX1); 158 cs5535_gpio_set(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_ENABLE);
134 geode_gpio_clear(OLPC_GPIO_SMB_CLK|OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_AUX2); 159 cs5535_gpio_set(OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_ENABLE);
135 geode_gpio_clear(OLPC_GPIO_SMB_CLK|OLPC_GPIO_SMB_DATA, GPIO_INPUT_AUX1); 160 cs5535_gpio_clear(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_AUX1);
161 cs5535_gpio_clear(OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_AUX1);
162 cs5535_gpio_clear(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_AUX2);
163 cs5535_gpio_clear(OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_AUX2);
164 cs5535_gpio_clear(OLPC_GPIO_SMB_CLK, GPIO_INPUT_AUX1);
165 cs5535_gpio_clear(OLPC_GPIO_SMB_DATA, GPIO_INPUT_AUX1);
136 166
137 for (x = 0; x < 16; x++) { 167 for (x = 0; x < 16; x++) {
138 udelay(5); 168 udelay(5);
139 geode_gpio_clear(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_VAL); 169 cs5535_gpio_clear(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_VAL);
140 udelay(5); 170 udelay(5);
141 geode_gpio_set(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_VAL); 171 cs5535_gpio_set(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_VAL);
142 } 172 }
143 udelay(5); 173 udelay(5);
144 geode_gpio_set(OLPC_GPIO_SMB_CLK|OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_AUX1); 174 cs5535_gpio_set(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_AUX1);
145 geode_gpio_set(OLPC_GPIO_SMB_CLK|OLPC_GPIO_SMB_DATA, GPIO_INPUT_AUX1); 175 cs5535_gpio_set(OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_AUX1);
176 cs5535_gpio_set(OLPC_GPIO_SMB_CLK, GPIO_INPUT_AUX1);
177 cs5535_gpio_set(OLPC_GPIO_SMB_DATA, GPIO_INPUT_AUX1);
146} 178}
147 179
148static void dcon_set_dconload_1(int val) 180static void dcon_set_dconload_1(int val)
149{ 181{
150 if (val) 182 gpio_set_value(OLPC_GPIO_DCON_LOAD, val);
151 outl(1<<11, gpio_base + GPIOx_OUT_VAL);
152 else
153 outl(1<<(11 + 16), gpio_base + GPIOx_OUT_VAL);
154} 183}
155 184
156static int dcon_read_status_xo_1(void) 185static u8 dcon_read_status_xo_1(void)
157{ 186{
158 int status = inl(gpio_base + GPIOx_READ_BACK) >> 5; 187 u8 status;
159 188
189 status = gpio_get_value(OLPC_GPIO_DCON_STAT0);
190 status |= gpio_get_value(OLPC_GPIO_DCON_STAT1) << 1;
191
160 /* Clear the negative edge status for GPIO7 */ 192 /* Clear the negative edge status for GPIO7 */
161 outl(1 << 7, gpio_base + GPIOx_NEGEDGE_STS); 193 cs5535_gpio_set(OLPC_GPIO_DCON_IRQ, GPIO_NEGATIVE_EDGE_STS);
162 194
163 return status; 195 return status;
164} 196}
diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c
index cca6a235ef96..4f56098bb366 100644
--- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c
+++ b/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c
@@ -195,9 +195,9 @@ static void dcon_set_dconload_xo_1_5(int val)
195 } 195 }
196} 196}
197 197
198static int dcon_read_status_xo_1_5(void) 198static u8 dcon_read_status_xo_1_5(void)
199{ 199{
200 int status; 200 u8 status;
201 201
202 if (!dcon_was_irq()) 202 if (!dcon_was_irq())
203 return -1; 203 return -1;