diff --git a/smbus_rw.c b/smbus_rw.c
index 2f87f2a..757e24c 100644
--- a/smbus_rw.c
+++ b/smbus_rw.c
@@ -32,7 +32,8 @@ enum SMBUS_SIZE
{
SMBUS_SIZE_8 = SIZE8,
SMBUS_SIZE_16 = SIZE16,
- SMBUS_SIZE_BLOCK
+ SMBUS_SIZE_BLOCK,
+ SMBUS_SIZE_BYTE,
};
typedef union {
@@ -96,7 +97,8 @@ parse_uint8(const char *arg, uint8_t *ret)
* and write. It will parse the comand line arguments and open the appropriate
* i2c device. It returns 1 on success, 0 on failure. */
static int
-smbus_prologue(const char *argv[], struct smbus_op_params *params)
+smbus_prologue(const char *argv[], struct smbus_op_params *params,
+ const struct smbus_op *op)
{
if (parse_uint8(argv[1], ¶ms->i2c_bus)) {
fprintf(stderr, "invalid adapter value\n");
@@ -106,9 +108,14 @@ smbus_prologue(const char *argv[], struct smbus_op_params *params)
fprintf(stderr, "invalid address value\n");
return -1;
}
- if (parse_uint8(argv[3], ¶ms->reg)) {
- fprintf(stderr, "invalid register value\n");
- return -1;
+
+ /* Only obtain the register if size designates that it is not a byte
+ * operation. */
+ if (op->size != SMBUS_SIZE_BYTE) {
+ if (parse_uint8(argv[3], ¶ms->reg)) {
+ fprintf(stderr, "invalid register value\n");
+ return -1;
+ }
}
params->fd = open_i2c_slave(params->i2c_bus, params->address);
@@ -128,7 +135,7 @@ smbus_read(int argc, const char *argv[], const struct cmd_info *info)
const struct smbus_op *op =
(const struct smbus_op *)info->privdata;
- if (smbus_prologue(argv, ¶ms) < 0) {
+ if (smbus_prologue(argv, ¶ms, op) < 0) {
return -1;
}
@@ -157,6 +164,10 @@ smbus_read_op(struct smbus_op_params *params, const struct smbus_op *op)
result = i2c_smbus_read_block_data(params->fd,
params->reg, params->data.array) - 1;
break;
+ case SMBUS_SIZE_BYTE:
+ result = i2c_smbus_read_byte(params->fd);
+ params->data.fixed.u8 = result;
+ break;
default:
fprintf(stderr, "Illegal SMBus size for read operation.\n");
return -1;
@@ -172,6 +183,7 @@ smbus_read_op(struct smbus_op_params *params, const struct smbus_op *op)
/* print out the data read. */
switch (op->size) {
+ case SMBUS_SIZE_BYTE:
case SMBUS_SIZE_8:
printf("0x%02X\n", params->data.fixed.u8);
break;
@@ -199,6 +211,7 @@ parse_io_width(const char *arg, struct smbus_op_params *params,
char *end;
switch (op->size) {
+ case SMBUS_SIZE_BYTE:
case SMBUS_SIZE_8:
ldata = strtoul(arg, &end, 0);
if (ldata == LONG_MAX || *end != '\0') {
@@ -252,12 +265,19 @@ smbus_write(int argc, const char *argv[], const struct cmd_info *info)
struct smbus_op_params params;
const struct smbus_op *op =
(const struct smbus_op *)info->privdata;
+ /* All SMBus write operations use argv[4] except for the send_byte
+ * operation which uses 3. */
+ int arg_num = 4;
- if (smbus_prologue(argv, ¶ms) < 0) {
+ if (smbus_prologue(argv, ¶ms, op) < 0) {
return -1;
}
- if (parse_io_width(argv[4], ¶ms, op) < 0 ) {
+ if (op->size == SMBUS_SIZE_BYTE) {
+ arg_num = 3;
+ }
+
+ if (parse_io_width(argv[arg_num], ¶ms, op) < 0 ) {
fprintf(stderr, "invalid value to write\n");
return -1;
}
@@ -295,6 +315,10 @@ smbus_write_op(struct smbus_op_params *params, const struct smbus_op *op)
result = i2c_smbus_write_block_data(params->fd, params->reg,
params->len, params->data.array);
break;
+ case SMBUS_SIZE_BYTE:
+ result = i2c_smbus_write_byte(params->fd,
+ params->data.fixed.u8);
+ break;
default:
fprintf(stderr, "Illegal SMBus size for write operation.\n");
return -1;
@@ -313,6 +337,10 @@ MAKE_PREREQ_PARAMS_FIXED_ARGS(smbus_read_params, 4,
"<adapter> <address> <register>", 0);
MAKE_PREREQ_PARAMS_FIXED_ARGS(smbus_write_params, 5,
"<adapter> <address> <register> <value>", 0);
+MAKE_PREREQ_PARAMS_FIXED_ARGS(smbus_receive_byte_params, 3,
+ "<adapter> <address>", 0);
+MAKE_PREREQ_PARAMS_FIXED_ARGS(smbus_send_byte_params, 4,
+ "<adapter> <address> <value>", 0);
#define MAKE_SMBUS_OP(name_, size_, fn_) \
static const struct smbus_op name_ = { \
@@ -326,6 +354,7 @@ MAKE_PREREQ_PARAMS_FIXED_ARGS(smbus_write_params, 5,
MAKE_SMBUS_RW_OP(smbus_op_8, 8, smbus_read_op, smbus_write_op);
MAKE_SMBUS_RW_OP(smbus_op_16, 16, smbus_read_op, smbus_write_op);
MAKE_SMBUS_RW_OP(smbus_op_block, BLOCK, smbus_read_op, smbus_write_op);
+MAKE_SMBUS_RW_OP(smbus_op_byte, BYTE, smbus_read_op, smbus_write_op);
#define MAKE_SMBUS_RW_CMDS(size_) \
MAKE_CMD_WITH_PARAMS(smbus_read ##size_, smbus_read, \
@@ -337,6 +366,10 @@ static const struct cmd_info smbus_cmds[] = {
MAKE_SMBUS_RW_CMDS(8),
MAKE_SMBUS_RW_CMDS(16),
MAKE_SMBUS_RW_CMDS(block),
+ MAKE_CMD_WITH_PARAMS(smbus_recieve_byte, smbus_read,
+ &smbus_op_byte_r, &smbus_receive_byte_params),
+ MAKE_CMD_WITH_PARAMS(smbus_send_byte, smbus_write,
+ &smbus_op_byte_w, &smbus_send_byte_params),
};
MAKE_CMD_GROUP(SMBus, "commands to access the system management bus",