162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * Copyright (c) 2012 Intel Corporation. All rights reserved.
362306a36Sopenharmony_ci * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved.
462306a36Sopenharmony_ci * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * This software is available to you under a choice of one of two
762306a36Sopenharmony_ci * licenses.  You may choose to be licensed under the terms of the GNU
862306a36Sopenharmony_ci * General Public License (GPL) Version 2, available from the file
962306a36Sopenharmony_ci * COPYING in the main directory of this source tree, or the
1062306a36Sopenharmony_ci * OpenIB.org BSD license below:
1162306a36Sopenharmony_ci *
1262306a36Sopenharmony_ci *     Redistribution and use in source and binary forms, with or
1362306a36Sopenharmony_ci *     without modification, are permitted provided that the following
1462306a36Sopenharmony_ci *     conditions are met:
1562306a36Sopenharmony_ci *
1662306a36Sopenharmony_ci *      - Redistributions of source code must retain the above
1762306a36Sopenharmony_ci *        copyright notice, this list of conditions and the following
1862306a36Sopenharmony_ci *        disclaimer.
1962306a36Sopenharmony_ci *
2062306a36Sopenharmony_ci *      - Redistributions in binary form must reproduce the above
2162306a36Sopenharmony_ci *        copyright notice, this list of conditions and the following
2262306a36Sopenharmony_ci *        disclaimer in the documentation and/or other materials
2362306a36Sopenharmony_ci *        provided with the distribution.
2462306a36Sopenharmony_ci *
2562306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
2662306a36Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2762306a36Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
2862306a36Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
2962306a36Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
3062306a36Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
3162306a36Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3262306a36Sopenharmony_ci * SOFTWARE.
3362306a36Sopenharmony_ci */
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci#include <linux/delay.h>
3662306a36Sopenharmony_ci#include <linux/pci.h>
3762306a36Sopenharmony_ci#include <linux/vmalloc.h>
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci#include "qib.h"
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci/*
4262306a36Sopenharmony_ci * QLogic_IB "Two Wire Serial Interface" driver.
4362306a36Sopenharmony_ci * Originally written for a not-quite-i2c serial eeprom, which is
4462306a36Sopenharmony_ci * still used on some supported boards. Later boards have added a
4562306a36Sopenharmony_ci * variety of other uses, most board-specific, so the bit-boffing
4662306a36Sopenharmony_ci * part has been split off to this file, while the other parts
4762306a36Sopenharmony_ci * have been moved to chip-specific files.
4862306a36Sopenharmony_ci *
4962306a36Sopenharmony_ci * We have also dropped all pretense of fully generic (e.g. pretend
5062306a36Sopenharmony_ci * we don't know whether '1' is the higher voltage) interface, as
5162306a36Sopenharmony_ci * the restrictions of the generic i2c interface (e.g. no access from
5262306a36Sopenharmony_ci * driver itself) make it unsuitable for this use.
5362306a36Sopenharmony_ci */
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci#define READ_CMD 1
5662306a36Sopenharmony_ci#define WRITE_CMD 0
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci/**
5962306a36Sopenharmony_ci * i2c_wait_for_writes - wait for a write
6062306a36Sopenharmony_ci * @dd: the qlogic_ib device
6162306a36Sopenharmony_ci *
6262306a36Sopenharmony_ci * We use this instead of udelay directly, so we can make sure
6362306a36Sopenharmony_ci * that previous register writes have been flushed all the way
6462306a36Sopenharmony_ci * to the chip.  Since we are delaying anyway, the cost doesn't
6562306a36Sopenharmony_ci * hurt, and makes the bit twiddling more regular
6662306a36Sopenharmony_ci */
6762306a36Sopenharmony_cistatic void i2c_wait_for_writes(struct qib_devdata *dd)
6862306a36Sopenharmony_ci{
6962306a36Sopenharmony_ci	/*
7062306a36Sopenharmony_ci	 * implicit read of EXTStatus is as good as explicit
7162306a36Sopenharmony_ci	 * read of scratch, if all we want to do is flush
7262306a36Sopenharmony_ci	 * writes.
7362306a36Sopenharmony_ci	 */
7462306a36Sopenharmony_ci	dd->f_gpio_mod(dd, 0, 0, 0);
7562306a36Sopenharmony_ci	rmb(); /* inlined, so prevent compiler reordering */
7662306a36Sopenharmony_ci}
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci/*
7962306a36Sopenharmony_ci * QSFP modules are allowed to hold SCL low for 500uSec. Allow twice that
8062306a36Sopenharmony_ci * for "almost compliant" modules
8162306a36Sopenharmony_ci */
8262306a36Sopenharmony_ci#define SCL_WAIT_USEC 1000
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci/* BUF_WAIT is time bus must be free between STOP or ACK and to next START.
8562306a36Sopenharmony_ci * Should be 20, but some chips need more.
8662306a36Sopenharmony_ci */
8762306a36Sopenharmony_ci#define TWSI_BUF_WAIT_USEC 60
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_cistatic void scl_out(struct qib_devdata *dd, u8 bit)
9062306a36Sopenharmony_ci{
9162306a36Sopenharmony_ci	u32 mask;
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci	udelay(1);
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci	mask = 1UL << dd->gpio_scl_num;
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci	/* SCL is meant to be bare-drain, so never set "OUT", just DIR */
9862306a36Sopenharmony_ci	dd->f_gpio_mod(dd, 0, bit ? 0 : mask, mask);
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci	/*
10162306a36Sopenharmony_ci	 * Allow for slow slaves by simple
10262306a36Sopenharmony_ci	 * delay for falling edge, sampling on rise.
10362306a36Sopenharmony_ci	 */
10462306a36Sopenharmony_ci	if (!bit)
10562306a36Sopenharmony_ci		udelay(2);
10662306a36Sopenharmony_ci	else {
10762306a36Sopenharmony_ci		int rise_usec;
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci		for (rise_usec = SCL_WAIT_USEC; rise_usec > 0; rise_usec -= 2) {
11062306a36Sopenharmony_ci			if (mask & dd->f_gpio_mod(dd, 0, 0, 0))
11162306a36Sopenharmony_ci				break;
11262306a36Sopenharmony_ci			udelay(2);
11362306a36Sopenharmony_ci		}
11462306a36Sopenharmony_ci		if (rise_usec <= 0)
11562306a36Sopenharmony_ci			qib_dev_err(dd, "SCL interface stuck low > %d uSec\n",
11662306a36Sopenharmony_ci				    SCL_WAIT_USEC);
11762306a36Sopenharmony_ci	}
11862306a36Sopenharmony_ci	i2c_wait_for_writes(dd);
11962306a36Sopenharmony_ci}
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_cistatic void sda_out(struct qib_devdata *dd, u8 bit)
12262306a36Sopenharmony_ci{
12362306a36Sopenharmony_ci	u32 mask;
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci	mask = 1UL << dd->gpio_sda_num;
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci	/* SDA is meant to be bare-drain, so never set "OUT", just DIR */
12862306a36Sopenharmony_ci	dd->f_gpio_mod(dd, 0, bit ? 0 : mask, mask);
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci	i2c_wait_for_writes(dd);
13162306a36Sopenharmony_ci	udelay(2);
13262306a36Sopenharmony_ci}
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_cistatic u8 sda_in(struct qib_devdata *dd, int wait)
13562306a36Sopenharmony_ci{
13662306a36Sopenharmony_ci	int bnum;
13762306a36Sopenharmony_ci	u32 read_val, mask;
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci	bnum = dd->gpio_sda_num;
14062306a36Sopenharmony_ci	mask = (1UL << bnum);
14162306a36Sopenharmony_ci	/* SDA is meant to be bare-drain, so never set "OUT", just DIR */
14262306a36Sopenharmony_ci	dd->f_gpio_mod(dd, 0, 0, mask);
14362306a36Sopenharmony_ci	read_val = dd->f_gpio_mod(dd, 0, 0, 0);
14462306a36Sopenharmony_ci	if (wait)
14562306a36Sopenharmony_ci		i2c_wait_for_writes(dd);
14662306a36Sopenharmony_ci	return (read_val & mask) >> bnum;
14762306a36Sopenharmony_ci}
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci/**
15062306a36Sopenharmony_ci * i2c_ackrcv - see if ack following write is true
15162306a36Sopenharmony_ci * @dd: the qlogic_ib device
15262306a36Sopenharmony_ci */
15362306a36Sopenharmony_cistatic int i2c_ackrcv(struct qib_devdata *dd)
15462306a36Sopenharmony_ci{
15562306a36Sopenharmony_ci	u8 ack_received;
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci	/* AT ENTRY SCL = LOW */
15862306a36Sopenharmony_ci	/* change direction, ignore data */
15962306a36Sopenharmony_ci	ack_received = sda_in(dd, 1);
16062306a36Sopenharmony_ci	scl_out(dd, 1);
16162306a36Sopenharmony_ci	ack_received = sda_in(dd, 1) == 0;
16262306a36Sopenharmony_ci	scl_out(dd, 0);
16362306a36Sopenharmony_ci	return ack_received;
16462306a36Sopenharmony_ci}
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_cistatic void stop_cmd(struct qib_devdata *dd);
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci/**
16962306a36Sopenharmony_ci * rd_byte - read a byte, sending STOP on last, else ACK
17062306a36Sopenharmony_ci * @dd: the qlogic_ib device
17162306a36Sopenharmony_ci * @last: identifies the last read
17262306a36Sopenharmony_ci *
17362306a36Sopenharmony_ci * Returns byte shifted out of device
17462306a36Sopenharmony_ci */
17562306a36Sopenharmony_cistatic int rd_byte(struct qib_devdata *dd, int last)
17662306a36Sopenharmony_ci{
17762306a36Sopenharmony_ci	int bit_cntr, data;
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci	data = 0;
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci	for (bit_cntr = 7; bit_cntr >= 0; --bit_cntr) {
18262306a36Sopenharmony_ci		data <<= 1;
18362306a36Sopenharmony_ci		scl_out(dd, 1);
18462306a36Sopenharmony_ci		data |= sda_in(dd, 0);
18562306a36Sopenharmony_ci		scl_out(dd, 0);
18662306a36Sopenharmony_ci	}
18762306a36Sopenharmony_ci	if (last) {
18862306a36Sopenharmony_ci		scl_out(dd, 1);
18962306a36Sopenharmony_ci		stop_cmd(dd);
19062306a36Sopenharmony_ci	} else {
19162306a36Sopenharmony_ci		sda_out(dd, 0);
19262306a36Sopenharmony_ci		scl_out(dd, 1);
19362306a36Sopenharmony_ci		scl_out(dd, 0);
19462306a36Sopenharmony_ci		sda_out(dd, 1);
19562306a36Sopenharmony_ci	}
19662306a36Sopenharmony_ci	return data;
19762306a36Sopenharmony_ci}
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci/**
20062306a36Sopenharmony_ci * wr_byte - write a byte, one bit at a time
20162306a36Sopenharmony_ci * @dd: the qlogic_ib device
20262306a36Sopenharmony_ci * @data: the byte to write
20362306a36Sopenharmony_ci *
20462306a36Sopenharmony_ci * Returns 0 if we got the following ack, otherwise 1
20562306a36Sopenharmony_ci */
20662306a36Sopenharmony_cistatic int wr_byte(struct qib_devdata *dd, u8 data)
20762306a36Sopenharmony_ci{
20862306a36Sopenharmony_ci	int bit_cntr;
20962306a36Sopenharmony_ci	u8 bit;
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci	for (bit_cntr = 7; bit_cntr >= 0; bit_cntr--) {
21262306a36Sopenharmony_ci		bit = (data >> bit_cntr) & 1;
21362306a36Sopenharmony_ci		sda_out(dd, bit);
21462306a36Sopenharmony_ci		scl_out(dd, 1);
21562306a36Sopenharmony_ci		scl_out(dd, 0);
21662306a36Sopenharmony_ci	}
21762306a36Sopenharmony_ci	return (!i2c_ackrcv(dd)) ? 1 : 0;
21862306a36Sopenharmony_ci}
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci/*
22162306a36Sopenharmony_ci * issue TWSI start sequence:
22262306a36Sopenharmony_ci * (both clock/data high, clock high, data low while clock is high)
22362306a36Sopenharmony_ci */
22462306a36Sopenharmony_cistatic void start_seq(struct qib_devdata *dd)
22562306a36Sopenharmony_ci{
22662306a36Sopenharmony_ci	sda_out(dd, 1);
22762306a36Sopenharmony_ci	scl_out(dd, 1);
22862306a36Sopenharmony_ci	sda_out(dd, 0);
22962306a36Sopenharmony_ci	udelay(1);
23062306a36Sopenharmony_ci	scl_out(dd, 0);
23162306a36Sopenharmony_ci}
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci/**
23462306a36Sopenharmony_ci * stop_seq - transmit the stop sequence
23562306a36Sopenharmony_ci * @dd: the qlogic_ib device
23662306a36Sopenharmony_ci *
23762306a36Sopenharmony_ci * (both clock/data low, clock high, data high while clock is high)
23862306a36Sopenharmony_ci */
23962306a36Sopenharmony_cistatic void stop_seq(struct qib_devdata *dd)
24062306a36Sopenharmony_ci{
24162306a36Sopenharmony_ci	scl_out(dd, 0);
24262306a36Sopenharmony_ci	sda_out(dd, 0);
24362306a36Sopenharmony_ci	scl_out(dd, 1);
24462306a36Sopenharmony_ci	sda_out(dd, 1);
24562306a36Sopenharmony_ci}
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_ci/**
24862306a36Sopenharmony_ci * stop_cmd - transmit the stop condition
24962306a36Sopenharmony_ci * @dd: the qlogic_ib device
25062306a36Sopenharmony_ci *
25162306a36Sopenharmony_ci * (both clock/data low, clock high, data high while clock is high)
25262306a36Sopenharmony_ci */
25362306a36Sopenharmony_cistatic void stop_cmd(struct qib_devdata *dd)
25462306a36Sopenharmony_ci{
25562306a36Sopenharmony_ci	stop_seq(dd);
25662306a36Sopenharmony_ci	udelay(TWSI_BUF_WAIT_USEC);
25762306a36Sopenharmony_ci}
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci/**
26062306a36Sopenharmony_ci * qib_twsi_reset - reset I2C communication
26162306a36Sopenharmony_ci * @dd: the qlogic_ib device
26262306a36Sopenharmony_ci */
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_ciint qib_twsi_reset(struct qib_devdata *dd)
26562306a36Sopenharmony_ci{
26662306a36Sopenharmony_ci	int clock_cycles_left = 9;
26762306a36Sopenharmony_ci	int was_high = 0;
26862306a36Sopenharmony_ci	u32 pins, mask;
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci	/* Both SCL and SDA should be high. If not, there
27162306a36Sopenharmony_ci	 * is something wrong.
27262306a36Sopenharmony_ci	 */
27362306a36Sopenharmony_ci	mask = (1UL << dd->gpio_scl_num) | (1UL << dd->gpio_sda_num);
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci	/*
27662306a36Sopenharmony_ci	 * Force pins to desired innocuous state.
27762306a36Sopenharmony_ci	 * This is the default power-on state with out=0 and dir=0,
27862306a36Sopenharmony_ci	 * So tri-stated and should be floating high (barring HW problems)
27962306a36Sopenharmony_ci	 */
28062306a36Sopenharmony_ci	dd->f_gpio_mod(dd, 0, 0, mask);
28162306a36Sopenharmony_ci
28262306a36Sopenharmony_ci	/*
28362306a36Sopenharmony_ci	 * Clock nine times to get all listeners into a sane state.
28462306a36Sopenharmony_ci	 * If SDA does not go high at any point, we are wedged.
28562306a36Sopenharmony_ci	 * One vendor recommends then issuing START followed by STOP.
28662306a36Sopenharmony_ci	 * we cannot use our "normal" functions to do that, because
28762306a36Sopenharmony_ci	 * if SCL drops between them, another vendor's part will
28862306a36Sopenharmony_ci	 * wedge, dropping SDA and keeping it low forever, at the end of
28962306a36Sopenharmony_ci	 * the next transaction (even if it was not the device addressed).
29062306a36Sopenharmony_ci	 * So our START and STOP take place with SCL held high.
29162306a36Sopenharmony_ci	 */
29262306a36Sopenharmony_ci	while (clock_cycles_left--) {
29362306a36Sopenharmony_ci		scl_out(dd, 0);
29462306a36Sopenharmony_ci		scl_out(dd, 1);
29562306a36Sopenharmony_ci		/* Note if SDA is high, but keep clocking to sync slave */
29662306a36Sopenharmony_ci		was_high |= sda_in(dd, 0);
29762306a36Sopenharmony_ci	}
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci	if (was_high) {
30062306a36Sopenharmony_ci		/*
30162306a36Sopenharmony_ci		 * We saw a high, which we hope means the slave is sync'd.
30262306a36Sopenharmony_ci		 * Issue START, STOP, pause for T_BUF.
30362306a36Sopenharmony_ci		 */
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ci		pins = dd->f_gpio_mod(dd, 0, 0, 0);
30662306a36Sopenharmony_ci		if ((pins & mask) != mask)
30762306a36Sopenharmony_ci			qib_dev_err(dd, "GPIO pins not at rest: %d\n",
30862306a36Sopenharmony_ci				    pins & mask);
30962306a36Sopenharmony_ci		/* Drop SDA to issue START */
31062306a36Sopenharmony_ci		udelay(1); /* Guarantee .6 uSec setup */
31162306a36Sopenharmony_ci		sda_out(dd, 0);
31262306a36Sopenharmony_ci		udelay(1); /* Guarantee .6 uSec hold */
31362306a36Sopenharmony_ci		/* At this point, SCL is high, SDA low. Raise SDA for STOP */
31462306a36Sopenharmony_ci		sda_out(dd, 1);
31562306a36Sopenharmony_ci		udelay(TWSI_BUF_WAIT_USEC);
31662306a36Sopenharmony_ci	}
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ci	return !was_high;
31962306a36Sopenharmony_ci}
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci#define QIB_TWSI_START 0x100
32262306a36Sopenharmony_ci#define QIB_TWSI_STOP 0x200
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ci/* Write byte to TWSI, optionally prefixed with START or suffixed with
32562306a36Sopenharmony_ci * STOP.
32662306a36Sopenharmony_ci * returns 0 if OK (ACK received), else != 0
32762306a36Sopenharmony_ci */
32862306a36Sopenharmony_cistatic int qib_twsi_wr(struct qib_devdata *dd, int data, int flags)
32962306a36Sopenharmony_ci{
33062306a36Sopenharmony_ci	int ret = 1;
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_ci	if (flags & QIB_TWSI_START)
33362306a36Sopenharmony_ci		start_seq(dd);
33462306a36Sopenharmony_ci
33562306a36Sopenharmony_ci	ret = wr_byte(dd, data); /* Leaves SCL low (from i2c_ackrcv()) */
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_ci	if (flags & QIB_TWSI_STOP)
33862306a36Sopenharmony_ci		stop_cmd(dd);
33962306a36Sopenharmony_ci	return ret;
34062306a36Sopenharmony_ci}
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ci/* Added functionality for IBA7220-based cards */
34362306a36Sopenharmony_ci#define QIB_TEMP_DEV 0x98
34462306a36Sopenharmony_ci
34562306a36Sopenharmony_ci/*
34662306a36Sopenharmony_ci * qib_twsi_blk_rd
34762306a36Sopenharmony_ci * Formerly called qib_eeprom_internal_read, and only used for eeprom,
34862306a36Sopenharmony_ci * but now the general interface for data transfer from twsi devices.
34962306a36Sopenharmony_ci * One vestige of its former role is that it recognizes a device
35062306a36Sopenharmony_ci * QIB_TWSI_NO_DEV and does the correct operation for the legacy part,
35162306a36Sopenharmony_ci * which responded to all TWSI device codes, interpreting them as
35262306a36Sopenharmony_ci * address within device. On all other devices found on board handled by
35362306a36Sopenharmony_ci * this driver, the device is followed by a one-byte "address" which selects
35462306a36Sopenharmony_ci * the "register" or "offset" within the device from which data should
35562306a36Sopenharmony_ci * be read.
35662306a36Sopenharmony_ci */
35762306a36Sopenharmony_ciint qib_twsi_blk_rd(struct qib_devdata *dd, int dev, int addr,
35862306a36Sopenharmony_ci		    void *buffer, int len)
35962306a36Sopenharmony_ci{
36062306a36Sopenharmony_ci	int ret;
36162306a36Sopenharmony_ci	u8 *bp = buffer;
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_ci	ret = 1;
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci	if (dev == QIB_TWSI_NO_DEV) {
36662306a36Sopenharmony_ci		/* legacy not-really-I2C */
36762306a36Sopenharmony_ci		addr = (addr << 1) | READ_CMD;
36862306a36Sopenharmony_ci		ret = qib_twsi_wr(dd, addr, QIB_TWSI_START);
36962306a36Sopenharmony_ci	} else {
37062306a36Sopenharmony_ci		/* Actual I2C */
37162306a36Sopenharmony_ci		ret = qib_twsi_wr(dd, dev | WRITE_CMD, QIB_TWSI_START);
37262306a36Sopenharmony_ci		if (ret) {
37362306a36Sopenharmony_ci			stop_cmd(dd);
37462306a36Sopenharmony_ci			ret = 1;
37562306a36Sopenharmony_ci			goto bail;
37662306a36Sopenharmony_ci		}
37762306a36Sopenharmony_ci		/*
37862306a36Sopenharmony_ci		 * SFF spec claims we do _not_ stop after the addr
37962306a36Sopenharmony_ci		 * but simply issue a start with the "read" dev-addr.
38062306a36Sopenharmony_ci		 * Since we are implicitely waiting for ACK here,
38162306a36Sopenharmony_ci		 * we need t_buf (nominally 20uSec) before that start,
38262306a36Sopenharmony_ci		 * and cannot rely on the delay built in to the STOP
38362306a36Sopenharmony_ci		 */
38462306a36Sopenharmony_ci		ret = qib_twsi_wr(dd, addr, 0);
38562306a36Sopenharmony_ci		udelay(TWSI_BUF_WAIT_USEC);
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_ci		if (ret) {
38862306a36Sopenharmony_ci			qib_dev_err(dd,
38962306a36Sopenharmony_ci				"Failed to write interface read addr %02X\n",
39062306a36Sopenharmony_ci				addr);
39162306a36Sopenharmony_ci			ret = 1;
39262306a36Sopenharmony_ci			goto bail;
39362306a36Sopenharmony_ci		}
39462306a36Sopenharmony_ci		ret = qib_twsi_wr(dd, dev | READ_CMD, QIB_TWSI_START);
39562306a36Sopenharmony_ci	}
39662306a36Sopenharmony_ci	if (ret) {
39762306a36Sopenharmony_ci		stop_cmd(dd);
39862306a36Sopenharmony_ci		ret = 1;
39962306a36Sopenharmony_ci		goto bail;
40062306a36Sopenharmony_ci	}
40162306a36Sopenharmony_ci
40262306a36Sopenharmony_ci	/*
40362306a36Sopenharmony_ci	 * block devices keeps clocking data out as long as we ack,
40462306a36Sopenharmony_ci	 * automatically incrementing the address. Some have "pages"
40562306a36Sopenharmony_ci	 * whose boundaries will not be crossed, but the handling
40662306a36Sopenharmony_ci	 * of these is left to the caller, who is in a better
40762306a36Sopenharmony_ci	 * position to know.
40862306a36Sopenharmony_ci	 */
40962306a36Sopenharmony_ci	while (len-- > 0) {
41062306a36Sopenharmony_ci		/*
41162306a36Sopenharmony_ci		 * Get and store data, sending ACK if length remaining,
41262306a36Sopenharmony_ci		 * else STOP
41362306a36Sopenharmony_ci		 */
41462306a36Sopenharmony_ci		*bp++ = rd_byte(dd, !len);
41562306a36Sopenharmony_ci	}
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_ci	ret = 0;
41862306a36Sopenharmony_ci
41962306a36Sopenharmony_cibail:
42062306a36Sopenharmony_ci	return ret;
42162306a36Sopenharmony_ci}
42262306a36Sopenharmony_ci
42362306a36Sopenharmony_ci/*
42462306a36Sopenharmony_ci * qib_twsi_blk_wr
42562306a36Sopenharmony_ci * Formerly called qib_eeprom_internal_write, and only used for eeprom,
42662306a36Sopenharmony_ci * but now the general interface for data transfer to twsi devices.
42762306a36Sopenharmony_ci * One vestige of its former role is that it recognizes a device
42862306a36Sopenharmony_ci * QIB_TWSI_NO_DEV and does the correct operation for the legacy part,
42962306a36Sopenharmony_ci * which responded to all TWSI device codes, interpreting them as
43062306a36Sopenharmony_ci * address within device. On all other devices found on board handled by
43162306a36Sopenharmony_ci * this driver, the device is followed by a one-byte "address" which selects
43262306a36Sopenharmony_ci * the "register" or "offset" within the device to which data should
43362306a36Sopenharmony_ci * be written.
43462306a36Sopenharmony_ci */
43562306a36Sopenharmony_ciint qib_twsi_blk_wr(struct qib_devdata *dd, int dev, int addr,
43662306a36Sopenharmony_ci		    const void *buffer, int len)
43762306a36Sopenharmony_ci{
43862306a36Sopenharmony_ci	int sub_len;
43962306a36Sopenharmony_ci	const u8 *bp = buffer;
44062306a36Sopenharmony_ci	int max_wait_time, i;
44162306a36Sopenharmony_ci	int ret = 1;
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_ci	while (len > 0) {
44462306a36Sopenharmony_ci		if (dev == QIB_TWSI_NO_DEV) {
44562306a36Sopenharmony_ci			if (qib_twsi_wr(dd, (addr << 1) | WRITE_CMD,
44662306a36Sopenharmony_ci					QIB_TWSI_START)) {
44762306a36Sopenharmony_ci				goto failed_write;
44862306a36Sopenharmony_ci			}
44962306a36Sopenharmony_ci		} else {
45062306a36Sopenharmony_ci			/* Real I2C */
45162306a36Sopenharmony_ci			if (qib_twsi_wr(dd, dev | WRITE_CMD, QIB_TWSI_START))
45262306a36Sopenharmony_ci				goto failed_write;
45362306a36Sopenharmony_ci			ret = qib_twsi_wr(dd, addr, 0);
45462306a36Sopenharmony_ci			if (ret) {
45562306a36Sopenharmony_ci				qib_dev_err(dd,
45662306a36Sopenharmony_ci					"Failed to write interface write addr %02X\n",
45762306a36Sopenharmony_ci					addr);
45862306a36Sopenharmony_ci				goto failed_write;
45962306a36Sopenharmony_ci			}
46062306a36Sopenharmony_ci		}
46162306a36Sopenharmony_ci
46262306a36Sopenharmony_ci		sub_len = min(len, 4);
46362306a36Sopenharmony_ci		addr += sub_len;
46462306a36Sopenharmony_ci		len -= sub_len;
46562306a36Sopenharmony_ci
46662306a36Sopenharmony_ci		for (i = 0; i < sub_len; i++)
46762306a36Sopenharmony_ci			if (qib_twsi_wr(dd, *bp++, 0))
46862306a36Sopenharmony_ci				goto failed_write;
46962306a36Sopenharmony_ci
47062306a36Sopenharmony_ci		stop_cmd(dd);
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_ci		/*
47362306a36Sopenharmony_ci		 * Wait for write complete by waiting for a successful
47462306a36Sopenharmony_ci		 * read (the chip replies with a zero after the write
47562306a36Sopenharmony_ci		 * cmd completes, and before it writes to the eeprom.
47662306a36Sopenharmony_ci		 * The startcmd for the read will fail the ack until
47762306a36Sopenharmony_ci		 * the writes have completed.   We do this inline to avoid
47862306a36Sopenharmony_ci		 * the debug prints that are in the real read routine
47962306a36Sopenharmony_ci		 * if the startcmd fails.
48062306a36Sopenharmony_ci		 * We also use the proper device address, so it doesn't matter
48162306a36Sopenharmony_ci		 * whether we have real eeprom_dev. Legacy likes any address.
48262306a36Sopenharmony_ci		 */
48362306a36Sopenharmony_ci		max_wait_time = 100;
48462306a36Sopenharmony_ci		while (qib_twsi_wr(dd, dev | READ_CMD, QIB_TWSI_START)) {
48562306a36Sopenharmony_ci			stop_cmd(dd);
48662306a36Sopenharmony_ci			if (!--max_wait_time)
48762306a36Sopenharmony_ci				goto failed_write;
48862306a36Sopenharmony_ci		}
48962306a36Sopenharmony_ci		/* now read (and ignore) the resulting byte */
49062306a36Sopenharmony_ci		rd_byte(dd, 1);
49162306a36Sopenharmony_ci	}
49262306a36Sopenharmony_ci
49362306a36Sopenharmony_ci	ret = 0;
49462306a36Sopenharmony_ci	goto bail;
49562306a36Sopenharmony_ci
49662306a36Sopenharmony_cifailed_write:
49762306a36Sopenharmony_ci	stop_cmd(dd);
49862306a36Sopenharmony_ci	ret = 1;
49962306a36Sopenharmony_ci
50062306a36Sopenharmony_cibail:
50162306a36Sopenharmony_ci	return ret;
50262306a36Sopenharmony_ci}
503