Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
420 | giacomo | 1 | /* |
2 | i2c Support for Apple Keywest I2C Bus Controller |
||
3 | |||
4 | Copyright (c) 2001 Benjamin Herrenschmidt <benh@kernel.crashing.org> |
||
5 | |||
6 | Original work by |
||
7 | |||
8 | Copyright (c) 2000 Philip Edelbrock <phil@stimpy.netroedge.com> |
||
9 | |||
10 | This program is free software; you can redistribute it and/or modify |
||
11 | it under the terms of the GNU General Public License as published by |
||
12 | the Free Software Foundation; either version 2 of the License, or |
||
13 | (at your option) any later version. |
||
14 | |||
15 | This program is distributed in the hope that it will be useful, |
||
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
18 | GNU General Public License for more details. |
||
19 | |||
20 | You should have received a copy of the GNU General Public License |
||
21 | along with this program; if not, write to the Free Software |
||
22 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
||
23 | |||
24 | Changes: |
||
25 | |||
26 | 2001/12/13 BenH New implementation |
||
27 | 2001/12/15 BenH Add support for "byte" and "quick" |
||
28 | transfers. Add i2c_xfer routine. |
||
29 | |||
30 | My understanding of the various modes supported by keywest are: |
||
31 | |||
32 | - Dumb mode : not implemented, probably direct tweaking of lines |
||
33 | - Standard mode : simple i2c transaction of type |
||
34 | S Addr R/W A Data A Data ... T |
||
35 | - Standard sub mode : combined 8 bit subaddr write with data read |
||
36 | S Addr R/W A SubAddr A Data A Data ... T |
||
37 | - Combined mode : Subaddress and Data sequences appended with no stop |
||
38 | S Addr R/W A SubAddr S Addr R/W A Data A Data ... T |
||
39 | |||
40 | Currently, this driver uses only Standard mode for i2c xfer, and |
||
41 | smbus byte & quick transfers ; and uses StandardSub mode for |
||
42 | other smbus transfers instead of combined as we need that for the |
||
43 | sound driver to be happy |
||
44 | */ |
||
45 | |||
46 | #include <linux/module.h> |
||
47 | #include <linux/config.h> |
||
48 | #include <linux/kernel.h> |
||
49 | #include <linux/ioport.h> |
||
50 | #include <linux/pci.h> |
||
51 | #include <linux/types.h> |
||
52 | #include <linux/delay.h> |
||
53 | #include <linux/i2c.h> |
||
54 | #include <linux/init.h> |
||
55 | #include <linux/mm.h> |
||
56 | #include <linux/timer.h> |
||
57 | #include <linux/spinlock.h> |
||
58 | #include <linux/completion.h> |
||
59 | #include <linux/interrupt.h> |
||
60 | |||
61 | #include <asm/io.h> |
||
62 | #include <asm/prom.h> |
||
63 | #include <asm/machdep.h> |
||
64 | #include <asm/pmac_feature.h> |
||
65 | |||
66 | #include "i2c-keywest.h" |
||
67 | |||
68 | #define DBG(x...) do {\ |
||
69 | if (debug > 0) \ |
||
70 | printk(KERN_DEBUG "KW:" x); \ |
||
71 | } while(0) |
||
72 | |||
73 | |||
74 | MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>"); |
||
75 | MODULE_DESCRIPTION("I2C driver for Apple's Keywest"); |
||
76 | MODULE_LICENSE("GPL"); |
||
77 | MODULE_PARM(probe, "i"); |
||
78 | MODULE_PARM(debug, "i"); |
||
79 | |||
80 | int probe = 0; |
||
81 | int debug = 0; |
||
82 | |||
83 | static void |
||
84 | do_stop(struct keywest_iface* iface, int result) |
||
85 | { |
||
86 | write_reg(reg_control, read_reg(reg_control) | KW_I2C_CTL_STOP); |
||
87 | iface->state = state_stop; |
||
88 | iface->result = result; |
||
89 | } |
||
90 | |||
91 | /* Main state machine for standard & standard sub mode */ |
||
92 | static int |
||
93 | handle_interrupt(struct keywest_iface *iface, u8 isr) |
||
94 | { |
||
95 | int ack; |
||
96 | int rearm_timer = 1; |
||
97 | |||
98 | DBG("handle_interrupt(), got: %x, status: %x, state: %d\n", |
||
99 | isr, read_reg(reg_status), iface->state); |
||
100 | if (isr == 0 && iface->state != state_stop) { |
||
101 | do_stop(iface, -1); |
||
102 | return rearm_timer; |
||
103 | } |
||
104 | if (isr & KW_I2C_IRQ_STOP && iface->state != state_stop) { |
||
105 | iface->result = -1; |
||
106 | iface->state = state_stop; |
||
107 | } |
||
108 | switch(iface->state) { |
||
109 | case state_addr: |
||
110 | if (!(isr & KW_I2C_IRQ_ADDR)) { |
||
111 | do_stop(iface, -1); |
||
112 | break; |
||
113 | } |
||
114 | ack = read_reg(reg_status); |
||
115 | DBG("ack on set address: %x\n", ack); |
||
116 | if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { |
||
117 | do_stop(iface, -1); |
||
118 | break; |
||
119 | } |
||
120 | /* Handle rw "quick" mode */ |
||
121 | if (iface->datalen == 0) |
||
122 | do_stop(iface, 0); |
||
123 | else if (iface->read_write == I2C_SMBUS_READ) { |
||
124 | iface->state = state_read; |
||
125 | if (iface->datalen > 1) |
||
126 | write_reg(reg_control, read_reg(reg_control) |
||
127 | | KW_I2C_CTL_AAK); |
||
128 | } else { |
||
129 | iface->state = state_write; |
||
130 | DBG("write byte: %x\n", *(iface->data)); |
||
131 | write_reg(reg_data, *(iface->data++)); |
||
132 | iface->datalen--; |
||
133 | } |
||
134 | |||
135 | break; |
||
136 | case state_read: |
||
137 | if (!(isr & KW_I2C_IRQ_DATA)) { |
||
138 | do_stop(iface, -1); |
||
139 | break; |
||
140 | } |
||
141 | *(iface->data++) = read_reg(reg_data); |
||
142 | DBG("read byte: %x\n", *(iface->data-1)); |
||
143 | iface->datalen--; |
||
144 | if (iface->datalen == 0) |
||
145 | iface->state = state_stop; |
||
146 | else |
||
147 | write_reg(reg_control, 0); |
||
148 | break; |
||
149 | case state_write: |
||
150 | if (!(isr & KW_I2C_IRQ_DATA)) { |
||
151 | do_stop(iface, -1); |
||
152 | break; |
||
153 | } |
||
154 | /* Check ack status */ |
||
155 | ack = read_reg(reg_status); |
||
156 | DBG("ack on data write: %x\n", ack); |
||
157 | if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { |
||
158 | do_stop(iface, -1); |
||
159 | break; |
||
160 | } |
||
161 | if (iface->datalen) { |
||
162 | DBG("write byte: %x\n", *(iface->data)); |
||
163 | write_reg(reg_data, *(iface->data++)); |
||
164 | iface->datalen--; |
||
165 | } else |
||
166 | do_stop(iface, 0); |
||
167 | break; |
||
168 | |||
169 | case state_stop: |
||
170 | if (!(isr & KW_I2C_IRQ_STOP) && (++iface->stopretry) < 10) |
||
171 | do_stop(iface, -1); |
||
172 | else { |
||
173 | rearm_timer = 0; |
||
174 | iface->state = state_idle; |
||
175 | write_reg(reg_control, 0x00); |
||
176 | write_reg(reg_ier, 0x00); |
||
177 | complete(&iface->complete); |
||
178 | } |
||
179 | break; |
||
180 | } |
||
181 | |||
182 | write_reg(reg_isr, isr); |
||
183 | |||
184 | return rearm_timer; |
||
185 | } |
||
186 | |||
187 | /* Interrupt handler */ |
||
188 | static irqreturn_t |
||
189 | keywest_irq(int irq, void *dev_id, struct pt_regs *regs) |
||
190 | { |
||
191 | struct keywest_iface *iface = (struct keywest_iface *)dev_id; |
||
192 | |||
193 | spin_lock(&iface->lock); |
||
194 | del_timer(&iface->timeout_timer); |
||
195 | if (handle_interrupt(iface, read_reg(reg_isr))) |
||
196 | mod_timer(&iface->timeout_timer, jiffies + POLL_TIMEOUT); |
||
197 | spin_unlock(&iface->lock); |
||
198 | return IRQ_HANDLED; |
||
199 | } |
||
200 | |||
201 | static void |
||
202 | keywest_timeout(unsigned long data) |
||
203 | { |
||
204 | struct keywest_iface *iface = (struct keywest_iface *)data; |
||
205 | |||
206 | DBG("timeout !\n"); |
||
207 | spin_lock_irq(&iface->lock); |
||
208 | if (handle_interrupt(iface, read_reg(reg_isr))) |
||
209 | mod_timer(&iface->timeout_timer, jiffies + POLL_TIMEOUT); |
||
210 | spin_unlock(&iface->lock); |
||
211 | } |
||
212 | |||
213 | /* |
||
214 | * SMBUS-type transfer entrypoint |
||
215 | */ |
||
216 | static s32 |
||
217 | keywest_smbus_xfer( struct i2c_adapter* adap, |
||
218 | u16 addr, |
||
219 | unsigned short flags, |
||
220 | char read_write, |
||
221 | u8 command, |
||
222 | int size, |
||
223 | union i2c_smbus_data* data) |
||
224 | { |
||
225 | struct keywest_chan* chan = i2c_get_adapdata(adap); |
||
226 | struct keywest_iface* iface = chan->iface; |
||
227 | int len; |
||
228 | u8* buffer; |
||
229 | u16 cur_word; |
||
230 | int rc = 0; |
||
231 | |||
232 | if (iface->state == state_dead) |
||
233 | return -1; |
||
234 | |||
235 | /* Prepare datas & select mode */ |
||
236 | iface->cur_mode &= ~KW_I2C_MODE_MODE_MASK; |
||
237 | switch (size) { |
||
238 | case I2C_SMBUS_QUICK: |
||
239 | len = 0; |
||
240 | buffer = NULL; |
||
241 | iface->cur_mode |= KW_I2C_MODE_STANDARD; |
||
242 | break; |
||
243 | case I2C_SMBUS_BYTE: |
||
244 | len = 1; |
||
245 | buffer = &data->byte; |
||
246 | iface->cur_mode |= KW_I2C_MODE_STANDARD; |
||
247 | break; |
||
248 | case I2C_SMBUS_BYTE_DATA: |
||
249 | len = 1; |
||
250 | buffer = &data->byte; |
||
251 | iface->cur_mode |= KW_I2C_MODE_STANDARDSUB; |
||
252 | break; |
||
253 | case I2C_SMBUS_WORD_DATA: |
||
254 | len = 2; |
||
255 | cur_word = cpu_to_le16(data->word); |
||
256 | buffer = (u8 *)&cur_word; |
||
257 | iface->cur_mode |= KW_I2C_MODE_STANDARDSUB; |
||
258 | break; |
||
259 | case I2C_SMBUS_BLOCK_DATA: |
||
260 | len = data->block[0]; |
||
261 | buffer = &data->block[1]; |
||
262 | iface->cur_mode |= KW_I2C_MODE_STANDARDSUB; |
||
263 | break; |
||
264 | default: |
||
265 | return -1; |
||
266 | } |
||
267 | |||
268 | /* Original driver had this limitation */ |
||
269 | if (len > 32) |
||
270 | len = 32; |
||
271 | |||
272 | down(&iface->sem); |
||
273 | |||
274 | DBG("chan: %d, addr: 0x%x, transfer len: %d, read: %d\n", |
||
275 | chan->chan_no, addr, len, read_write == I2C_SMBUS_READ); |
||
276 | |||
277 | iface->data = buffer; |
||
278 | iface->datalen = len; |
||
279 | iface->state = state_addr; |
||
280 | iface->result = 0; |
||
281 | iface->stopretry = 0; |
||
282 | iface->read_write = read_write; |
||
283 | |||
284 | /* Setup channel & clear pending irqs */ |
||
285 | write_reg(reg_mode, iface->cur_mode | (chan->chan_no << 4)); |
||
286 | write_reg(reg_isr, read_reg(reg_isr)); |
||
287 | write_reg(reg_status, 0); |
||
288 | |||
289 | /* Set up address and r/w bit */ |
||
290 | write_reg(reg_addr, |
||
291 | (addr << 1) | ((read_write == I2C_SMBUS_READ) ? 0x01 : 0x00)); |
||
292 | |||
293 | /* Set up the sub address */ |
||
294 | if ((iface->cur_mode & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_STANDARDSUB |
||
295 | || (iface->cur_mode & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_COMBINED) |
||
296 | write_reg(reg_subaddr, command); |
||
297 | |||
298 | /* Arm timeout */ |
||
299 | mod_timer(&iface->timeout_timer, jiffies + POLL_TIMEOUT); |
||
300 | |||
301 | /* Start sending address & enable interrupt*/ |
||
302 | write_reg(reg_control, read_reg(reg_control) | KW_I2C_CTL_XADDR); |
||
303 | write_reg(reg_ier, KW_I2C_IRQ_MASK); |
||
304 | |||
305 | /* Wait interrupt operations completion */ |
||
306 | wait_for_completion(&iface->complete); |
||
307 | |||
308 | rc = iface->result; |
||
309 | DBG("transfer done, result: %d\n", rc); |
||
310 | |||
311 | if (rc == 0 && size == I2C_SMBUS_WORD_DATA && read_write == I2C_SMBUS_READ) |
||
312 | data->word = le16_to_cpu(cur_word); |
||
313 | |||
314 | /* Release sem */ |
||
315 | up(&iface->sem); |
||
316 | |||
317 | return rc; |
||
318 | } |
||
319 | |||
320 | /* |
||
321 | * Generic i2c master transfer entrypoint |
||
322 | */ |
||
323 | static int |
||
324 | keywest_xfer( struct i2c_adapter *adap, |
||
325 | struct i2c_msg msgs[], |
||
326 | int num) |
||
327 | { |
||
328 | struct keywest_chan* chan = i2c_get_adapdata(adap); |
||
329 | struct keywest_iface* iface = chan->iface; |
||
330 | struct i2c_msg *pmsg; |
||
331 | int i, completed; |
||
332 | int rc = 0; |
||
333 | |||
334 | down(&iface->sem); |
||
335 | |||
336 | /* Set adapter to standard mode */ |
||
337 | iface->cur_mode &= ~KW_I2C_MODE_MODE_MASK; |
||
338 | iface->cur_mode |= KW_I2C_MODE_STANDARD; |
||
339 | |||
340 | completed = 0; |
||
341 | for (i = 0; rc >= 0 && i < num;) { |
||
342 | u8 addr; |
||
343 | |||
344 | pmsg = &msgs[i++]; |
||
345 | addr = pmsg->addr; |
||
346 | if (pmsg->flags & I2C_M_TEN) { |
||
347 | printk(KERN_ERR "i2c-keywest: 10 bits addr not supported !\n"); |
||
348 | rc = -EINVAL; |
||
349 | break; |
||
350 | } |
||
351 | DBG("xfer: chan: %d, doing %s %d bytes to 0x%02x - %d of %d messages\n", |
||
352 | chan->chan_no, |
||
353 | pmsg->flags & I2C_M_RD ? "read" : "write", |
||
354 | pmsg->len, addr, i, num); |
||
355 | |||
356 | /* Setup channel & clear pending irqs */ |
||
357 | write_reg(reg_mode, iface->cur_mode | (chan->chan_no << 4)); |
||
358 | write_reg(reg_isr, read_reg(reg_isr)); |
||
359 | write_reg(reg_status, 0); |
||
360 | |||
361 | iface->data = pmsg->buf; |
||
362 | iface->datalen = pmsg->len; |
||
363 | iface->state = state_addr; |
||
364 | iface->result = 0; |
||
365 | iface->stopretry = 0; |
||
366 | if (pmsg->flags & I2C_M_RD) |
||
367 | iface->read_write = I2C_SMBUS_READ; |
||
368 | else |
||
369 | iface->read_write = I2C_SMBUS_WRITE; |
||
370 | |||
371 | /* Set up address and r/w bit */ |
||
372 | if (pmsg->flags & I2C_M_REV_DIR_ADDR) |
||
373 | addr ^= 1; |
||
374 | write_reg(reg_addr, |
||
375 | (addr << 1) | |
||
376 | ((iface->read_write == I2C_SMBUS_READ) ? 0x01 : 0x00)); |
||
377 | |||
378 | /* Arm timeout */ |
||
379 | mod_timer(&iface->timeout_timer, jiffies + POLL_TIMEOUT); |
||
380 | |||
381 | /* Start sending address & enable interrupt*/ |
||
382 | write_reg(reg_control, read_reg(reg_control) | KW_I2C_CTL_XADDR); |
||
383 | write_reg(reg_ier, KW_I2C_IRQ_MASK); |
||
384 | |||
385 | /* Wait interrupt operations completion */ |
||
386 | wait_for_completion(&iface->complete); |
||
387 | |||
388 | rc = iface->result; |
||
389 | if (rc == 0) |
||
390 | completed++; |
||
391 | DBG("transfer done, result: %d\n", rc); |
||
392 | } |
||
393 | |||
394 | /* Release sem */ |
||
395 | up(&iface->sem); |
||
396 | |||
397 | return completed; |
||
398 | } |
||
399 | |||
400 | static u32 |
||
401 | keywest_func(struct i2c_adapter * adapter) |
||
402 | { |
||
403 | return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | |
||
404 | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | |
||
405 | I2C_FUNC_SMBUS_BLOCK_DATA; |
||
406 | } |
||
407 | |||
408 | /* For now, we only handle combined mode (smbus) */ |
||
409 | static struct i2c_algorithm keywest_algorithm = { |
||
410 | .name = "Keywest i2c", |
||
411 | .id = I2C_ALGO_SMBUS, |
||
412 | .smbus_xfer = keywest_smbus_xfer, |
||
413 | .master_xfer = keywest_xfer, |
||
414 | .functionality = keywest_func, |
||
415 | }; |
||
416 | |||
417 | |||
418 | static int |
||
419 | create_iface(struct device_node *np, struct device *dev) |
||
420 | { |
||
421 | unsigned long steps, *psteps, *prate; |
||
422 | unsigned bsteps, tsize, i, nchan, addroffset; |
||
423 | struct keywest_iface* iface; |
||
424 | int rc; |
||
425 | |||
426 | psteps = (unsigned long *)get_property(np, "AAPL,address-step", NULL); |
||
427 | steps = psteps ? (*psteps) : 0x10; |
||
428 | |||
429 | /* Hrm... maybe we can be smarter here */ |
||
430 | for (bsteps = 0; (steps & 0x01) == 0; bsteps++) |
||
431 | steps >>= 1; |
||
432 | |||
433 | if (!strcmp(np->parent->name, "uni-n")) { |
||
434 | nchan = 2; |
||
435 | addroffset = 3; |
||
436 | } else { |
||
437 | addroffset = 0; |
||
438 | nchan = 1; |
||
439 | } |
||
440 | |||
441 | tsize = sizeof(struct keywest_iface) + |
||
442 | (sizeof(struct keywest_chan) + 4) * nchan; |
||
443 | iface = (struct keywest_iface *) kmalloc(tsize, GFP_KERNEL); |
||
444 | if (iface == NULL) { |
||
445 | printk(KERN_ERR "i2c-keywest: can't allocate inteface !\n"); |
||
446 | return -ENOMEM; |
||
447 | } |
||
448 | memset(iface, 0, tsize); |
||
449 | init_MUTEX(&iface->sem); |
||
450 | spin_lock_init(&iface->lock); |
||
451 | init_completion(&iface->complete); |
||
452 | iface->bsteps = bsteps; |
||
453 | iface->chan_count = nchan; |
||
454 | iface->state = state_idle; |
||
455 | iface->irq = np->intrs[0].line; |
||
456 | iface->channels = (struct keywest_chan *) |
||
457 | (((unsigned long)(iface + 1) + 3UL) & ~3UL); |
||
458 | iface->base = (unsigned long)ioremap(np->addrs[0].address + addroffset, |
||
459 | np->addrs[0].size); |
||
460 | if (iface->base == 0) { |
||
461 | printk(KERN_ERR "i2c-keywest: can't map inteface !\n"); |
||
462 | kfree(iface); |
||
463 | return -ENOMEM; |
||
464 | } |
||
465 | |||
466 | init_timer(&iface->timeout_timer); |
||
467 | iface->timeout_timer.function = keywest_timeout; |
||
468 | iface->timeout_timer.data = (unsigned long)iface; |
||
469 | |||
470 | /* Select interface rate */ |
||
471 | iface->cur_mode = KW_I2C_MODE_100KHZ; |
||
472 | prate = (unsigned long *)get_property(np, "AAPL,i2c-rate", NULL); |
||
473 | if (prate) switch(*prate) { |
||
474 | case 100: |
||
475 | iface->cur_mode = KW_I2C_MODE_100KHZ; |
||
476 | break; |
||
477 | case 50: |
||
478 | iface->cur_mode = KW_I2C_MODE_50KHZ; |
||
479 | break; |
||
480 | case 25: |
||
481 | iface->cur_mode = KW_I2C_MODE_25KHZ; |
||
482 | break; |
||
483 | default: |
||
484 | printk(KERN_WARNING "i2c-keywest: unknown rate %ldKhz, using 100KHz\n", |
||
485 | *prate); |
||
486 | } |
||
487 | |||
488 | /* Select standard sub mode */ |
||
489 | iface->cur_mode |= KW_I2C_MODE_STANDARDSUB; |
||
490 | |||
491 | /* Write mode */ |
||
492 | write_reg(reg_mode, iface->cur_mode); |
||
493 | |||
494 | /* Switch interrupts off & clear them*/ |
||
495 | write_reg(reg_ier, 0x00); |
||
496 | write_reg(reg_isr, KW_I2C_IRQ_MASK); |
||
497 | |||
498 | /* Request chip interrupt */ |
||
499 | rc = request_irq(iface->irq, keywest_irq, 0, "keywest i2c", iface); |
||
500 | if (rc) { |
||
501 | printk(KERN_ERR "i2c-keywest: can't get IRQ %d !\n", iface->irq); |
||
502 | iounmap((void *)iface->base); |
||
503 | kfree(iface); |
||
504 | return -ENODEV; |
||
505 | } |
||
506 | |||
507 | dev_set_drvdata(dev, iface); |
||
508 | |||
509 | for (i=0; i<nchan; i++) { |
||
510 | struct keywest_chan* chan = &iface->channels[i]; |
||
511 | u8 addr; |
||
512 | |||
513 | sprintf(chan->adapter.name, "%s %d", np->parent->name, i); |
||
514 | chan->iface = iface; |
||
515 | chan->chan_no = i; |
||
516 | chan->adapter.id = I2C_ALGO_SMBUS; |
||
517 | chan->adapter.algo = &keywest_algorithm; |
||
518 | chan->adapter.algo_data = NULL; |
||
519 | chan->adapter.client_register = NULL; |
||
520 | chan->adapter.client_unregister = NULL; |
||
521 | i2c_set_adapdata(&chan->adapter, chan); |
||
522 | chan->adapter.dev.parent = dev; |
||
523 | |||
524 | rc = i2c_add_adapter(&chan->adapter); |
||
525 | if (rc) { |
||
526 | printk("i2c-keywest.c: Adapter %s registration failed\n", |
||
527 | chan->adapter.name); |
||
528 | i2c_set_adapdata(&chan->adapter, NULL); |
||
529 | } |
||
530 | if (probe) { |
||
531 | printk("Probe: "); |
||
532 | for (addr = 0x00; addr <= 0x7f; addr++) { |
||
533 | if (i2c_smbus_xfer(&chan->adapter,addr, |
||
534 | 0,0,0,I2C_SMBUS_QUICK,NULL) >= 0) |
||
535 | printk("%02x ", addr); |
||
536 | } |
||
537 | printk("\n"); |
||
538 | } |
||
539 | } |
||
540 | |||
541 | printk(KERN_INFO "Found KeyWest i2c on \"%s\", %d channel%s, stepping: %d bits\n", |
||
542 | np->parent->name, nchan, nchan > 1 ? "s" : "", bsteps); |
||
543 | |||
544 | return 0; |
||
545 | } |
||
546 | |||
547 | static int |
||
548 | dispose_iface(struct device *dev) |
||
549 | { |
||
550 | struct keywest_iface *iface = dev_get_drvdata(dev); |
||
551 | int i, rc; |
||
552 | |||
553 | /* Make sure we stop all activity */ |
||
554 | down(&iface->sem); |
||
555 | |||
556 | spin_lock_irq(&iface->lock); |
||
557 | while (iface->state != state_idle) { |
||
558 | spin_unlock_irq(&iface->lock); |
||
559 | set_task_state(current,TASK_UNINTERRUPTIBLE); |
||
560 | schedule_timeout(HZ/10); |
||
561 | spin_lock_irq(&iface->lock); |
||
562 | } |
||
563 | iface->state = state_dead; |
||
564 | spin_unlock_irq(&iface->lock); |
||
565 | free_irq(iface->irq, iface); |
||
566 | up(&iface->sem); |
||
567 | |||
568 | /* Release all channels */ |
||
569 | for (i=0; i<iface->chan_count; i++) { |
||
570 | struct keywest_chan* chan = &iface->channels[i]; |
||
571 | if (i2c_get_adapdata(&chan->adapter) == NULL) |
||
572 | continue; |
||
573 | rc = i2c_del_adapter(&chan->adapter); |
||
574 | i2c_set_adapdata(&chan->adapter, NULL); |
||
575 | /* We aren't that prepared to deal with this... */ |
||
576 | if (rc) |
||
577 | printk("i2c-keywest.c: i2c_del_adapter failed, that's bad !\n"); |
||
578 | } |
||
579 | iounmap((void *)iface->base); |
||
580 | dev_set_drvdata(dev, NULL); |
||
581 | kfree(iface); |
||
582 | |||
583 | return 0; |
||
584 | } |
||
585 | |||
586 | static int |
||
587 | create_iface_macio(struct macio_dev* dev, const struct of_match *match) |
||
588 | { |
||
589 | return create_iface(dev->ofdev.node, &dev->ofdev.dev); |
||
590 | } |
||
591 | |||
592 | static int |
||
593 | dispose_iface_macio(struct macio_dev* dev) |
||
594 | { |
||
595 | return dispose_iface(&dev->ofdev.dev); |
||
596 | } |
||
597 | |||
598 | static int |
||
599 | create_iface_of_platform(struct of_device* dev, const struct of_match *match) |
||
600 | { |
||
601 | return create_iface(dev->node, &dev->dev); |
||
602 | } |
||
603 | |||
604 | static int |
||
605 | dispose_iface_of_platform(struct of_device* dev) |
||
606 | { |
||
607 | return dispose_iface(&dev->dev); |
||
608 | } |
||
609 | |||
610 | static struct of_match i2c_keywest_match[] = |
||
611 | { |
||
612 | { |
||
613 | .name = OF_ANY_MATCH, |
||
614 | .type = "i2c", |
||
615 | .compatible = "keywest" |
||
616 | }, |
||
617 | {}, |
||
618 | }; |
||
619 | |||
620 | static struct macio_driver i2c_keywest_macio_driver = |
||
621 | { |
||
622 | .name = "i2c-keywest", |
||
623 | .match_table = i2c_keywest_match, |
||
624 | .probe = create_iface_macio, |
||
625 | .remove = dispose_iface_macio |
||
626 | }; |
||
627 | |||
628 | static struct of_platform_driver i2c_keywest_of_platform_driver = |
||
629 | { |
||
630 | .name = "i2c-keywest", |
||
631 | .match_table = i2c_keywest_match, |
||
632 | .probe = create_iface_of_platform, |
||
633 | .remove = dispose_iface_of_platform |
||
634 | }; |
||
635 | |||
636 | static int __init |
||
637 | i2c_keywest_init(void) |
||
638 | { |
||
639 | macio_register_driver(&i2c_keywest_macio_driver); |
||
640 | of_register_driver(&i2c_keywest_of_platform_driver); |
||
641 | |||
642 | return 0; |
||
643 | } |
||
644 | |||
645 | static void __exit |
||
646 | i2c_keywest_cleanup(void) |
||
647 | { |
||
648 | macio_unregister_driver(&i2c_keywest_macio_driver); |
||
649 | of_unregister_driver(&i2c_keywest_of_platform_driver); |
||
650 | } |
||
651 | |||
652 | module_init(i2c_keywest_init); |
||
653 | module_exit(i2c_keywest_cleanup); |