Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
olpc_dcon_xo_1.c
Go to the documentation of this file.
1 /*
2  * Mainly by David Woodhouse, somewhat modified by Jordan Crouse
3  *
4  * Copyright © 2006-2007 Red Hat, Inc.
5  * Copyright © 2006-2007 Advanced Micro Devices, Inc.
6  * Copyright © 2009 VIA Technology, Inc.
7  * Copyright (c) 2010 Andres Salomon <[email protected]>
8  *
9  * This program is free software. You can redistribute it and/or
10  * modify it under the terms of version 2 of the GNU General Public
11  * License as published by the Free Software Foundation.
12  */
13 
14 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15 
16 #include <linux/cs5535.h>
17 #include <linux/gpio.h>
18 #include <linux/delay.h>
19 #include <asm/olpc.h>
20 
21 #include "olpc_dcon.h"
22 
23 static int dcon_init_xo_1(struct dcon_priv *dcon)
24 {
25  unsigned char lob;
26 
27  if (gpio_request(OLPC_GPIO_DCON_STAT0, "OLPC-DCON")) {
28  pr_err("failed to request STAT0 GPIO\n");
29  return -EIO;
30  }
31  if (gpio_request(OLPC_GPIO_DCON_STAT1, "OLPC-DCON")) {
32  pr_err("failed to request STAT1 GPIO\n");
33  goto err_gp_stat1;
34  }
35  if (gpio_request(OLPC_GPIO_DCON_IRQ, "OLPC-DCON")) {
36  pr_err("failed to request IRQ GPIO\n");
37  goto err_gp_irq;
38  }
39  if (gpio_request(OLPC_GPIO_DCON_LOAD, "OLPC-DCON")) {
40  pr_err("failed to request LOAD GPIO\n");
41  goto err_gp_load;
42  }
43  if (gpio_request(OLPC_GPIO_DCON_BLANK, "OLPC-DCON")) {
44  pr_err("failed to request BLANK GPIO\n");
45  goto err_gp_blank;
46  }
47 
48  /* Turn off the event enable for GPIO7 just to be safe */
50 
51  /*
52  * Determine the current state by reading the GPIO bit; earlier
53  * stages of the boot process have established the state.
54  *
55  * Note that we read GPIO_OUPUT_VAL rather than GPIO_READ_BACK here;
56  * this is because OFW will disable input for the pin and set a value..
57  * READ_BACK will only contain a valid value if input is enabled and
58  * then a value is set. So, future readings of the pin can use
59  * READ_BACK, but the first one cannot. Awesome, huh?
60  */
64  dcon->pending_src = dcon->curr_src;
65 
66  /* Set the directions for the GPIO pins */
72  dcon->curr_src == DCON_SOURCE_CPU);
73 
74  /* Set up the interrupt mappings */
75 
76  /* Set the IRQ to pair 2 */
78 
79  /* Enable group 2 to trigger the DCON interrupt */
81 
82  /* Select edge level for interrupt (in PIC) */
83  lob = inb(0x4d0);
84  lob &= ~(1 << DCON_IRQ);
85  outb(lob, 0x4d0);
86 
87  /* Register the interrupt handler */
88  if (request_irq(DCON_IRQ, &dcon_interrupt, 0, "DCON", dcon)) {
89  pr_err("failed to request DCON's irq\n");
90  goto err_req_irq;
91  }
92 
93  /* Clear INV_EN for GPIO7 (DCONIRQ) */
95 
96  /* Enable filter for GPIO12 (DCONBLANK) */
98 
99  /* Disable filter for GPIO7 */
101 
102  /* Disable event counter for GPIO7 (DCONIRQ) and GPIO12 (DCONBLANK) */
105 
106  /* Add GPIO12 to the Filter Event Pair #7 */
108 
109  /* Turn off negative Edge Enable for GPIO12 */
111 
112  /* Enable negative Edge Enable for GPIO7 */
114 
115  /* Zero the filter amount for Filter Event Pair #7 */
117 
118  /* Clear the negative edge status for GPIO7 and GPIO12 */
121 
122  /* FIXME: Clear the positive status as well, just to be sure */
125 
126  /* Enable events for GPIO7 (DCONIRQ) and GPIO12 (DCONBLANK) */
129 
130  return 0;
131 
132 err_req_irq:
134 err_gp_blank:
136 err_gp_load:
138 err_gp_irq:
140 err_gp_stat1:
142  return -EIO;
143 }
144 
145 static void dcon_wiggle_xo_1(void)
146 {
147  int x;
148 
149  /*
150  * According to HiMax, when powering the DCON up we should hold
151  * SMB_DATA high for 8 SMB_CLK cycles. This will force the DCON
152  * state machine to reset to a (sane) initial state. Mitch Bradley
153  * did some testing and discovered that holding for 16 SMB_CLK cycles
154  * worked a lot more reliably, so that's what we do here.
155  *
156  * According to the cs5536 spec, to set GPIO14 to SMB_CLK we must
157  * simultaneously set AUX1 IN/OUT to GPIO14; ditto for SMB_DATA and
158  * GPIO15.
159  */
170 
171  for (x = 0; x < 16; x++) {
172  udelay(5);
174  udelay(5);
176  }
177  udelay(5);
182 }
183 
184 static void dcon_set_dconload_1(int val)
185 {
187 }
188 
189 static int dcon_read_status_xo_1(u8 *status)
190 {
192  *status |= gpio_get_value(OLPC_GPIO_DCON_STAT1) << 1;
193 
194  /* Clear the negative edge status for GPIO7 */
196 
197  return 0;
198 }
199 
201  .init = dcon_init_xo_1,
202  .bus_stabilize_wiggle = dcon_wiggle_xo_1,
203  .set_dconload = dcon_set_dconload_1,
204  .read_status = dcon_read_status_xo_1,
205 };