i2c:smbus: Correct the working of quick commands

The logic of handling quick SMBus commands was wrong.  If you get a
finish event with no data, that's a quick command.

Document the quick command while we are at it.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
master
Corey Minyard 2018-11-30 13:20:12 -06:00
parent bc15cde0c4
commit 905cec6d11
2 changed files with 24 additions and 16 deletions

View File

@ -54,9 +54,7 @@ static void smbus_do_write(SMBusDevice *dev)
{
SMBusDeviceClass *sc = SMBUS_DEVICE_GET_CLASS(dev);
if (dev->data_len == 0) {
smbus_do_quick_cmd(dev, 0);
} else if (dev->data_len == 1) {
if (dev->data_len == 1) {
DPRINTF("Send Byte\n");
if (sc->send_byte) {
sc->send_byte(dev, dev->data_buf[0]);
@ -120,19 +118,24 @@ static int smbus_i2c_event(I2CSlave *s, enum i2c_event event)
break;
case I2C_FINISH:
switch (dev->mode) {
case SMBUS_WRITE_DATA:
smbus_do_write(dev);
break;
case SMBUS_RECV_BYTE:
smbus_do_quick_cmd(dev, 1);
break;
case SMBUS_READ_DATA:
BADF("Unexpected stop during receive\n");
break;
default:
/* Nothing to do. */
break;
if (dev->data_len == 0) {
if (dev->mode == SMBUS_WRITE_DATA || dev->mode == SMBUS_READ_DATA) {
smbus_do_quick_cmd(dev, dev->mode == SMBUS_READ_DATA);
}
} else {
switch (dev->mode) {
case SMBUS_WRITE_DATA:
smbus_do_write(dev);
break;
case SMBUS_READ_DATA:
BADF("Unexpected stop during receive\n");
break;
default:
/* Nothing to do. */
break;
}
}
dev->mode = SMBUS_IDLE;
dev->data_len = 0;

View File

@ -40,6 +40,11 @@ typedef struct SMBusDevice SMBusDevice;
typedef struct SMBusDeviceClass
{
I2CSlaveClass parent_class;
/*
* An operation with no data, special in SMBus.
* This may be NULL, quick commands are ignore in that case.
*/
void (*quick_cmd)(SMBusDevice *dev, uint8_t read);
void (*send_byte)(SMBusDevice *dev, uint8_t val);
uint8_t (*receive_byte)(SMBusDevice *dev);