i2c: mvtwsi: Streamline code and add documentation

Convert groups of logically connected preprocessor defines into proper
enums, one macro into an inline function, and add documentation
to/extend existing documentation of these items.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
Reviewed-by: Stefan Roese <sr@denx.de>
This commit is contained in:
mario.six@gdsys.cc
2016-07-21 11:57:02 +02:00
committed by Heiko Schocher
parent 9ec43b0c3f
commit dfc3958cd3

View File

@@ -62,15 +62,23 @@ struct mvtwsi_registers {
#endif #endif
/* /*
* Control register fields * enum mvtwsi_ctrl_register_fields - Bit masks for flags in the control
* register
*/ */
enum mvtwsi_ctrl_register_fields {
#define MVTWSI_CONTROL_ACK 0x00000004 /* Acknowledge bit */
#define MVTWSI_CONTROL_IFLG 0x00000008 MVTWSI_CONTROL_ACK = 0x00000004,
#define MVTWSI_CONTROL_STOP 0x00000010 /* Interrupt flag */
#define MVTWSI_CONTROL_START 0x00000020 MVTWSI_CONTROL_IFLG = 0x00000008,
#define MVTWSI_CONTROL_TWSIEN 0x00000040 /* Stop bit */
#define MVTWSI_CONTROL_INTEN 0x00000080 MVTWSI_CONTROL_STOP = 0x00000010,
/* Start bit */
MVTWSI_CONTROL_START = 0x00000020,
/* I2C enable */
MVTWSI_CONTROL_TWSIEN = 0x00000040,
/* Interrupt enable */
MVTWSI_CONTROL_INTEN = 0x00000080,
};
/* /*
* On sun6i and newer IFLG is a write-clear bit which is cleared by writing 1, * On sun6i and newer IFLG is a write-clear bit which is cleared by writing 1,
@@ -84,22 +92,36 @@ struct mvtwsi_registers {
#endif #endif
/* /*
* Status register values -- only those expected in normal master * enum mvstwsi_status_values - Possible values of I2C controller's status
* operation on non-10-bit-address devices; whatever status we don't * register
* expect in nominal conditions (bus errors, arbitration losses, *
* missing ACKs...) we just pass back to the caller as an error * Only those statuses expected in normal master operation on
* non-10-bit-address devices are specified.
*
* Every status that's unexpected during normal operation (bus errors,
* arbitration losses, missing ACKs...) is passed back to the caller as an error
* code. * code.
*/ */
enum mvstwsi_status_values {
#define MVTWSI_STATUS_START 0x08 /* START condition transmitted */
#define MVTWSI_STATUS_REPEATED_START 0x10 MVTWSI_STATUS_START = 0x08,
#define MVTWSI_STATUS_ADDR_W_ACK 0x18 /* Repeated START condition transmitted */
#define MVTWSI_STATUS_DATA_W_ACK 0x28 MVTWSI_STATUS_REPEATED_START = 0x10,
#define MVTWSI_STATUS_ADDR_R_ACK 0x40 /* Address + write bit transmitted, ACK received */
#define MVTWSI_STATUS_ADDR_R_NAK 0x48 MVTWSI_STATUS_ADDR_W_ACK = 0x18,
#define MVTWSI_STATUS_DATA_R_ACK 0x50 /* Data transmitted, ACK received */
#define MVTWSI_STATUS_DATA_R_NAK 0x58 MVTWSI_STATUS_DATA_W_ACK = 0x28,
#define MVTWSI_STATUS_IDLE 0xF8 /* Address + read bit transmitted, ACK received */
MVTWSI_STATUS_ADDR_R_ACK = 0x40,
/* Address + read bit transmitted, ACK not received */
MVTWSI_STATUS_ADDR_R_NAK = 0x48,
/* Data received, ACK transmitted */
MVTWSI_STATUS_DATA_R_ACK = 0x50,
/* Data received, ACK not transmitted */
MVTWSI_STATUS_DATA_R_NAK = 0x58,
/* No relevant status */
MVTWSI_STATUS_IDLE = 0xF8,
};
/* /*
* MVTWSI controller base * MVTWSI controller base
@@ -141,20 +163,35 @@ static struct mvtwsi_registers *twsi_get_base(struct i2c_adapter *adap)
} }
/* /*
* Returned statuses are 0 for success and nonzero otherwise. * enum mvtwsi_error_class - types of I2C errors
* Currently, cmd_i2c and cmd_eeprom do not interpret an error status.
* Thus to ease debugging, the return status contains some debug info:
* - bits 31..24 are error class: 1 is timeout, 2 is 'status mismatch'.
* - bits 23..16 are the last value of the control register.
* - bits 15..8 are the last value of the status register.
* - bits 7..0 are the expected value of the status register.
*/ */
enum mvtwsi_error_class {
/* The controller returned a different status than expected */
MVTWSI_ERROR_WRONG_STATUS = 0x01,
/* The controller timed out */
MVTWSI_ERROR_TIMEOUT = 0x02,
};
#define MVTWSI_ERROR_WRONG_STATUS 0x01 /*
#define MVTWSI_ERROR_TIMEOUT 0x02 * mvtwsi_error() - Build I2C return code from error information
*
#define MVTWSI_ERROR(ec, lc, ls, es) (((ec << 24) & 0xFF000000) | \ * For debugging purposes, this function packs some information of an occurred
((lc << 16) & 0x00FF0000) | ((ls<<8) & 0x0000FF00) | (es & 0xFF)) * error into a return code. These error codes are returned from I2C API
* functions (i2c_{read,write}, dm_i2c_{read,write}, etc.).
*
* @ec: The error class of the error (enum mvtwsi_error_class).
* @lc: The last value of the control register.
* @ls: The last value of the status register.
* @es: The expected value of the status register.
* @return The generated error code.
*/
inline uint mvtwsi_error(uint ec, uint lc, uint ls, uint es)
{
return ((ec << 24) & 0xFF000000)
| ((lc << 16) & 0x00FF0000)
| ((ls << 8) & 0x0000FF00)
| (es & 0xFF);
}
/* /*
* Wait for IFLG to raise, or return 'timeout'; then if status is as expected, * Wait for IFLG to raise, or return 'timeout'; then if status is as expected,
@@ -173,15 +210,15 @@ static int twsi_wait(struct i2c_adapter *adap, int expected_status)
if (status == expected_status) if (status == expected_status)
return 0; return 0;
else else
return MVTWSI_ERROR( return mvtwsi_error(
MVTWSI_ERROR_WRONG_STATUS, MVTWSI_ERROR_WRONG_STATUS,
control, status, expected_status); control, status, expected_status);
} }
udelay(10); /* one clock cycle at 100 kHz */ udelay(10); /* one clock cycle at 100 kHz */
} while (timeout--); } while (timeout--);
status = readl(&twsi->status); status = readl(&twsi->status);
return MVTWSI_ERROR( return mvtwsi_error(MVTWSI_ERROR_TIMEOUT, control, status,
MVTWSI_ERROR_TIMEOUT, control, status, expected_status); expected_status);
} }
/* /*
@@ -265,7 +302,7 @@ static int twsi_stop(struct i2c_adapter *adap, int status)
control = readl(&twsi->control); control = readl(&twsi->control);
if (stop_status != MVTWSI_STATUS_IDLE) if (stop_status != MVTWSI_STATUS_IDLE)
if (status == 0) if (status == 0)
status = MVTWSI_ERROR( status = mvtwsi_error(
MVTWSI_ERROR_TIMEOUT, MVTWSI_ERROR_TIMEOUT,
control, status, MVTWSI_STATUS_IDLE); control, status, MVTWSI_STATUS_IDLE);
return status; return status;