/* * Copyright (c) 2012 Intel Corporation. All rights reserved. * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved. * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU * General Public License (GPL) Version 2, available from the file * COPYING in the main directory of this source tree, or the * OpenIB.org BSD license below: * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * - Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include <linux/delay.h> #include <linux/pci.h> #include <linux/vmalloc.h> #include "qib.h" /* * QLogic_IB "Two Wire Serial Interface" driver. * Originally written for a not-quite-i2c serial eeprom, which is * still used on some supported boards. Later boards have added a * variety of other uses, most board-specific, so the bit-boffing * part has been split off to this file, while the other parts * have been moved to chip-specific files. * * We have also dropped all pretense of fully generic (e.g. pretend * we don't know whether '1' is the higher voltage) interface, as * the restrictions of the generic i2c interface (e.g. no access from * driver itself) make it unsuitable for this use. */ #define READ_CMD … #define WRITE_CMD … /** * i2c_wait_for_writes - wait for a write * @dd: the qlogic_ib device * * We use this instead of udelay directly, so we can make sure * that previous register writes have been flushed all the way * to the chip. Since we are delaying anyway, the cost doesn't * hurt, and makes the bit twiddling more regular */ static void i2c_wait_for_writes(struct qib_devdata *dd) { … } /* * QSFP modules are allowed to hold SCL low for 500uSec. Allow twice that * for "almost compliant" modules */ #define SCL_WAIT_USEC … /* BUF_WAIT is time bus must be free between STOP or ACK and to next START. * Should be 20, but some chips need more. */ #define TWSI_BUF_WAIT_USEC … static void scl_out(struct qib_devdata *dd, u8 bit) { … } static void sda_out(struct qib_devdata *dd, u8 bit) { … } static u8 sda_in(struct qib_devdata *dd, int wait) { … } /** * i2c_ackrcv - see if ack following write is true * @dd: the qlogic_ib device */ static int i2c_ackrcv(struct qib_devdata *dd) { … } static void stop_cmd(struct qib_devdata *dd); /** * rd_byte - read a byte, sending STOP on last, else ACK * @dd: the qlogic_ib device * @last: identifies the last read * * Returns byte shifted out of device */ static int rd_byte(struct qib_devdata *dd, int last) { … } /** * wr_byte - write a byte, one bit at a time * @dd: the qlogic_ib device * @data: the byte to write * * Returns 0 if we got the following ack, otherwise 1 */ static int wr_byte(struct qib_devdata *dd, u8 data) { … } /* * issue TWSI start sequence: * (both clock/data high, clock high, data low while clock is high) */ static void start_seq(struct qib_devdata *dd) { … } /** * stop_seq - transmit the stop sequence * @dd: the qlogic_ib device * * (both clock/data low, clock high, data high while clock is high) */ static void stop_seq(struct qib_devdata *dd) { … } /** * stop_cmd - transmit the stop condition * @dd: the qlogic_ib device * * (both clock/data low, clock high, data high while clock is high) */ static void stop_cmd(struct qib_devdata *dd) { … } /** * qib_twsi_reset - reset I2C communication * @dd: the qlogic_ib device */ int qib_twsi_reset(struct qib_devdata *dd) { … } #define QIB_TWSI_START … #define QIB_TWSI_STOP … /* Write byte to TWSI, optionally prefixed with START or suffixed with * STOP. * returns 0 if OK (ACK received), else != 0 */ static int qib_twsi_wr(struct qib_devdata *dd, int data, int flags) { … } /* Added functionality for IBA7220-based cards */ #define QIB_TEMP_DEV … /* * qib_twsi_blk_rd * Formerly called qib_eeprom_internal_read, and only used for eeprom, * but now the general interface for data transfer from twsi devices. * One vestige of its former role is that it recognizes a device * QIB_TWSI_NO_DEV and does the correct operation for the legacy part, * which responded to all TWSI device codes, interpreting them as * address within device. On all other devices found on board handled by * this driver, the device is followed by a one-byte "address" which selects * the "register" or "offset" within the device from which data should * be read. */ int qib_twsi_blk_rd(struct qib_devdata *dd, int dev, int addr, void *buffer, int len) { … } /* * qib_twsi_blk_wr * Formerly called qib_eeprom_internal_write, and only used for eeprom, * but now the general interface for data transfer to twsi devices. * One vestige of its former role is that it recognizes a device * QIB_TWSI_NO_DEV and does the correct operation for the legacy part, * which responded to all TWSI device codes, interpreting them as * address within device. On all other devices found on board handled by * this driver, the device is followed by a one-byte "address" which selects * the "register" or "offset" within the device to which data should * be written. */ int qib_twsi_blk_wr(struct qib_devdata *dd, int dev, int addr, const void *buffer, int len) { … }