1// SPDX-License-Identifier: GPL-2.0
2#define USE_HW_I2C
3#ifdef USE_HW_I2C
4#include "ddk750_chip.h"
5#include "ddk750_reg.h"
6#include "ddk750_hwi2c.h"
7#include "ddk750_power.h"
8
9#define MAX_HWI2C_FIFO                  16
10#define HWI2C_WAIT_TIMEOUT              0xF0000
11
12int sm750_hw_i2c_init(unsigned char bus_speed_mode)
13{
14	unsigned int value;
15
16	/* Enable GPIO 30 & 31 as IIC clock & data */
17	value = peek32(GPIO_MUX);
18
19	value |= (GPIO_MUX_30 | GPIO_MUX_31);
20	poke32(GPIO_MUX, value);
21
22	/*
23	 * Enable Hardware I2C power.
24	 * TODO: Check if we need to enable GPIO power?
25	 */
26	sm750_enable_i2c(1);
27
28	/* Enable the I2C Controller and set the bus speed mode */
29	value = peek32(I2C_CTRL) & ~(I2C_CTRL_MODE | I2C_CTRL_EN);
30	if (bus_speed_mode)
31		value |= I2C_CTRL_MODE;
32	value |= I2C_CTRL_EN;
33	poke32(I2C_CTRL, value);
34
35	return 0;
36}
37
38void sm750_hw_i2c_close(void)
39{
40	unsigned int value;
41
42	/* Disable I2C controller */
43	value = peek32(I2C_CTRL) & ~I2C_CTRL_EN;
44	poke32(I2C_CTRL, value);
45
46	/* Disable I2C Power */
47	sm750_enable_i2c(0);
48
49	/* Set GPIO 30 & 31 back as GPIO pins */
50	value = peek32(GPIO_MUX);
51	value &= ~GPIO_MUX_30;
52	value &= ~GPIO_MUX_31;
53	poke32(GPIO_MUX, value);
54}
55
56static long hw_i2c_wait_tx_done(void)
57{
58	unsigned int timeout;
59
60	/* Wait until the transfer is completed. */
61	timeout = HWI2C_WAIT_TIMEOUT;
62	while (!(peek32(I2C_STATUS) & I2C_STATUS_TX) && (timeout != 0))
63		timeout--;
64
65	if (timeout == 0)
66		return -1;
67
68	return 0;
69}
70
71/*
72 *  This function writes data to the i2c slave device registers.
73 *
74 *  Parameters:
75 *      addr            - i2c Slave device address
76 *      length          - Total number of bytes to be written to the device
77 *      buf             - The buffer that contains the data to be written to the
78 *                     i2c device.
79 *
80 *  Return Value:
81 *      Total number of bytes those are actually written.
82 */
83static unsigned int hw_i2c_write_data(unsigned char addr,
84				      unsigned int length,
85				      unsigned char *buf)
86{
87	unsigned char count, i;
88	unsigned int total_bytes = 0;
89
90	/* Set the Device Address */
91	poke32(I2C_SLAVE_ADDRESS, addr & ~0x01);
92
93	/*
94	 * Write data.
95	 * Note:
96	 *      Only 16 byte can be accessed per i2c start instruction.
97	 */
98	do {
99		/*
100		 * Reset I2C by writing 0 to I2C_RESET register to
101		 * clear the previous status.
102		 */
103		poke32(I2C_RESET, 0);
104
105		/* Set the number of bytes to be written */
106		if (length < MAX_HWI2C_FIFO)
107			count = length - 1;
108		else
109			count = MAX_HWI2C_FIFO - 1;
110		poke32(I2C_BYTE_COUNT, count);
111
112		/* Move the data to the I2C data register */
113		for (i = 0; i <= count; i++)
114			poke32(I2C_DATA0 + i, *buf++);
115
116		/* Start the I2C */
117		poke32(I2C_CTRL, peek32(I2C_CTRL) | I2C_CTRL_CTRL);
118
119		/* Wait until the transfer is completed. */
120		if (hw_i2c_wait_tx_done() != 0)
121			break;
122
123		/* Subtract length */
124		length -= (count + 1);
125
126		/* Total byte written */
127		total_bytes += (count + 1);
128
129	} while (length > 0);
130
131	return total_bytes;
132}
133
134/*
135 *  This function reads data from the slave device and stores them
136 *  in the given buffer
137 *
138 *  Parameters:
139 *      addr            - i2c Slave device address
140 *      length          - Total number of bytes to be read
141 *      buf             - Pointer to a buffer to be filled with the data read
142 *                     from the slave device. It has to be the same size as the
143 *                     length to make sure that it can keep all the data read.
144 *
145 *  Return Value:
146 *      Total number of actual bytes read from the slave device
147 */
148static unsigned int hw_i2c_read_data(unsigned char addr,
149				     unsigned int length,
150				     unsigned char *buf)
151{
152	unsigned char count, i;
153	unsigned int total_bytes = 0;
154
155	/* Set the Device Address */
156	poke32(I2C_SLAVE_ADDRESS, addr | 0x01);
157
158	/*
159	 * Read data and save them to the buffer.
160	 * Note:
161	 *      Only 16 byte can be accessed per i2c start instruction.
162	 */
163	do {
164		/*
165		 * Reset I2C by writing 0 to I2C_RESET register to
166		 * clear all the status.
167		 */
168		poke32(I2C_RESET, 0);
169
170		/* Set the number of bytes to be read */
171		if (length <= MAX_HWI2C_FIFO)
172			count = length - 1;
173		else
174			count = MAX_HWI2C_FIFO - 1;
175		poke32(I2C_BYTE_COUNT, count);
176
177		/* Start the I2C */
178		poke32(I2C_CTRL, peek32(I2C_CTRL) | I2C_CTRL_CTRL);
179
180		/* Wait until transaction done. */
181		if (hw_i2c_wait_tx_done() != 0)
182			break;
183
184		/* Save the data to the given buffer */
185		for (i = 0; i <= count; i++)
186			*buf++ = peek32(I2C_DATA0 + i);
187
188		/* Subtract length by 16 */
189		length -= (count + 1);
190
191		/* Number of bytes read. */
192		total_bytes += (count + 1);
193
194	} while (length > 0);
195
196	return total_bytes;
197}
198
199/*
200 *  This function reads the slave device's register
201 *
202 *  Parameters:
203 *      deviceAddress   - i2c Slave device address which register
204 *                        to be read from
205 *      registerIndex   - Slave device's register to be read
206 *
207 *  Return Value:
208 *      Register value
209 */
210unsigned char sm750_hw_i2c_read_reg(unsigned char addr, unsigned char reg)
211{
212	unsigned char value = 0xFF;
213
214	if (hw_i2c_write_data(addr, 1, &reg) == 1)
215		hw_i2c_read_data(addr, 1, &value);
216
217	return value;
218}
219
220/*
221 *  This function writes a value to the slave device's register
222 *
223 *  Parameters:
224 *      deviceAddress   - i2c Slave device address which register
225 *                        to be written
226 *      registerIndex   - Slave device's register to be written
227 *      data            - Data to be written to the register
228 *
229 *  Result:
230 *          0   - Success
231 *         -1   - Fail
232 */
233int sm750_hw_i2c_write_reg(unsigned char addr,
234			   unsigned char reg,
235			   unsigned char data)
236{
237	unsigned char value[2];
238
239	value[0] = reg;
240	value[1] = data;
241	if (hw_i2c_write_data(addr, 2, value) == 2)
242		return 0;
243
244	return -1;
245}
246
247#endif
248