-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathi2c-eeprom.c
93 lines (70 loc) · 2.18 KB
/
i2c-eeprom.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// Copyright 2009 Segher Boessenkool <[email protected]>
// Licensed under the terms of the GNU GPL, version 2
// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
#include <stdlib.h>
#include "types.h"
#include "platform.h"
#include "i2c.h"
#include <stdio.h>
struct i2c_eeprom {
struct i2c_device dev;
u8 *data;
u32 size; // in bytes
void *file_cookie;
u8 address; // i2c bus address
u32 current; // data pointer
int address_bytes_left;
};
static int i2c_eeprom_address(struct i2c_device *dev, u8 address)
{
struct i2c_eeprom *eeprom = subtype(struct i2c_eeprom, dev, dev);
// XXX: for 24c04 only
if ((address & 0xfc) != eeprom->address)
return 1;
if ((address & 1) == 0) {
// XXX: for 24c04 only
eeprom->address_bytes_left = 1;
eeprom->current = (address >> 1) & 1;
}
return 0;
}
static int i2c_eeprom_write(struct i2c_device *dev, u8 data)
{
struct i2c_eeprom *eeprom = subtype(struct i2c_eeprom, dev, dev);
if (eeprom->address_bytes_left) {
eeprom->address_bytes_left--;
eeprom->current = (eeprom->current << 8) | data;
} else {
eeprom->data[eeprom->current] = data;
//debug("EEPROM: wrote %02x @ %02x, writing to file\n", data, eeprom->current);
save_eeprom(eeprom->file_cookie, eeprom->data, eeprom->size);
// XXX: for 24c04 only
eeprom->current = (eeprom->current & ~0x0f) |
((eeprom->current + 1) & 0x0f);
}
return 0;
}
static u8 i2c_eeprom_read(struct i2c_device *dev)
{
struct i2c_eeprom *eeprom = subtype(struct i2c_eeprom, dev, dev);
u8 data = eeprom->data[eeprom->current];
// XXX: for 24c04 only
eeprom->current = (eeprom->current + 1) & 0x1ff;
return data;
}
void i2c_eeprom_create(struct i2c_bus *bus, u32 size, u8 address,
const char *file_name)
{
struct i2c_eeprom *eeprom = malloc(sizeof *eeprom);
eeprom->dev.next = bus->devices;
bus->devices = &eeprom->dev;
eeprom->dev.address = i2c_eeprom_address;
eeprom->dev.write = i2c_eeprom_write;
eeprom->dev.read = i2c_eeprom_read;
eeprom->dev.read_ack = 0;
eeprom->data = calloc(size, 1);
eeprom->size = size;
eeprom->file_cookie = open_eeprom(file_name, eeprom->data, size);
eeprom->address = address;
eeprom->current = 0;
}