diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/i2c/busses/i2c-parport.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/i2c/busses/i2c-parport.c')
-rw-r--r-- | drivers/i2c/busses/i2c-parport.c | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c index 0d8998610c74..846583ed4763 100644 --- a/drivers/i2c/busses/i2c-parport.c +++ b/drivers/i2c/busses/i2c-parport.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* ------------------------------------------------------------------------ * | 1 | /* ------------------------------------------------------------------------ * |
2 | * i2c-parport.c I2C bus over parallel port * | 2 | * i2c-parport.c I2C bus over parallel port * |
3 | * ------------------------------------------------------------------------ * | 3 | * ------------------------------------------------------------------------ * |
4 | Copyright (C) 2003-2007 Jean Delvare <khali@linux-fr.org> | 4 | Copyright (C) 2003-2010 Jean Delvare <khali@linux-fr.org> |
5 | 5 | ||
6 | Based on older i2c-philips-par.c driver | 6 | Based on older i2c-philips-par.c driver |
7 | Copyright (C) 1995-2000 Simon G. Vogl | 7 | Copyright (C) 1995-2000 Simon G. Vogl |
@@ -27,9 +27,12 @@ | |||
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/delay.h> | ||
30 | #include <linux/parport.h> | 31 | #include <linux/parport.h> |
31 | #include <linux/i2c.h> | 32 | #include <linux/i2c.h> |
32 | #include <linux/i2c-algo-bit.h> | 33 | #include <linux/i2c-algo-bit.h> |
34 | #include <linux/i2c-smbus.h> | ||
35 | #include <linux/slab.h> | ||
33 | #include "i2c-parport.h" | 36 | #include "i2c-parport.h" |
34 | 37 | ||
35 | /* ----- Device list ------------------------------------------------------ */ | 38 | /* ----- Device list ------------------------------------------------------ */ |
@@ -38,6 +41,8 @@ struct i2c_par { | |||
38 | struct pardevice *pdev; | 41 | struct pardevice *pdev; |
39 | struct i2c_adapter adapter; | 42 | struct i2c_adapter adapter; |
40 | struct i2c_algo_bit_data algo_data; | 43 | struct i2c_algo_bit_data algo_data; |
44 | struct i2c_smbus_alert_setup alert_data; | ||
45 | struct i2c_client *ara; | ||
41 | struct i2c_par *next; | 46 | struct i2c_par *next; |
42 | }; | 47 | }; |
43 | 48 | ||
@@ -143,6 +148,19 @@ static struct i2c_algo_bit_data parport_algo_data = { | |||
143 | 148 | ||
144 | /* ----- I2c and parallel port call-back functions and structures --------- */ | 149 | /* ----- I2c and parallel port call-back functions and structures --------- */ |
145 | 150 | ||
151 | void i2c_parport_irq(void *data) | ||
152 | { | ||
153 | struct i2c_par *adapter = data; | ||
154 | struct i2c_client *ara = adapter->ara; | ||
155 | |||
156 | if (ara) { | ||
157 | dev_dbg(&ara->dev, "SMBus alert received\n"); | ||
158 | i2c_handle_smbus_alert(ara); | ||
159 | } else | ||
160 | dev_dbg(&adapter->adapter.dev, | ||
161 | "SMBus alert received but no ARA client!\n"); | ||
162 | } | ||
163 | |||
146 | static void i2c_parport_attach (struct parport *port) | 164 | static void i2c_parport_attach (struct parport *port) |
147 | { | 165 | { |
148 | struct i2c_par *adapter; | 166 | struct i2c_par *adapter; |
@@ -154,8 +172,9 @@ static void i2c_parport_attach (struct parport *port) | |||
154 | } | 172 | } |
155 | 173 | ||
156 | pr_debug("i2c-parport: attaching to %s\n", port->name); | 174 | pr_debug("i2c-parport: attaching to %s\n", port->name); |
175 | parport_disable_irq(port); | ||
157 | adapter->pdev = parport_register_device(port, "i2c-parport", | 176 | adapter->pdev = parport_register_device(port, "i2c-parport", |
158 | NULL, NULL, NULL, PARPORT_FLAG_EXCL, NULL); | 177 | NULL, NULL, i2c_parport_irq, PARPORT_FLAG_EXCL, adapter); |
159 | if (!adapter->pdev) { | 178 | if (!adapter->pdev) { |
160 | printk(KERN_ERR "i2c-parport: Unable to register with parport\n"); | 179 | printk(KERN_ERR "i2c-parport: Unable to register with parport\n"); |
161 | goto ERROR0; | 180 | goto ERROR0; |
@@ -185,14 +204,29 @@ static void i2c_parport_attach (struct parport *port) | |||
185 | parport_setsda(port, 1); | 204 | parport_setsda(port, 1); |
186 | parport_setscl(port, 1); | 205 | parport_setscl(port, 1); |
187 | /* Other init if needed (power on...) */ | 206 | /* Other init if needed (power on...) */ |
188 | if (adapter_parm[type].init.val) | 207 | if (adapter_parm[type].init.val) { |
189 | line_set(port, 1, &adapter_parm[type].init); | 208 | line_set(port, 1, &adapter_parm[type].init); |
209 | /* Give powered devices some time to settle */ | ||
210 | msleep(100); | ||
211 | } | ||
190 | 212 | ||
191 | if (i2c_bit_add_bus(&adapter->adapter) < 0) { | 213 | if (i2c_bit_add_bus(&adapter->adapter) < 0) { |
192 | printk(KERN_ERR "i2c-parport: Unable to register with I2C\n"); | 214 | printk(KERN_ERR "i2c-parport: Unable to register with I2C\n"); |
193 | goto ERROR1; | 215 | goto ERROR1; |
194 | } | 216 | } |
195 | 217 | ||
218 | /* Setup SMBus alert if supported */ | ||
219 | if (adapter_parm[type].smbus_alert) { | ||
220 | adapter->alert_data.alert_edge_triggered = 1; | ||
221 | adapter->ara = i2c_setup_smbus_alert(&adapter->adapter, | ||
222 | &adapter->alert_data); | ||
223 | if (adapter->ara) | ||
224 | parport_enable_irq(port); | ||
225 | else | ||
226 | printk(KERN_WARNING "i2c-parport: Failed to register " | ||
227 | "ARA client\n"); | ||
228 | } | ||
229 | |||
196 | /* Add the new adapter to the list */ | 230 | /* Add the new adapter to the list */ |
197 | adapter->next = adapter_list; | 231 | adapter->next = adapter_list; |
198 | adapter_list = adapter; | 232 | adapter_list = adapter; |
@@ -213,6 +247,10 @@ static void i2c_parport_detach (struct parport *port) | |||
213 | for (prev = NULL, adapter = adapter_list; adapter; | 247 | for (prev = NULL, adapter = adapter_list; adapter; |
214 | prev = adapter, adapter = adapter->next) { | 248 | prev = adapter, adapter = adapter->next) { |
215 | if (adapter->pdev->port == port) { | 249 | if (adapter->pdev->port == port) { |
250 | if (adapter->ara) { | ||
251 | parport_disable_irq(port); | ||
252 | i2c_unregister_device(adapter->ara); | ||
253 | } | ||
216 | i2c_del_adapter(&adapter->adapter); | 254 | i2c_del_adapter(&adapter->adapter); |
217 | 255 | ||
218 | /* Un-init if needed (power off...) */ | 256 | /* Un-init if needed (power off...) */ |