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