i2c: Factor our send() and recv() common logic
Most of the control flow logic between send and recv (error checking etc) is the same. Factor this out into a common send_recv() API. This is then usable by clients, where the control logic for send and receive differs only by a boolean. E.g. if (send) i2c_send(...): else i2c_recv(...); becomes: i2c_send_recv(... , send); Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com> Reviewed-by: Alistair Francis <alistair.francis@xilinx.com> Signed-off-by: KONRAD Frederic <fred.konrad@greensocs.com> Message-id: 1465833014-21982-4-git-send-email-fred.konrad@greensocs.com Changes from FK: * Rebased on master. * Rebased on my i2c broadcast patch. Signed-off-by: KONRAD Frederic <fred.konrad@greensocs.com> Reviewed-by: Alistair Francis <alistair.francis@xilinx.com> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
		
							parent
							
								
									2293c27fad
								
							
						
					
					
						commit
						056fca7b51
					
				| @ -149,36 +149,52 @@ void i2c_end_transfer(I2CBus *bus) | ||||
|     bus->broadcast = false; | ||||
| } | ||||
| 
 | ||||
| int i2c_send(I2CBus *bus, uint8_t data) | ||||
| int i2c_send_recv(I2CBus *bus, uint8_t *data, bool send) | ||||
| { | ||||
|     I2CSlaveClass *sc; | ||||
|     I2CNode *node; | ||||
|     int ret = 0; | ||||
| 
 | ||||
|     QLIST_FOREACH(node, &bus->current_devs, next) { | ||||
|         sc = I2C_SLAVE_GET_CLASS(node->elt); | ||||
|         if (sc->send) { | ||||
|             ret = ret || sc->send(node->elt, data); | ||||
|         } else { | ||||
|             ret = -1; | ||||
|     if (send) { | ||||
|         QLIST_FOREACH(node, &bus->current_devs, next) { | ||||
|             sc = I2C_SLAVE_GET_CLASS(node->elt); | ||||
|             if (sc->send) { | ||||
|                 ret = ret || sc->send(node->elt, *data); | ||||
|             } else { | ||||
|                 ret = -1; | ||||
|             } | ||||
|         } | ||||
|         return ret ? -1 : 0; | ||||
|     } else { | ||||
|         if ((QLIST_EMPTY(&bus->current_devs)) || (bus->broadcast)) { | ||||
|             return -1; | ||||
|         } | ||||
| 
 | ||||
|         sc = I2C_SLAVE_GET_CLASS(QLIST_FIRST(&bus->current_devs)->elt); | ||||
|         if (sc->recv) { | ||||
|             ret = sc->recv(QLIST_FIRST(&bus->current_devs)->elt); | ||||
|             if (ret < 0) { | ||||
|                 return ret; | ||||
|             } else { | ||||
|                 *data = ret; | ||||
|                 return 0; | ||||
|             } | ||||
|         } | ||||
|         return -1; | ||||
|     } | ||||
|     return ret ? -1 : 0; | ||||
| } | ||||
| 
 | ||||
| int i2c_send(I2CBus *bus, uint8_t data) | ||||
| { | ||||
|     return i2c_send_recv(bus, &data, true); | ||||
| } | ||||
| 
 | ||||
| int i2c_recv(I2CBus *bus) | ||||
| { | ||||
|     I2CSlaveClass *sc; | ||||
|     uint8_t data; | ||||
|     int ret = i2c_send_recv(bus, &data, false); | ||||
| 
 | ||||
|     if ((QLIST_EMPTY(&bus->current_devs)) || (bus->broadcast)) { | ||||
|         return -1; | ||||
|     } | ||||
| 
 | ||||
|     sc = I2C_SLAVE_GET_CLASS(QLIST_FIRST(&bus->current_devs)->elt); | ||||
|     if (sc->recv) { | ||||
|         return sc->recv(QLIST_FIRST(&bus->current_devs)->elt); | ||||
|     } | ||||
|     return -1; | ||||
|     return ret < 0 ? ret : data; | ||||
| } | ||||
| 
 | ||||
| void i2c_nack(I2CBus *bus) | ||||
|  | ||||
| @ -56,6 +56,7 @@ int i2c_bus_busy(I2CBus *bus); | ||||
| int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv); | ||||
| void i2c_end_transfer(I2CBus *bus); | ||||
| void i2c_nack(I2CBus *bus); | ||||
| int i2c_send_recv(I2CBus *bus, uint8_t *data, bool send); | ||||
| int i2c_send(I2CBus *bus, uint8_t data); | ||||
| int i2c_recv(I2CBus *bus); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Peter Crosthwaite
						Peter Crosthwaite