1*473c88f9SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2*473c88f9SBruce Richardson * Copyright(c) 2010-2019 Intel Corporation
3*473c88f9SBruce Richardson */
4*473c88f9SBruce Richardson
5*473c88f9SBruce Richardson #include "opae_osdep.h"
6*473c88f9SBruce Richardson #include "opae_i2c.h"
7*473c88f9SBruce Richardson #include "opae_at24_eeprom.h"
8*473c88f9SBruce Richardson
9*473c88f9SBruce Richardson #define AT24_READ_RETRY 10
10*473c88f9SBruce Richardson
at24_eeprom_read_and_try(struct altera_i2c_dev * dev,unsigned int slave_addr,u32 offset,u8 * buf,u32 len)11*473c88f9SBruce Richardson static int at24_eeprom_read_and_try(struct altera_i2c_dev *dev,
12*473c88f9SBruce Richardson unsigned int slave_addr,
13*473c88f9SBruce Richardson u32 offset, u8 *buf, u32 len)
14*473c88f9SBruce Richardson {
15*473c88f9SBruce Richardson int i;
16*473c88f9SBruce Richardson int ret = 0;
17*473c88f9SBruce Richardson
18*473c88f9SBruce Richardson for (i = 0; i < AT24_READ_RETRY; i++) {
19*473c88f9SBruce Richardson ret = i2c_read16(dev, slave_addr, offset,
20*473c88f9SBruce Richardson buf, len);
21*473c88f9SBruce Richardson if (ret == 0)
22*473c88f9SBruce Richardson break;
23*473c88f9SBruce Richardson
24*473c88f9SBruce Richardson opae_udelay(100);
25*473c88f9SBruce Richardson }
26*473c88f9SBruce Richardson
27*473c88f9SBruce Richardson return ret;
28*473c88f9SBruce Richardson }
29*473c88f9SBruce Richardson
at24_eeprom_read(struct altera_i2c_dev * dev,unsigned int slave_addr,u32 offset,u8 * buf,int count)30*473c88f9SBruce Richardson int at24_eeprom_read(struct altera_i2c_dev *dev, unsigned int slave_addr,
31*473c88f9SBruce Richardson u32 offset, u8 *buf, int count)
32*473c88f9SBruce Richardson {
33*473c88f9SBruce Richardson int len;
34*473c88f9SBruce Richardson int status;
35*473c88f9SBruce Richardson int read_count = 0;
36*473c88f9SBruce Richardson
37*473c88f9SBruce Richardson if (!count)
38*473c88f9SBruce Richardson return count;
39*473c88f9SBruce Richardson
40*473c88f9SBruce Richardson if (count > AT24C512_IO_LIMIT)
41*473c88f9SBruce Richardson len = AT24C512_IO_LIMIT;
42*473c88f9SBruce Richardson else
43*473c88f9SBruce Richardson len = count;
44*473c88f9SBruce Richardson
45*473c88f9SBruce Richardson while (count) {
46*473c88f9SBruce Richardson status = at24_eeprom_read_and_try(dev, slave_addr, offset,
47*473c88f9SBruce Richardson buf, len);
48*473c88f9SBruce Richardson if (status)
49*473c88f9SBruce Richardson break;
50*473c88f9SBruce Richardson
51*473c88f9SBruce Richardson buf += len;
52*473c88f9SBruce Richardson offset += len;
53*473c88f9SBruce Richardson count -= len;
54*473c88f9SBruce Richardson read_count += len;
55*473c88f9SBruce Richardson }
56*473c88f9SBruce Richardson
57*473c88f9SBruce Richardson return read_count;
58*473c88f9SBruce Richardson }
59*473c88f9SBruce Richardson
at24_eeprom_write(struct altera_i2c_dev * dev,unsigned int slave_addr,u32 offset,u8 * buf,int count)60*473c88f9SBruce Richardson int at24_eeprom_write(struct altera_i2c_dev *dev, unsigned int slave_addr,
61*473c88f9SBruce Richardson u32 offset, u8 *buf, int count)
62*473c88f9SBruce Richardson {
63*473c88f9SBruce Richardson int len;
64*473c88f9SBruce Richardson int status;
65*473c88f9SBruce Richardson int write_count = 0;
66*473c88f9SBruce Richardson
67*473c88f9SBruce Richardson if (!count)
68*473c88f9SBruce Richardson return count;
69*473c88f9SBruce Richardson
70*473c88f9SBruce Richardson if (count > AT24C512_PAGE_SIZE)
71*473c88f9SBruce Richardson len = AT24C512_PAGE_SIZE;
72*473c88f9SBruce Richardson else
73*473c88f9SBruce Richardson len = count;
74*473c88f9SBruce Richardson
75*473c88f9SBruce Richardson while (count) {
76*473c88f9SBruce Richardson status = i2c_write16(dev, slave_addr, offset, buf, len);
77*473c88f9SBruce Richardson if (status)
78*473c88f9SBruce Richardson break;
79*473c88f9SBruce Richardson
80*473c88f9SBruce Richardson buf += len;
81*473c88f9SBruce Richardson offset += len;
82*473c88f9SBruce Richardson count -= len;
83*473c88f9SBruce Richardson write_count += len;
84*473c88f9SBruce Richardson }
85*473c88f9SBruce Richardson
86*473c88f9SBruce Richardson return write_count;
87*473c88f9SBruce Richardson }
88