xref: /freebsd/sys/dev/ixl/ixl_pf_i2c.c (revision cb6b8299fdda0ccd5c9c9b0d29cd9c005f6d780b)
1*cb6b8299SEric Joyner /******************************************************************************
2*cb6b8299SEric Joyner 
3*cb6b8299SEric Joyner   Copyright (c) 2013-2015, Intel Corporation
4*cb6b8299SEric Joyner   All rights reserved.
5*cb6b8299SEric Joyner 
6*cb6b8299SEric Joyner   Redistribution and use in source and binary forms, with or without
7*cb6b8299SEric Joyner   modification, are permitted provided that the following conditions are met:
8*cb6b8299SEric Joyner 
9*cb6b8299SEric Joyner    1. Redistributions of source code must retain the above copyright notice,
10*cb6b8299SEric Joyner       this list of conditions and the following disclaimer.
11*cb6b8299SEric Joyner 
12*cb6b8299SEric Joyner    2. Redistributions in binary form must reproduce the above copyright
13*cb6b8299SEric Joyner       notice, this list of conditions and the following disclaimer in the
14*cb6b8299SEric Joyner       documentation and/or other materials provided with the distribution.
15*cb6b8299SEric Joyner 
16*cb6b8299SEric Joyner    3. Neither the name of the Intel Corporation nor the names of its
17*cb6b8299SEric Joyner       contributors may be used to endorse or promote products derived from
18*cb6b8299SEric Joyner       this software without specific prior written permission.
19*cb6b8299SEric Joyner 
20*cb6b8299SEric Joyner   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21*cb6b8299SEric Joyner   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22*cb6b8299SEric Joyner   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23*cb6b8299SEric Joyner   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24*cb6b8299SEric Joyner   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25*cb6b8299SEric Joyner   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26*cb6b8299SEric Joyner   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27*cb6b8299SEric Joyner   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28*cb6b8299SEric Joyner   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29*cb6b8299SEric Joyner   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30*cb6b8299SEric Joyner   POSSIBILITY OF SUCH DAMAGE.
31*cb6b8299SEric Joyner 
32*cb6b8299SEric Joyner ******************************************************************************/
33*cb6b8299SEric Joyner /*$FreeBSD$*/
34*cb6b8299SEric Joyner 
35*cb6b8299SEric Joyner #include "ixl_pf.h"
36*cb6b8299SEric Joyner 
37*cb6b8299SEric Joyner #define IXL_I2C_T_RISE		1
38*cb6b8299SEric Joyner #define IXL_I2C_T_FALL		1
39*cb6b8299SEric Joyner #define IXL_I2C_T_SU_DATA	1
40*cb6b8299SEric Joyner #define IXL_I2C_T_SU_STA	5
41*cb6b8299SEric Joyner #define IXL_I2C_T_SU_STO	4
42*cb6b8299SEric Joyner #define IXL_I2C_T_HD_STA	4
43*cb6b8299SEric Joyner #define IXL_I2C_T_LOW		5
44*cb6b8299SEric Joyner #define IXL_I2C_T_HIGH		4
45*cb6b8299SEric Joyner #define IXL_I2C_T_BUF		5
46*cb6b8299SEric Joyner #define IXL_I2C_CLOCK_STRETCHING_TIMEOUT 500
47*cb6b8299SEric Joyner 
48*cb6b8299SEric Joyner #define IXL_I2C_REG(_hw)	\
49*cb6b8299SEric Joyner     I40E_GLGEN_I2CPARAMS(((struct i40e_osdep *)(_hw)->back)->i2c_intfc_num)
50*cb6b8299SEric Joyner 
51*cb6b8299SEric Joyner 
52*cb6b8299SEric Joyner static s32	ixl_set_i2c_data(struct ixl_pf *pf, u32 *i2cctl, bool data);
53*cb6b8299SEric Joyner static bool	ixl_get_i2c_data(struct ixl_pf *pf, u32 *i2cctl);
54*cb6b8299SEric Joyner static void	ixl_raise_i2c_clk(struct ixl_pf *pf, u32 *i2cctl);
55*cb6b8299SEric Joyner static void	ixl_lower_i2c_clk(struct ixl_pf *pf, u32 *i2cctl);
56*cb6b8299SEric Joyner static s32	ixl_clock_out_i2c_bit(struct ixl_pf *pf, bool data);
57*cb6b8299SEric Joyner static s32	ixl_get_i2c_ack(struct ixl_pf *pf);
58*cb6b8299SEric Joyner static s32	ixl_clock_out_i2c_byte(struct ixl_pf *pf, u8 data);
59*cb6b8299SEric Joyner static s32	ixl_clock_in_i2c_bit(struct ixl_pf *pf, bool *data);
60*cb6b8299SEric Joyner static s32	ixl_clock_in_i2c_byte(struct ixl_pf *pf, u8 *data);
61*cb6b8299SEric Joyner static void 	ixl_i2c_bus_clear(struct ixl_pf *pf);
62*cb6b8299SEric Joyner static void	ixl_i2c_start(struct ixl_pf *pf);
63*cb6b8299SEric Joyner static void	ixl_i2c_stop(struct ixl_pf *pf);
64*cb6b8299SEric Joyner 
65*cb6b8299SEric Joyner /**
66*cb6b8299SEric Joyner  *  ixl_i2c_bus_clear - Clears the I2C bus
67*cb6b8299SEric Joyner  *  @hw: pointer to hardware structure
68*cb6b8299SEric Joyner  *
69*cb6b8299SEric Joyner  *  Clears the I2C bus by sending nine clock pulses.
70*cb6b8299SEric Joyner  *  Used when data line is stuck low.
71*cb6b8299SEric Joyner  **/
72*cb6b8299SEric Joyner static void
73*cb6b8299SEric Joyner ixl_i2c_bus_clear(struct ixl_pf *pf)
74*cb6b8299SEric Joyner {
75*cb6b8299SEric Joyner 	struct i40e_hw *hw = &pf->hw;
76*cb6b8299SEric Joyner 	u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
77*cb6b8299SEric Joyner 	u32 i;
78*cb6b8299SEric Joyner 
79*cb6b8299SEric Joyner 	DEBUGFUNC("ixl_i2c_bus_clear");
80*cb6b8299SEric Joyner 
81*cb6b8299SEric Joyner 	ixl_i2c_start(pf);
82*cb6b8299SEric Joyner 
83*cb6b8299SEric Joyner 	ixl_set_i2c_data(pf, &i2cctl, 1);
84*cb6b8299SEric Joyner 
85*cb6b8299SEric Joyner 	for (i = 0; i < 9; i++) {
86*cb6b8299SEric Joyner 		ixl_raise_i2c_clk(pf, &i2cctl);
87*cb6b8299SEric Joyner 
88*cb6b8299SEric Joyner 		/* Min high period of clock is 4us */
89*cb6b8299SEric Joyner 		i40e_usec_delay(IXL_I2C_T_HIGH);
90*cb6b8299SEric Joyner 
91*cb6b8299SEric Joyner 		ixl_lower_i2c_clk(pf, &i2cctl);
92*cb6b8299SEric Joyner 
93*cb6b8299SEric Joyner 		/* Min low period of clock is 4.7us*/
94*cb6b8299SEric Joyner 		i40e_usec_delay(IXL_I2C_T_LOW);
95*cb6b8299SEric Joyner 	}
96*cb6b8299SEric Joyner 
97*cb6b8299SEric Joyner 	ixl_i2c_start(pf);
98*cb6b8299SEric Joyner 
99*cb6b8299SEric Joyner 	/* Put the i2c bus back to default state */
100*cb6b8299SEric Joyner 	ixl_i2c_stop(pf);
101*cb6b8299SEric Joyner }
102*cb6b8299SEric Joyner 
103*cb6b8299SEric Joyner /**
104*cb6b8299SEric Joyner  *  ixl_i2c_stop - Sets I2C stop condition
105*cb6b8299SEric Joyner  *  @hw: pointer to hardware structure
106*cb6b8299SEric Joyner  *
107*cb6b8299SEric Joyner  *  Sets I2C stop condition (Low -> High on SDA while SCL is High)
108*cb6b8299SEric Joyner  **/
109*cb6b8299SEric Joyner static void
110*cb6b8299SEric Joyner ixl_i2c_stop(struct ixl_pf *pf)
111*cb6b8299SEric Joyner {
112*cb6b8299SEric Joyner 	struct i40e_hw *hw = &pf->hw;
113*cb6b8299SEric Joyner 	u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
114*cb6b8299SEric Joyner 
115*cb6b8299SEric Joyner 	DEBUGFUNC("ixl_i2c_stop");
116*cb6b8299SEric Joyner 
117*cb6b8299SEric Joyner 	/* Stop condition must begin with data low and clock high */
118*cb6b8299SEric Joyner 	ixl_set_i2c_data(pf, &i2cctl, 0);
119*cb6b8299SEric Joyner 	ixl_raise_i2c_clk(pf, &i2cctl);
120*cb6b8299SEric Joyner 
121*cb6b8299SEric Joyner 	/* Setup time for stop condition (4us) */
122*cb6b8299SEric Joyner 	i40e_usec_delay(IXL_I2C_T_SU_STO);
123*cb6b8299SEric Joyner 
124*cb6b8299SEric Joyner 	ixl_set_i2c_data(pf, &i2cctl, 1);
125*cb6b8299SEric Joyner 
126*cb6b8299SEric Joyner 	/* bus free time between stop and start (4.7us)*/
127*cb6b8299SEric Joyner 	i40e_usec_delay(IXL_I2C_T_BUF);
128*cb6b8299SEric Joyner }
129*cb6b8299SEric Joyner 
130*cb6b8299SEric Joyner /**
131*cb6b8299SEric Joyner  *  ixl_clock_in_i2c_byte - Clocks in one byte via I2C
132*cb6b8299SEric Joyner  *  @hw: pointer to hardware structure
133*cb6b8299SEric Joyner  *  @data: data byte to clock in
134*cb6b8299SEric Joyner  *
135*cb6b8299SEric Joyner  *  Clocks in one byte data via I2C data/clock
136*cb6b8299SEric Joyner  **/
137*cb6b8299SEric Joyner static s32
138*cb6b8299SEric Joyner ixl_clock_in_i2c_byte(struct ixl_pf *pf, u8 *data)
139*cb6b8299SEric Joyner {
140*cb6b8299SEric Joyner 	s32 i;
141*cb6b8299SEric Joyner 	bool bit = 0;
142*cb6b8299SEric Joyner 
143*cb6b8299SEric Joyner 	DEBUGFUNC("ixl_clock_in_i2c_byte");
144*cb6b8299SEric Joyner 
145*cb6b8299SEric Joyner 	for (i = 7; i >= 0; i--) {
146*cb6b8299SEric Joyner 		ixl_clock_in_i2c_bit(pf, &bit);
147*cb6b8299SEric Joyner 		*data |= bit << i;
148*cb6b8299SEric Joyner 	}
149*cb6b8299SEric Joyner 
150*cb6b8299SEric Joyner 	return I40E_SUCCESS;
151*cb6b8299SEric Joyner }
152*cb6b8299SEric Joyner 
153*cb6b8299SEric Joyner /**
154*cb6b8299SEric Joyner  *  ixl_clock_in_i2c_bit - Clocks in one bit via I2C data/clock
155*cb6b8299SEric Joyner  *  @hw: pointer to hardware structure
156*cb6b8299SEric Joyner  *  @data: read data value
157*cb6b8299SEric Joyner  *
158*cb6b8299SEric Joyner  *  Clocks in one bit via I2C data/clock
159*cb6b8299SEric Joyner  **/
160*cb6b8299SEric Joyner static s32
161*cb6b8299SEric Joyner ixl_clock_in_i2c_bit(struct ixl_pf *pf, bool *data)
162*cb6b8299SEric Joyner {
163*cb6b8299SEric Joyner 	struct i40e_hw *hw = &pf->hw;
164*cb6b8299SEric Joyner 	u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
165*cb6b8299SEric Joyner 
166*cb6b8299SEric Joyner 	DEBUGFUNC("ixl_clock_in_i2c_bit");
167*cb6b8299SEric Joyner 
168*cb6b8299SEric Joyner 	ixl_raise_i2c_clk(pf, &i2cctl);
169*cb6b8299SEric Joyner 
170*cb6b8299SEric Joyner 	/* Minimum high period of clock is 4us */
171*cb6b8299SEric Joyner 	i40e_usec_delay(IXL_I2C_T_HIGH);
172*cb6b8299SEric Joyner 
173*cb6b8299SEric Joyner 	i2cctl = rd32(hw, IXL_I2C_REG(hw));
174*cb6b8299SEric Joyner 	i2cctl |= I40E_GLGEN_I2CPARAMS_DATA_OE_N_MASK;
175*cb6b8299SEric Joyner 	wr32(hw, IXL_I2C_REG(hw), i2cctl);
176*cb6b8299SEric Joyner 	ixl_flush(hw);
177*cb6b8299SEric Joyner 
178*cb6b8299SEric Joyner 	i2cctl = rd32(hw, IXL_I2C_REG(hw));
179*cb6b8299SEric Joyner 	*data = ixl_get_i2c_data(pf, &i2cctl);
180*cb6b8299SEric Joyner 
181*cb6b8299SEric Joyner 	ixl_lower_i2c_clk(pf, &i2cctl);
182*cb6b8299SEric Joyner 
183*cb6b8299SEric Joyner 	/* Minimum low period of clock is 4.7 us */
184*cb6b8299SEric Joyner 	i40e_usec_delay(IXL_I2C_T_LOW);
185*cb6b8299SEric Joyner 
186*cb6b8299SEric Joyner 	return I40E_SUCCESS;
187*cb6b8299SEric Joyner }
188*cb6b8299SEric Joyner 
189*cb6b8299SEric Joyner /**
190*cb6b8299SEric Joyner  *  ixl_get_i2c_ack - Polls for I2C ACK
191*cb6b8299SEric Joyner  *  @hw: pointer to hardware structure
192*cb6b8299SEric Joyner  *
193*cb6b8299SEric Joyner  *  Clocks in/out one bit via I2C data/clock
194*cb6b8299SEric Joyner  **/
195*cb6b8299SEric Joyner static s32
196*cb6b8299SEric Joyner ixl_get_i2c_ack(struct ixl_pf *pf)
197*cb6b8299SEric Joyner {
198*cb6b8299SEric Joyner 	struct i40e_hw *hw = &pf->hw;
199*cb6b8299SEric Joyner 	s32 status = I40E_SUCCESS;
200*cb6b8299SEric Joyner 	u32 i = 0;
201*cb6b8299SEric Joyner 	u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
202*cb6b8299SEric Joyner 	u32 timeout = 10;
203*cb6b8299SEric Joyner 	bool ack = 1;
204*cb6b8299SEric Joyner 
205*cb6b8299SEric Joyner 	ixl_raise_i2c_clk(pf, &i2cctl);
206*cb6b8299SEric Joyner 
207*cb6b8299SEric Joyner 	/* Minimum high period of clock is 4us */
208*cb6b8299SEric Joyner 	i40e_usec_delay(IXL_I2C_T_HIGH);
209*cb6b8299SEric Joyner 
210*cb6b8299SEric Joyner 	i2cctl = rd32(hw, IXL_I2C_REG(hw));
211*cb6b8299SEric Joyner 	i2cctl |= I40E_GLGEN_I2CPARAMS_DATA_OE_N_MASK;
212*cb6b8299SEric Joyner 	wr32(hw, IXL_I2C_REG(hw), i2cctl);
213*cb6b8299SEric Joyner 	ixl_flush(hw);
214*cb6b8299SEric Joyner 
215*cb6b8299SEric Joyner 	/* Poll for ACK.  Note that ACK in I2C spec is
216*cb6b8299SEric Joyner 	 * transition from 1 to 0 */
217*cb6b8299SEric Joyner 	for (i = 0; i < timeout; i++) {
218*cb6b8299SEric Joyner 		i2cctl = rd32(hw, IXL_I2C_REG(hw));
219*cb6b8299SEric Joyner 		ack = ixl_get_i2c_data(pf, &i2cctl);
220*cb6b8299SEric Joyner 
221*cb6b8299SEric Joyner 		i40e_usec_delay(1);
222*cb6b8299SEric Joyner 		if (!ack)
223*cb6b8299SEric Joyner 			break;
224*cb6b8299SEric Joyner 	}
225*cb6b8299SEric Joyner 
226*cb6b8299SEric Joyner 	if (ack) {
227*cb6b8299SEric Joyner 		ixl_dbg(pf, IXL_DBG_I2C, "I2C ack was not received.\n");
228*cb6b8299SEric Joyner 		status = I40E_ERR_PHY;
229*cb6b8299SEric Joyner 	}
230*cb6b8299SEric Joyner 
231*cb6b8299SEric Joyner 	ixl_lower_i2c_clk(pf, &i2cctl);
232*cb6b8299SEric Joyner 
233*cb6b8299SEric Joyner 	/* Minimum low period of clock is 4.7 us */
234*cb6b8299SEric Joyner 	i40e_usec_delay(IXL_I2C_T_LOW);
235*cb6b8299SEric Joyner 
236*cb6b8299SEric Joyner 	return status;
237*cb6b8299SEric Joyner }
238*cb6b8299SEric Joyner 
239*cb6b8299SEric Joyner /**
240*cb6b8299SEric Joyner  *  ixl_clock_out_i2c_bit - Clocks in/out one bit via I2C data/clock
241*cb6b8299SEric Joyner  *  @hw: pointer to hardware structure
242*cb6b8299SEric Joyner  *  @data: data value to write
243*cb6b8299SEric Joyner  *
244*cb6b8299SEric Joyner  *  Clocks out one bit via I2C data/clock
245*cb6b8299SEric Joyner  **/
246*cb6b8299SEric Joyner static s32
247*cb6b8299SEric Joyner ixl_clock_out_i2c_bit(struct ixl_pf *pf, bool data)
248*cb6b8299SEric Joyner {
249*cb6b8299SEric Joyner 	struct i40e_hw *hw = &pf->hw;
250*cb6b8299SEric Joyner 	s32 status;
251*cb6b8299SEric Joyner 	u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
252*cb6b8299SEric Joyner 
253*cb6b8299SEric Joyner 	status = ixl_set_i2c_data(pf, &i2cctl, data);
254*cb6b8299SEric Joyner 	if (status == I40E_SUCCESS) {
255*cb6b8299SEric Joyner 		ixl_raise_i2c_clk(pf, &i2cctl);
256*cb6b8299SEric Joyner 
257*cb6b8299SEric Joyner 		/* Minimum high period of clock is 4us */
258*cb6b8299SEric Joyner 		i40e_usec_delay(IXL_I2C_T_HIGH);
259*cb6b8299SEric Joyner 
260*cb6b8299SEric Joyner 		ixl_lower_i2c_clk(pf, &i2cctl);
261*cb6b8299SEric Joyner 
262*cb6b8299SEric Joyner 		/* Minimum low period of clock is 4.7 us.
263*cb6b8299SEric Joyner 		 * This also takes care of the data hold time.
264*cb6b8299SEric Joyner 		 */
265*cb6b8299SEric Joyner 		i40e_usec_delay(IXL_I2C_T_LOW);
266*cb6b8299SEric Joyner 	} else {
267*cb6b8299SEric Joyner 		status = I40E_ERR_PHY;
268*cb6b8299SEric Joyner 		ixl_dbg(pf, IXL_DBG_I2C, "I2C data was not set to %#x\n", data);
269*cb6b8299SEric Joyner 	}
270*cb6b8299SEric Joyner 
271*cb6b8299SEric Joyner 	return status;
272*cb6b8299SEric Joyner }
273*cb6b8299SEric Joyner 
274*cb6b8299SEric Joyner /**
275*cb6b8299SEric Joyner  *  ixl_clock_out_i2c_byte - Clocks out one byte via I2C
276*cb6b8299SEric Joyner  *  @hw: pointer to hardware structure
277*cb6b8299SEric Joyner  *  @data: data byte clocked out
278*cb6b8299SEric Joyner  *
279*cb6b8299SEric Joyner  *  Clocks out one byte data via I2C data/clock
280*cb6b8299SEric Joyner  **/
281*cb6b8299SEric Joyner static s32
282*cb6b8299SEric Joyner ixl_clock_out_i2c_byte(struct ixl_pf *pf, u8 data)
283*cb6b8299SEric Joyner {
284*cb6b8299SEric Joyner 	struct i40e_hw *hw = &pf->hw;
285*cb6b8299SEric Joyner 	s32 status = I40E_SUCCESS;
286*cb6b8299SEric Joyner 	s32 i;
287*cb6b8299SEric Joyner 	u32 i2cctl;
288*cb6b8299SEric Joyner 	bool bit;
289*cb6b8299SEric Joyner 
290*cb6b8299SEric Joyner 	DEBUGFUNC("ixl_clock_out_i2c_byte");
291*cb6b8299SEric Joyner 
292*cb6b8299SEric Joyner 	for (i = 7; i >= 0; i--) {
293*cb6b8299SEric Joyner 		bit = (data >> i) & 0x1;
294*cb6b8299SEric Joyner 		status = ixl_clock_out_i2c_bit(pf, bit);
295*cb6b8299SEric Joyner 
296*cb6b8299SEric Joyner 		if (status != I40E_SUCCESS)
297*cb6b8299SEric Joyner 			break;
298*cb6b8299SEric Joyner 	}
299*cb6b8299SEric Joyner 
300*cb6b8299SEric Joyner 	/* Release SDA line (set high) */
301*cb6b8299SEric Joyner 	i2cctl = rd32(hw, IXL_I2C_REG(hw));
302*cb6b8299SEric Joyner 	i2cctl |= I40E_GLGEN_I2CPARAMS_DATA_OUT_MASK;
303*cb6b8299SEric Joyner 	i2cctl &= ~(I40E_GLGEN_I2CPARAMS_DATA_OE_N_MASK);
304*cb6b8299SEric Joyner 	wr32(hw, IXL_I2C_REG(hw), i2cctl);
305*cb6b8299SEric Joyner 	ixl_flush(hw);
306*cb6b8299SEric Joyner 
307*cb6b8299SEric Joyner 	return status;
308*cb6b8299SEric Joyner }
309*cb6b8299SEric Joyner 
310*cb6b8299SEric Joyner /**
311*cb6b8299SEric Joyner  *  ixl_lower_i2c_clk - Lowers the I2C SCL clock
312*cb6b8299SEric Joyner  *  @hw: pointer to hardware structure
313*cb6b8299SEric Joyner  *  @i2cctl: Current value of I2CCTL register
314*cb6b8299SEric Joyner  *
315*cb6b8299SEric Joyner  *  Lowers the I2C clock line '1'->'0'
316*cb6b8299SEric Joyner  **/
317*cb6b8299SEric Joyner static void
318*cb6b8299SEric Joyner ixl_lower_i2c_clk(struct ixl_pf *pf, u32 *i2cctl)
319*cb6b8299SEric Joyner {
320*cb6b8299SEric Joyner 	struct i40e_hw *hw = &pf->hw;
321*cb6b8299SEric Joyner 
322*cb6b8299SEric Joyner 	*i2cctl &= ~(I40E_GLGEN_I2CPARAMS_CLK_MASK);
323*cb6b8299SEric Joyner 	*i2cctl &= ~(I40E_GLGEN_I2CPARAMS_CLK_OE_N_MASK);
324*cb6b8299SEric Joyner 
325*cb6b8299SEric Joyner 	wr32(hw, IXL_I2C_REG(hw), *i2cctl);
326*cb6b8299SEric Joyner 	ixl_flush(hw);
327*cb6b8299SEric Joyner 
328*cb6b8299SEric Joyner 	/* SCL fall time (300ns) */
329*cb6b8299SEric Joyner 	i40e_usec_delay(IXL_I2C_T_FALL);
330*cb6b8299SEric Joyner }
331*cb6b8299SEric Joyner 
332*cb6b8299SEric Joyner /**
333*cb6b8299SEric Joyner  *  ixl_raise_i2c_clk - Raises the I2C SCL clock
334*cb6b8299SEric Joyner  *  @hw: pointer to hardware structure
335*cb6b8299SEric Joyner  *  @i2cctl: Current value of I2CCTL register
336*cb6b8299SEric Joyner  *
337*cb6b8299SEric Joyner  *  Raises the I2C clock line '0'->'1'
338*cb6b8299SEric Joyner  **/
339*cb6b8299SEric Joyner static void
340*cb6b8299SEric Joyner ixl_raise_i2c_clk(struct ixl_pf *pf, u32 *i2cctl)
341*cb6b8299SEric Joyner {
342*cb6b8299SEric Joyner 	struct i40e_hw *hw = &pf->hw;
343*cb6b8299SEric Joyner 	u32 i = 0;
344*cb6b8299SEric Joyner 	u32 timeout = IXL_I2C_CLOCK_STRETCHING_TIMEOUT;
345*cb6b8299SEric Joyner 	u32 i2cctl_r = 0;
346*cb6b8299SEric Joyner 
347*cb6b8299SEric Joyner 	for (i = 0; i < timeout; i++) {
348*cb6b8299SEric Joyner 		*i2cctl |= I40E_GLGEN_I2CPARAMS_CLK_MASK;
349*cb6b8299SEric Joyner 		*i2cctl &= ~(I40E_GLGEN_I2CPARAMS_CLK_OE_N_MASK);
350*cb6b8299SEric Joyner 
351*cb6b8299SEric Joyner 		wr32(hw, IXL_I2C_REG(hw), *i2cctl);
352*cb6b8299SEric Joyner 		ixl_flush(hw);
353*cb6b8299SEric Joyner 		/* SCL rise time (1000ns) */
354*cb6b8299SEric Joyner 		i40e_usec_delay(IXL_I2C_T_RISE);
355*cb6b8299SEric Joyner 
356*cb6b8299SEric Joyner 		i2cctl_r = rd32(hw, IXL_I2C_REG(hw));
357*cb6b8299SEric Joyner 		if (i2cctl_r & I40E_GLGEN_I2CPARAMS_CLK_IN_MASK)
358*cb6b8299SEric Joyner 			break;
359*cb6b8299SEric Joyner 	}
360*cb6b8299SEric Joyner }
361*cb6b8299SEric Joyner 
362*cb6b8299SEric Joyner /**
363*cb6b8299SEric Joyner  *  ixl_get_i2c_data - Reads the I2C SDA data bit
364*cb6b8299SEric Joyner  *  @hw: pointer to hardware structure
365*cb6b8299SEric Joyner  *  @i2cctl: Current value of I2CCTL register
366*cb6b8299SEric Joyner  *
367*cb6b8299SEric Joyner  *  Returns the I2C data bit value
368*cb6b8299SEric Joyner  **/
369*cb6b8299SEric Joyner static bool
370*cb6b8299SEric Joyner ixl_get_i2c_data(struct ixl_pf *pf, u32 *i2cctl)
371*cb6b8299SEric Joyner {
372*cb6b8299SEric Joyner 	bool data;
373*cb6b8299SEric Joyner 
374*cb6b8299SEric Joyner 	if (*i2cctl & I40E_GLGEN_I2CPARAMS_DATA_IN_MASK)
375*cb6b8299SEric Joyner 		data = 1;
376*cb6b8299SEric Joyner 	else
377*cb6b8299SEric Joyner 		data = 0;
378*cb6b8299SEric Joyner 
379*cb6b8299SEric Joyner 	return data;
380*cb6b8299SEric Joyner }
381*cb6b8299SEric Joyner 
382*cb6b8299SEric Joyner /**
383*cb6b8299SEric Joyner  *  ixl_set_i2c_data - Sets the I2C data bit
384*cb6b8299SEric Joyner  *  @hw: pointer to hardware structure
385*cb6b8299SEric Joyner  *  @i2cctl: Current value of I2CCTL register
386*cb6b8299SEric Joyner  *  @data: I2C data value (0 or 1) to set
387*cb6b8299SEric Joyner  *
388*cb6b8299SEric Joyner  *  Sets the I2C data bit
389*cb6b8299SEric Joyner  **/
390*cb6b8299SEric Joyner static s32
391*cb6b8299SEric Joyner ixl_set_i2c_data(struct ixl_pf *pf, u32 *i2cctl, bool data)
392*cb6b8299SEric Joyner {
393*cb6b8299SEric Joyner 	struct i40e_hw *hw = &pf->hw;
394*cb6b8299SEric Joyner 	s32 status = I40E_SUCCESS;
395*cb6b8299SEric Joyner 
396*cb6b8299SEric Joyner 	DEBUGFUNC("ixl_set_i2c_data");
397*cb6b8299SEric Joyner 
398*cb6b8299SEric Joyner 	if (data)
399*cb6b8299SEric Joyner 		*i2cctl |= I40E_GLGEN_I2CPARAMS_DATA_OUT_MASK;
400*cb6b8299SEric Joyner 	else
401*cb6b8299SEric Joyner 		*i2cctl &= ~(I40E_GLGEN_I2CPARAMS_DATA_OUT_MASK);
402*cb6b8299SEric Joyner 	*i2cctl &= ~(I40E_GLGEN_I2CPARAMS_DATA_OE_N_MASK);
403*cb6b8299SEric Joyner 
404*cb6b8299SEric Joyner 	wr32(hw, IXL_I2C_REG(hw), *i2cctl);
405*cb6b8299SEric Joyner 	ixl_flush(hw);
406*cb6b8299SEric Joyner 
407*cb6b8299SEric Joyner 	/* Data rise/fall (1000ns/300ns) and set-up time (250ns) */
408*cb6b8299SEric Joyner 	i40e_usec_delay(IXL_I2C_T_RISE + IXL_I2C_T_FALL + IXL_I2C_T_SU_DATA);
409*cb6b8299SEric Joyner 
410*cb6b8299SEric Joyner 	/* Verify data was set correctly */
411*cb6b8299SEric Joyner 	*i2cctl = rd32(hw, IXL_I2C_REG(hw));
412*cb6b8299SEric Joyner 	if (data != ixl_get_i2c_data(pf, i2cctl)) {
413*cb6b8299SEric Joyner 		status = I40E_ERR_PHY;
414*cb6b8299SEric Joyner 		ixl_dbg(pf, IXL_DBG_I2C, "Error - I2C data was not set to %X.\n", data);
415*cb6b8299SEric Joyner 	}
416*cb6b8299SEric Joyner 
417*cb6b8299SEric Joyner 	return status;
418*cb6b8299SEric Joyner }
419*cb6b8299SEric Joyner 
420*cb6b8299SEric Joyner /**
421*cb6b8299SEric Joyner  *  ixl_i2c_start - Sets I2C start condition
422*cb6b8299SEric Joyner  *  Sets I2C start condition (High -> Low on SDA while SCL is High)
423*cb6b8299SEric Joyner  **/
424*cb6b8299SEric Joyner static void
425*cb6b8299SEric Joyner ixl_i2c_start(struct ixl_pf *pf)
426*cb6b8299SEric Joyner {
427*cb6b8299SEric Joyner 	struct i40e_hw *hw = &pf->hw;
428*cb6b8299SEric Joyner 	u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
429*cb6b8299SEric Joyner 
430*cb6b8299SEric Joyner 	DEBUGFUNC("ixl_i2c_start");
431*cb6b8299SEric Joyner 
432*cb6b8299SEric Joyner 	/* Start condition must begin with data and clock high */
433*cb6b8299SEric Joyner 	ixl_set_i2c_data(pf, &i2cctl, 1);
434*cb6b8299SEric Joyner 	ixl_raise_i2c_clk(pf, &i2cctl);
435*cb6b8299SEric Joyner 
436*cb6b8299SEric Joyner 	/* Setup time for start condition (4.7us) */
437*cb6b8299SEric Joyner 	i40e_usec_delay(IXL_I2C_T_SU_STA);
438*cb6b8299SEric Joyner 
439*cb6b8299SEric Joyner 	ixl_set_i2c_data(pf, &i2cctl, 0);
440*cb6b8299SEric Joyner 
441*cb6b8299SEric Joyner 	/* Hold time for start condition (4us) */
442*cb6b8299SEric Joyner 	i40e_usec_delay(IXL_I2C_T_HD_STA);
443*cb6b8299SEric Joyner 
444*cb6b8299SEric Joyner 	ixl_lower_i2c_clk(pf, &i2cctl);
445*cb6b8299SEric Joyner 
446*cb6b8299SEric Joyner 	/* Minimum low period of clock is 4.7 us */
447*cb6b8299SEric Joyner 	i40e_usec_delay(IXL_I2C_T_LOW);
448*cb6b8299SEric Joyner 
449*cb6b8299SEric Joyner }
450*cb6b8299SEric Joyner 
451*cb6b8299SEric Joyner /**
452*cb6b8299SEric Joyner  *  ixl_read_i2c_byte - Reads 8 bit word over I2C
453*cb6b8299SEric Joyner  **/
454*cb6b8299SEric Joyner s32
455*cb6b8299SEric Joyner ixl_read_i2c_byte(struct ixl_pf *pf, u8 byte_offset,
456*cb6b8299SEric Joyner 		  u8 dev_addr, u8 *data)
457*cb6b8299SEric Joyner {
458*cb6b8299SEric Joyner 	struct i40e_hw *hw = &pf->hw;
459*cb6b8299SEric Joyner 	u32 max_retry = 10;
460*cb6b8299SEric Joyner 	u32 retry = 0;
461*cb6b8299SEric Joyner 	bool nack = 1;
462*cb6b8299SEric Joyner 	s32 status;
463*cb6b8299SEric Joyner 	*data = 0;
464*cb6b8299SEric Joyner 
465*cb6b8299SEric Joyner 	u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
466*cb6b8299SEric Joyner 	i2cctl |= I40E_GLGEN_I2CPARAMS_I2CBB_EN_MASK;
467*cb6b8299SEric Joyner 	wr32(hw, IXL_I2C_REG(hw), i2cctl);
468*cb6b8299SEric Joyner 	ixl_flush(hw);
469*cb6b8299SEric Joyner 
470*cb6b8299SEric Joyner 	do {
471*cb6b8299SEric Joyner 		ixl_i2c_start(pf);
472*cb6b8299SEric Joyner 
473*cb6b8299SEric Joyner 		/* Device Address and write indication */
474*cb6b8299SEric Joyner 		status = ixl_clock_out_i2c_byte(pf, dev_addr);
475*cb6b8299SEric Joyner 		if (status != I40E_SUCCESS) {
476*cb6b8299SEric Joyner 			ixl_dbg(pf, IXL_DBG_I2C, "dev_addr clock out error\n");
477*cb6b8299SEric Joyner 			goto fail;
478*cb6b8299SEric Joyner 		}
479*cb6b8299SEric Joyner 
480*cb6b8299SEric Joyner 		status = ixl_get_i2c_ack(pf);
481*cb6b8299SEric Joyner 		if (status != I40E_SUCCESS) {
482*cb6b8299SEric Joyner 			ixl_dbg(pf, IXL_DBG_I2C, "dev_addr i2c ack error\n");
483*cb6b8299SEric Joyner 			goto fail;
484*cb6b8299SEric Joyner 		}
485*cb6b8299SEric Joyner 
486*cb6b8299SEric Joyner 		status = ixl_clock_out_i2c_byte(pf, byte_offset);
487*cb6b8299SEric Joyner 		if (status != I40E_SUCCESS) {
488*cb6b8299SEric Joyner 			ixl_dbg(pf, IXL_DBG_I2C, "byte_offset clock out error\n");
489*cb6b8299SEric Joyner 			goto fail;
490*cb6b8299SEric Joyner 		}
491*cb6b8299SEric Joyner 
492*cb6b8299SEric Joyner 		status = ixl_get_i2c_ack(pf);
493*cb6b8299SEric Joyner 		if (status != I40E_SUCCESS) {
494*cb6b8299SEric Joyner 			ixl_dbg(pf, IXL_DBG_I2C, "byte_offset i2c ack error\n");
495*cb6b8299SEric Joyner 			goto fail;
496*cb6b8299SEric Joyner 		}
497*cb6b8299SEric Joyner 
498*cb6b8299SEric Joyner 		ixl_i2c_start(pf);
499*cb6b8299SEric Joyner 
500*cb6b8299SEric Joyner 		/* Device Address and read indication */
501*cb6b8299SEric Joyner 		status = ixl_clock_out_i2c_byte(pf, (dev_addr | 0x1));
502*cb6b8299SEric Joyner 		if (status != I40E_SUCCESS)
503*cb6b8299SEric Joyner 			goto fail;
504*cb6b8299SEric Joyner 
505*cb6b8299SEric Joyner 		status = ixl_get_i2c_ack(pf);
506*cb6b8299SEric Joyner 		if (status != I40E_SUCCESS)
507*cb6b8299SEric Joyner 			goto fail;
508*cb6b8299SEric Joyner 
509*cb6b8299SEric Joyner 		status = ixl_clock_in_i2c_byte(pf, data);
510*cb6b8299SEric Joyner 		if (status != I40E_SUCCESS)
511*cb6b8299SEric Joyner 			goto fail;
512*cb6b8299SEric Joyner 
513*cb6b8299SEric Joyner 		status = ixl_clock_out_i2c_bit(pf, nack);
514*cb6b8299SEric Joyner 		if (status != I40E_SUCCESS)
515*cb6b8299SEric Joyner 			goto fail;
516*cb6b8299SEric Joyner 
517*cb6b8299SEric Joyner 		ixl_i2c_stop(pf);
518*cb6b8299SEric Joyner 		status = I40E_SUCCESS;
519*cb6b8299SEric Joyner 		goto done;
520*cb6b8299SEric Joyner 
521*cb6b8299SEric Joyner fail:
522*cb6b8299SEric Joyner 		ixl_i2c_bus_clear(pf);
523*cb6b8299SEric Joyner 		i40e_msec_delay(100);
524*cb6b8299SEric Joyner 		retry++;
525*cb6b8299SEric Joyner 		if (retry < max_retry)
526*cb6b8299SEric Joyner 			ixl_dbg(pf, IXL_DBG_I2C, "I2C byte read error - Retrying.\n");
527*cb6b8299SEric Joyner 		else
528*cb6b8299SEric Joyner 			ixl_dbg(pf, IXL_DBG_I2C, "I2C byte read error.\n");
529*cb6b8299SEric Joyner 
530*cb6b8299SEric Joyner 	} while (retry < max_retry);
531*cb6b8299SEric Joyner done:
532*cb6b8299SEric Joyner 	i2cctl = rd32(hw, IXL_I2C_REG(hw));
533*cb6b8299SEric Joyner 	i2cctl &= ~I40E_GLGEN_I2CPARAMS_I2CBB_EN_MASK;
534*cb6b8299SEric Joyner 	wr32(hw, IXL_I2C_REG(hw), i2cctl);
535*cb6b8299SEric Joyner 	ixl_flush(hw);
536*cb6b8299SEric Joyner 
537*cb6b8299SEric Joyner 	return status;
538*cb6b8299SEric Joyner }
539*cb6b8299SEric Joyner 
540*cb6b8299SEric Joyner /**
541*cb6b8299SEric Joyner  *  ixl_write_i2c_byte - Writes 8 bit word over I2C
542*cb6b8299SEric Joyner  **/
543*cb6b8299SEric Joyner s32
544*cb6b8299SEric Joyner ixl_write_i2c_byte(struct ixl_pf *pf, u8 byte_offset,
545*cb6b8299SEric Joyner 		       u8 dev_addr, u8 data)
546*cb6b8299SEric Joyner {
547*cb6b8299SEric Joyner 	struct i40e_hw *hw = &pf->hw;
548*cb6b8299SEric Joyner 	s32 status = I40E_SUCCESS;
549*cb6b8299SEric Joyner 	u32 max_retry = 1;
550*cb6b8299SEric Joyner 	u32 retry = 0;
551*cb6b8299SEric Joyner 
552*cb6b8299SEric Joyner 	u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
553*cb6b8299SEric Joyner 	i2cctl |= I40E_GLGEN_I2CPARAMS_I2CBB_EN_MASK;
554*cb6b8299SEric Joyner 	wr32(hw, IXL_I2C_REG(hw), i2cctl);
555*cb6b8299SEric Joyner 	ixl_flush(hw);
556*cb6b8299SEric Joyner 
557*cb6b8299SEric Joyner 	do {
558*cb6b8299SEric Joyner 		ixl_i2c_start(pf);
559*cb6b8299SEric Joyner 
560*cb6b8299SEric Joyner 		status = ixl_clock_out_i2c_byte(pf, dev_addr);
561*cb6b8299SEric Joyner 		if (status != I40E_SUCCESS)
562*cb6b8299SEric Joyner 			goto fail;
563*cb6b8299SEric Joyner 
564*cb6b8299SEric Joyner 		status = ixl_get_i2c_ack(pf);
565*cb6b8299SEric Joyner 		if (status != I40E_SUCCESS)
566*cb6b8299SEric Joyner 			goto fail;
567*cb6b8299SEric Joyner 
568*cb6b8299SEric Joyner 		status = ixl_clock_out_i2c_byte(pf, byte_offset);
569*cb6b8299SEric Joyner 		if (status != I40E_SUCCESS)
570*cb6b8299SEric Joyner 			goto fail;
571*cb6b8299SEric Joyner 
572*cb6b8299SEric Joyner 		status = ixl_get_i2c_ack(pf);
573*cb6b8299SEric Joyner 		if (status != I40E_SUCCESS)
574*cb6b8299SEric Joyner 			goto fail;
575*cb6b8299SEric Joyner 
576*cb6b8299SEric Joyner 		status = ixl_clock_out_i2c_byte(pf, data);
577*cb6b8299SEric Joyner 		if (status != I40E_SUCCESS)
578*cb6b8299SEric Joyner 			goto fail;
579*cb6b8299SEric Joyner 
580*cb6b8299SEric Joyner 		status = ixl_get_i2c_ack(pf);
581*cb6b8299SEric Joyner 		if (status != I40E_SUCCESS)
582*cb6b8299SEric Joyner 			goto fail;
583*cb6b8299SEric Joyner 
584*cb6b8299SEric Joyner 		ixl_i2c_stop(pf);
585*cb6b8299SEric Joyner 		goto write_byte_out;
586*cb6b8299SEric Joyner 
587*cb6b8299SEric Joyner fail:
588*cb6b8299SEric Joyner 		ixl_i2c_bus_clear(pf);
589*cb6b8299SEric Joyner 		i40e_msec_delay(100);
590*cb6b8299SEric Joyner 		retry++;
591*cb6b8299SEric Joyner 		if (retry < max_retry)
592*cb6b8299SEric Joyner 			ixl_dbg(pf, IXL_DBG_I2C, "I2C byte write error - Retrying.\n");
593*cb6b8299SEric Joyner 		else
594*cb6b8299SEric Joyner 			ixl_dbg(pf, IXL_DBG_I2C, "I2C byte write error.\n");
595*cb6b8299SEric Joyner 	} while (retry < max_retry);
596*cb6b8299SEric Joyner 
597*cb6b8299SEric Joyner write_byte_out:
598*cb6b8299SEric Joyner 	i2cctl = rd32(hw, IXL_I2C_REG(hw));
599*cb6b8299SEric Joyner 	i2cctl &= ~I40E_GLGEN_I2CPARAMS_I2CBB_EN_MASK;
600*cb6b8299SEric Joyner 	wr32(hw, IXL_I2C_REG(hw), i2cctl);
601*cb6b8299SEric Joyner 	ixl_flush(hw);
602*cb6b8299SEric Joyner 
603*cb6b8299SEric Joyner 	return status;
604*cb6b8299SEric Joyner }
605*cb6b8299SEric Joyner 
606