blob: 4ed0923e62ef15c258f278a8eb8e9fdb91fa8ea3 [file] [log] [blame]
Valentin Yakovenkov28a1fcc2009-10-26 18:49:06 -04001/*
2 * File: drivers/i2c/pca9564.c
3 * Based on: drivers/i2c/s3c44b0_i2c.c
4 * Author:
5 *
6 * Created: 2009-06-23
7 * Description: PCA9564 i2c bridge driver
8 *
9 * Modified:
10 * Copyright 2009 CJSC "NII STT", http://www.niistt.ru/
11 *
12 * Bugs:
13 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +020014 * SPDX-License-Identifier: GPL-2.0+
Simon Glasscb052ff2016-11-23 06:34:44 -070015 *
16 * NOTE: This driver should be converted to driver model before June 2017.
17 * Please see doc/driver-model/i2c-howto.txt for instructions.
Valentin Yakovenkov28a1fcc2009-10-26 18:49:06 -040018 */
19
20#include <common.h>
21#include <i2c.h>
22#include <pca9564.h>
23#include <asm/io.h>
24
25#define PCA_STA (CONFIG_PCA9564_BASE + 0)
26#define PCA_TO (CONFIG_PCA9564_BASE + 0)
27#define PCA_DAT (CONFIG_PCA9564_BASE + (1 << 2))
28#define PCA_ADR (CONFIG_PCA9564_BASE + (2 << 2))
29#define PCA_CON (CONFIG_PCA9564_BASE + (3 << 2))
30
31static unsigned char pca_read_reg(unsigned int reg)
32{
33 return readb((void *)reg);
34}
35
36static void pca_write_reg(unsigned int reg, unsigned char value)
37{
38 writeb(value, (void *)reg);
39}
40
41static int pca_wait_busy(void)
42{
43 unsigned int timeout = 10000;
44
45 while (!(pca_read_reg(PCA_CON) & PCA_CON_SI) && --timeout)
46 udelay(1);
47
48 if (timeout == 0)
49 debug("I2C timeout!\n");
50
51 debug("CON = 0x%02x, STA = 0x%02x\n", pca_read_reg(PCA_CON),
52 pca_read_reg(PCA_STA));
53
54 return timeout ? 0 : 1;
55}
56
57/*=====================================================================*/
58/* Public Functions */
59/*=====================================================================*/
60
61/*-----------------------------------------------------------------------
62 * Initialization
63 */
64void i2c_init(int speed, int slaveaddr)
65{
66 pca_write_reg(PCA_CON, PCA_CON_ENSIO | speed);
67}
68
69/*
70 * Probe the given I2C chip address. Returns 0 if a chip responded,
71 * not 0 on failure.
72 */
73
74int i2c_probe(uchar chip)
75{
76 unsigned char res;
77
78 pca_write_reg(PCA_CON, PCA_CON_STA | PCA_CON_ENSIO);
79 pca_wait_busy();
80
81 pca_write_reg(PCA_CON, PCA_CON_STA | PCA_CON_ENSIO);
82
83 pca_write_reg(PCA_DAT, (chip << 1) | 1);
84 res = pca_wait_busy();
85
86 if ((res == 0) && (pca_read_reg(PCA_STA) == 0x48))
87 res = 1;
88
89 pca_write_reg(PCA_CON, PCA_CON_STO | PCA_CON_ENSIO);
90
91 return res;
92}
93
94/*
95 * Read/Write interface:
96 * chip: I2C chip address, range 0..127
97 * addr: Memory (register) address within the chip
98 * alen: Number of bytes to use for addr (typically 1, 2 for larger
99 * memories, 0 for register type devices with only one
100 * register)
101 * buffer: Where to read/write the data
102 * len: How many bytes to read/write
103 *
104 * Returns: 0 on success, not 0 on failure
105 */
106int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
107{
108 int i;
109
110 pca_write_reg(PCA_CON, PCA_CON_ENSIO | PCA_CON_STA);
111 pca_wait_busy();
112
113 pca_write_reg(PCA_CON, PCA_CON_ENSIO);
114
115 pca_write_reg(PCA_DAT, (chip << 1));
116 pca_wait_busy();
117 pca_write_reg(PCA_CON, PCA_CON_ENSIO);
118
119 if (alen > 0) {
120 pca_write_reg(PCA_DAT, addr);
121 pca_wait_busy();
122 pca_write_reg(PCA_CON, PCA_CON_ENSIO);
123 }
124
125 pca_write_reg(PCA_CON, PCA_CON_ENSIO | PCA_CON_STO);
126
127 udelay(500);
128
129 pca_write_reg(PCA_CON, PCA_CON_ENSIO | PCA_CON_STA);
130 pca_wait_busy();
131 pca_write_reg(PCA_CON, PCA_CON_ENSIO);
132
133 pca_write_reg(PCA_DAT, (chip << 1) | 1);
134 pca_wait_busy();
135
136 for (i = 0; i < len; ++i) {
137 if (i == len - 1)
138 pca_write_reg(PCA_CON, PCA_CON_ENSIO);
139 else
140 pca_write_reg(PCA_CON, PCA_CON_ENSIO | PCA_CON_AA);
141
142 pca_wait_busy();
143 buffer[i] = pca_read_reg(PCA_DAT);
144
145 }
146
147 pca_write_reg(PCA_CON, PCA_CON_ENSIO | PCA_CON_STO);
148
149 return 0;
150}
151
152int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
153{
154 int i;
155
156 pca_write_reg(PCA_CON, PCA_CON_ENSIO | PCA_CON_STA);
157 pca_wait_busy();
158 pca_write_reg(PCA_CON, PCA_CON_ENSIO);
159
160 pca_write_reg(PCA_DAT, chip << 1);
161 pca_wait_busy();
162 pca_write_reg(PCA_CON, PCA_CON_ENSIO);
163
164 if (alen > 0) {
165 pca_write_reg(PCA_DAT, addr);
166 pca_wait_busy();
167 pca_write_reg(PCA_CON, PCA_CON_ENSIO);
168 }
169
170 for (i = 0; i < len; ++i) {
171 pca_write_reg(PCA_DAT, buffer[i]);
172 pca_wait_busy();
173 pca_write_reg(PCA_CON, PCA_CON_ENSIO);
174 }
175
176 pca_write_reg(PCA_CON, PCA_CON_STO | PCA_CON_ENSIO);
177
178 return 0;
179}