Skip to content

Commit d90d71c

Browse files
ShLiTTcfriedt
authored andcommitted
drivers: smbus: stm32: implement smbus_block_read
Smbus implementation for stm32 lacks of smbus_block_read(), so add the functionality. Fix some indentations. Signed-off-by: Andrew Lewycky <[email protected]> Signed-off-by: Sherry Li <[email protected]>
1 parent 7fc8051 commit d90d71c

File tree

1 file changed

+39
-3
lines changed

1 file changed

+39
-3
lines changed

drivers/smbus/smbus_stm32.c

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ static int smbus_stm32_word_data_read(const struct device *dev, uint16_t periph_
204204
int result;
205205

206206
result = i2c_write_read(config->i2c_dev, periph_addr, &command, sizeof(command), word,
207-
sizeof(*word));
207+
sizeof(*word));
208208
*word = sys_le16_to_cpu(*word);
209209

210210
return result;
@@ -221,7 +221,7 @@ static int smbus_stm32_pcall(const struct device *dev, uint16_t periph_addr, uin
221221
sys_put_le16(send_word, buffer + 1);
222222

223223
result = i2c_write_read(config->i2c_dev, periph_addr, buffer, ARRAY_SIZE(buffer), recv_word,
224-
sizeof(*recv_word));
224+
sizeof(*recv_word));
225225
*recv_word = sys_le16_to_cpu(*recv_word);
226226

227227
return result;
@@ -252,6 +252,42 @@ static int smbus_stm32_block_write(const struct device *dev, uint16_t periph_add
252252
return i2c_transfer(config->i2c_dev, messages, ARRAY_SIZE(messages), periph_addr);
253253
}
254254

255+
static int smbus_stm32_block_read(const struct device *dev, uint16_t periph_addr, uint8_t command,
256+
uint8_t *count, uint8_t *buf)
257+
{
258+
const struct smbus_stm32_config *config = dev->config;
259+
260+
struct i2c_msg messages[] = {
261+
{
262+
.buf = &command,
263+
.len = sizeof(command),
264+
.flags = I2C_MSG_WRITE,
265+
},
266+
{
267+
.buf = NULL, /* will point to next message's len field */
268+
.len = 1,
269+
.flags = I2C_MSG_READ | I2C_MSG_RESTART,
270+
},
271+
{
272+
.buf = buf,
273+
.len = 0, /* written by previous message! */
274+
.flags = I2C_MSG_READ,
275+
}
276+
};
277+
278+
/* Count is read in msg 1 and stored in the len of msg 2.
279+
* This works because the STM I2C driver processes each message serially.
280+
* The addressing math assumes little-endian.
281+
*/
282+
messages[1].buf = (uint8_t *)&messages[2].len;
283+
284+
int res = i2c_transfer(config->i2c_dev, messages, ARRAY_SIZE(messages), periph_addr);
285+
286+
*count = messages[2].len;
287+
288+
return res;
289+
}
290+
255291
static DEVICE_API(smbus, smbus_stm32_api) = {
256292
.configure = smbus_stm32_configure,
257293
.get_config = smbus_stm32_get_config,
@@ -264,14 +300,14 @@ static DEVICE_API(smbus, smbus_stm32_api) = {
264300
.smbus_word_data_read = smbus_stm32_word_data_read,
265301
.smbus_pcall = smbus_stm32_pcall,
266302
.smbus_block_write = smbus_stm32_block_write,
303+
.smbus_block_read = smbus_stm32_block_read,
267304
#ifdef CONFIG_SMBUS_STM32_SMBALERT
268305
.smbus_smbalert_set_cb = smbus_stm32_smbalert_set_cb,
269306
.smbus_smbalert_remove_cb = smbus_stm32_smbalert_remove_cb,
270307
#else
271308
.smbus_smbalert_set_cb = NULL,
272309
.smbus_smbalert_remove_cb = NULL,
273310
#endif /* CONFIG_SMBUS_STM32_SMBALERT */
274-
.smbus_block_read = NULL,
275311
.smbus_block_pcall = NULL,
276312
.smbus_host_notify_set_cb = NULL,
277313
.smbus_host_notify_remove_cb = NULL,

0 commit comments

Comments
 (0)