diff options
-rw-r--r-- | drivers/i2c/busses/i2c-pxa.c | 131 | ||||
-rw-r--r-- | include/linux/i2c-pxa.h | 31 |
2 files changed, 1 insertions, 161 deletions
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index c95a6c154165..c3b1567c852a 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c | |||
@@ -358,133 +358,6 @@ static void i2c_pxa_reset(struct pxa_i2c *i2c) | |||
358 | 358 | ||
359 | #ifdef CONFIG_I2C_PXA_SLAVE | 359 | #ifdef CONFIG_I2C_PXA_SLAVE |
360 | /* | 360 | /* |
361 | * I2C EEPROM emulation. | ||
362 | */ | ||
363 | static struct i2c_eeprom_emu eeprom = { | ||
364 | .size = I2C_EEPROM_EMU_SIZE, | ||
365 | .watch = LIST_HEAD_INIT(eeprom.watch), | ||
366 | }; | ||
367 | |||
368 | struct i2c_eeprom_emu *i2c_pxa_get_eeprom(void) | ||
369 | { | ||
370 | return &eeprom; | ||
371 | } | ||
372 | |||
373 | int i2c_eeprom_emu_addwatcher(struct i2c_eeprom_emu *emu, void *data, | ||
374 | unsigned int addr, unsigned int size, | ||
375 | struct i2c_eeprom_emu_watcher *watcher) | ||
376 | { | ||
377 | struct i2c_eeprom_emu_watch *watch; | ||
378 | unsigned long flags; | ||
379 | |||
380 | if (addr + size > emu->size) | ||
381 | return -EINVAL; | ||
382 | |||
383 | watch = kmalloc(sizeof(struct i2c_eeprom_emu_watch), GFP_KERNEL); | ||
384 | if (watch) { | ||
385 | watch->start = addr; | ||
386 | watch->end = addr + size - 1; | ||
387 | watch->ops = watcher; | ||
388 | watch->data = data; | ||
389 | |||
390 | local_irq_save(flags); | ||
391 | list_add(&watch->node, &emu->watch); | ||
392 | local_irq_restore(flags); | ||
393 | } | ||
394 | |||
395 | return watch ? 0 : -ENOMEM; | ||
396 | } | ||
397 | |||
398 | void i2c_eeprom_emu_delwatcher(struct i2c_eeprom_emu *emu, void *data, | ||
399 | struct i2c_eeprom_emu_watcher *watcher) | ||
400 | { | ||
401 | struct i2c_eeprom_emu_watch *watch, *n; | ||
402 | unsigned long flags; | ||
403 | |||
404 | list_for_each_entry_safe(watch, n, &emu->watch, node) { | ||
405 | if (watch->ops == watcher && watch->data == data) { | ||
406 | local_irq_save(flags); | ||
407 | list_del(&watch->node); | ||
408 | local_irq_restore(flags); | ||
409 | kfree(watch); | ||
410 | } | ||
411 | } | ||
412 | } | ||
413 | |||
414 | static void i2c_eeprom_emu_event(void *ptr, i2c_slave_event_t event) | ||
415 | { | ||
416 | struct i2c_eeprom_emu *emu = ptr; | ||
417 | |||
418 | eedbg(3, "i2c_eeprom_emu_event: %d\n", event); | ||
419 | |||
420 | switch (event) { | ||
421 | case I2C_SLAVE_EVENT_START_WRITE: | ||
422 | emu->seen_start = 1; | ||
423 | eedbg(2, "i2c_eeprom: write initiated\n"); | ||
424 | break; | ||
425 | |||
426 | case I2C_SLAVE_EVENT_START_READ: | ||
427 | emu->seen_start = 0; | ||
428 | eedbg(2, "i2c_eeprom: read initiated\n"); | ||
429 | break; | ||
430 | |||
431 | case I2C_SLAVE_EVENT_STOP: | ||
432 | emu->seen_start = 0; | ||
433 | eedbg(2, "i2c_eeprom: received stop\n"); | ||
434 | break; | ||
435 | |||
436 | default: | ||
437 | eedbg(0, "i2c_eeprom: unhandled event\n"); | ||
438 | break; | ||
439 | } | ||
440 | } | ||
441 | |||
442 | static int i2c_eeprom_emu_read(void *ptr) | ||
443 | { | ||
444 | struct i2c_eeprom_emu *emu = ptr; | ||
445 | int ret; | ||
446 | |||
447 | ret = emu->bytes[emu->ptr]; | ||
448 | emu->ptr = (emu->ptr + 1) % emu->size; | ||
449 | |||
450 | return ret; | ||
451 | } | ||
452 | |||
453 | static void i2c_eeprom_emu_write(void *ptr, unsigned int val) | ||
454 | { | ||
455 | struct i2c_eeprom_emu *emu = ptr; | ||
456 | struct i2c_eeprom_emu_watch *watch; | ||
457 | |||
458 | if (emu->seen_start != 0) { | ||
459 | eedbg(2, "i2c_eeprom_emu_write: setting ptr %02x\n", val); | ||
460 | emu->ptr = val; | ||
461 | emu->seen_start = 0; | ||
462 | return; | ||
463 | } | ||
464 | |||
465 | emu->bytes[emu->ptr] = val; | ||
466 | |||
467 | eedbg(1, "i2c_eeprom_emu_write: ptr=0x%02x, val=0x%02x\n", | ||
468 | emu->ptr, val); | ||
469 | |||
470 | list_for_each_entry(watch, &emu->watch, node) { | ||
471 | if (!watch->ops || !watch->ops->write) | ||
472 | continue; | ||
473 | if (watch->start <= emu->ptr && watch->end >= emu->ptr) | ||
474 | watch->ops->write(watch->data, emu->ptr, val); | ||
475 | } | ||
476 | |||
477 | emu->ptr = (emu->ptr + 1) % emu->size; | ||
478 | } | ||
479 | |||
480 | struct i2c_slave_client eeprom_client = { | ||
481 | .data = &eeprom, | ||
482 | .event = i2c_eeprom_emu_event, | ||
483 | .read = i2c_eeprom_emu_read, | ||
484 | .write = i2c_eeprom_emu_write | ||
485 | }; | ||
486 | |||
487 | /* | ||
488 | * PXA I2C Slave mode | 361 | * PXA I2C Slave mode |
489 | */ | 362 | */ |
490 | 363 | ||
@@ -963,11 +836,9 @@ static int i2c_pxa_probe(struct platform_device *dev) | |||
963 | i2c->slave_addr = I2C_PXA_SLAVE_ADDR; | 836 | i2c->slave_addr = I2C_PXA_SLAVE_ADDR; |
964 | 837 | ||
965 | #ifdef CONFIG_I2C_PXA_SLAVE | 838 | #ifdef CONFIG_I2C_PXA_SLAVE |
966 | i2c->slave = &eeprom_client; | ||
967 | if (plat) { | 839 | if (plat) { |
968 | i2c->slave_addr = plat->slave_addr; | 840 | i2c->slave_addr = plat->slave_addr; |
969 | if (plat->slave) | 841 | i2c->slave = plat->slave; |
970 | i2c->slave = plat->slave; | ||
971 | } | 842 | } |
972 | #endif | 843 | #endif |
973 | 844 | ||
diff --git a/include/linux/i2c-pxa.h b/include/linux/i2c-pxa.h index 5f3eaf802223..41dcdfe7f625 100644 --- a/include/linux/i2c-pxa.h +++ b/include/linux/i2c-pxa.h | |||
@@ -1,29 +1,6 @@ | |||
1 | #ifndef _LINUX_I2C_ALGO_PXA_H | 1 | #ifndef _LINUX_I2C_ALGO_PXA_H |
2 | #define _LINUX_I2C_ALGO_PXA_H | 2 | #define _LINUX_I2C_ALGO_PXA_H |
3 | 3 | ||
4 | struct i2c_eeprom_emu_watcher { | ||
5 | void (*write)(void *, unsigned int addr, unsigned char newval); | ||
6 | }; | ||
7 | |||
8 | struct i2c_eeprom_emu_watch { | ||
9 | struct list_head node; | ||
10 | unsigned int start; | ||
11 | unsigned int end; | ||
12 | struct i2c_eeprom_emu_watcher *ops; | ||
13 | void *data; | ||
14 | }; | ||
15 | |||
16 | #define I2C_EEPROM_EMU_SIZE (256) | ||
17 | |||
18 | struct i2c_eeprom_emu { | ||
19 | unsigned int size; | ||
20 | unsigned int ptr; | ||
21 | unsigned int seen_start; | ||
22 | struct list_head watch; | ||
23 | |||
24 | unsigned char bytes[I2C_EEPROM_EMU_SIZE]; | ||
25 | }; | ||
26 | |||
27 | typedef enum i2c_slave_event_e { | 4 | typedef enum i2c_slave_event_e { |
28 | I2C_SLAVE_EVENT_START_READ, | 5 | I2C_SLAVE_EVENT_START_READ, |
29 | I2C_SLAVE_EVENT_START_WRITE, | 6 | I2C_SLAVE_EVENT_START_WRITE, |
@@ -37,12 +14,4 @@ struct i2c_slave_client { | |||
37 | void (*write)(void *ptr, unsigned int val); | 14 | void (*write)(void *ptr, unsigned int val); |
38 | }; | 15 | }; |
39 | 16 | ||
40 | extern int i2c_eeprom_emu_addwatcher(struct i2c_eeprom_emu *, void *data, | ||
41 | unsigned int addr, unsigned int size, | ||
42 | struct i2c_eeprom_emu_watcher *); | ||
43 | |||
44 | extern void i2c_eeprom_emu_delwatcher(struct i2c_eeprom_emu *, void *data, struct i2c_eeprom_emu_watcher *watcher); | ||
45 | |||
46 | extern struct i2c_eeprom_emu *i2c_pxa_get_eeprom(void); | ||
47 | |||
48 | #endif /* _LINUX_I2C_ALGO_PXA_H */ | 17 | #endif /* _LINUX_I2C_ALGO_PXA_H */ |