Index: linux-3.18-rc3/arch/arm/mach-at91/board-dt-sam9.c =================================================================== --- linux-3.18-rc3.orig/arch/arm/mach-at91/board-dt-sam9.c 2014-11-02 17:01:51.000000000 -0600 +++ linux-3.18-rc3/arch/arm/mach-at91/board-dt-sam9.c 2014-11-03 15:27:22.831959257 -0600 @@ -25,6 +25,87 @@ #include "board.h" #include "generic.h" +#include + +uint8_t mts_id_eeprom[512]; + +EXPORT_SYMBOL(mts_id_eeprom); + +static void mts_id_eeprom_load(struct memory_accessor *macc, void *context) +{ + int tmp; + + memset(mts_id_eeprom, 0, sizeof(mts_id_eeprom)); + + tmp = macc->read(macc, mts_id_eeprom, 0, sizeof(mts_id_eeprom)); + if (tmp != sizeof(mts_id_eeprom)) { + printk(KERN_ERR "sam9x5: id eeprom read failed: %d\n", tmp); + } else { + printk(KERN_INFO "sam9x5: read %d bytes from id eeprom\n", tmp); + } +} + +struct mts_eeprom_callback id_eeprom_callback = { + .address = 0x56, + .index = -1, + .setup = mts_id_eeprom_load, +}; + +#ifdef CONFIG_MTS_NUM_ACCESSORY_PORTS +#define NUM_AP CONFIG_MTS_NUM_ACCESSORY_PORTS +#else +#define NUM_AP 0 +#endif + +#if NUM_AP > 0 + +uint8_t mts_ap_eeprom[NUM_AP][512]; + +EXPORT_SYMBOL(mts_ap_eeprom); + +static void mts_ap_eeprom_load(struct memory_accessor *macc, void *context) +{ + int tmp; + int* index = (int*)context; + + memset(mts_ap_eeprom[*index], 0, sizeof(mts_ap_eeprom[*index])); + + tmp = macc->read(macc, mts_ap_eeprom[*index], 0, sizeof(mts_ap_eeprom[*index])); + if (tmp != sizeof(mts_ap_eeprom[*index])) { + printk(KERN_INFO "sam9x5: ap%d eeprom read failed: %d\n", *index + 1, tmp); + } else { + printk(KERN_INFO "sam9x5: read %d bytes from ap%d eeprom\n", tmp, *index + 1); + } +} + +struct mts_eeprom_callback ap1_eeprom_callback = { + .address = 0x50, + .index = 0, + .setup = mts_ap_eeprom_load, +}; + +struct mts_eeprom_callback ap2_eeprom_callback = { + .address = 0x52, + .index = 1, + .setup = mts_ap_eeprom_load, +}; + +struct mts_eeprom_callback* mts_eeprom_callback_lookup[] = { + &id_eeprom_callback, + &ap1_eeprom_callback, + &ap2_eeprom_callback, + NULL +}; + +#else + +struct mts_eeprom_callback* mts_eeprom_callback_lookup[] = { + &id_eeprom_callback, + NULL +}; + +#endif + static const char *at91_dt_board_compat[] __initdata = { "atmel,at91sam9", NULL Index: linux-3.18-rc3/drivers/misc/eeprom/at24.c =================================================================== --- linux-3.18-rc3.orig/drivers/misc/eeprom/at24.c 2014-11-02 17:01:51.000000000 -0600 +++ linux-3.18-rc3/drivers/misc/eeprom/at24.c 2014-11-03 15:30:11.867964508 -0600 @@ -24,6 +24,8 @@ #include #include +#include + /* * I2C EEPROMs from most vendors are inexpensive and mostly interchangeable. * Differences between different vendor product lines (like Atmel AT24C or @@ -476,6 +478,23 @@ chip->page_size = be32_to_cpup(val); } } + +static void at24_get_setup(struct i2c_client *client, + struct at24_platform_data *chip) +{ + int i; + + for (i = 0; mts_eeprom_callback_lookup[i] != NULL; i++) { + if (mts_eeprom_callback_lookup[i]->address == client->addr) { + printk(KERN_INFO "%s: found a match for eeprom at %X\n", __func__, client->addr); + chip->setup = mts_eeprom_callback_lookup[i]->setup; + if (mts_eeprom_callback_lookup[i]->index > -1) { + chip->context = (void*)&mts_eeprom_callback_lookup[i]->index; + } + break; + } + } +} #else static void at24_get_ofdata(struct i2c_client *client, struct at24_platform_data *chip) @@ -508,12 +527,14 @@ * is recommended anyhow. */ chip.page_size = 1; + chip.setup = NULL; + chip.context = NULL; /* update chipdata if OF is present */ at24_get_ofdata(client, &chip); - chip.setup = NULL; - chip.context = NULL; + /* see if we have a setup callback */ + at24_get_setup(client, &chip); } if (!is_power_of_2(chip.byte_len)) Index: linux-3.18-rc3/include/linux/mts_at24.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.18-rc3/include/linux/mts_at24.h 2014-11-03 15:30:46.051965569 -0600 @@ -0,0 +1,14 @@ +#ifndef _LINUX_MTSAT24_H +#define _LINUX_MTSAT24_H + +#include + +struct mts_eeprom_callback { + unsigned short address; + int index; + void (*setup)(struct memory_accessor *, void *context); +}; + +extern struct mts_eeprom_callback* mts_eeprom_callback_lookup[]; + +#endif /* _LINUX_MTSAT24_H */