@@ -73,6 +73,56 @@ static const struct nvmem_cell_info adm1266_nvmem_cells[] = {
DECLARE_CRC8_TABLE(pmbus_crc_table);
+/* PMBus Group command. */
+static int adm1266_pmbus_group_command(struct adm1266_data *data, struct i2c_client **clients,
+ u8 nr_clients, u8 cmd, u8 w_len, u8 *data_w)
+{
+ struct i2c_msg *msgs;
+ u8 addr;
+ int ret;
+ int i;
+
+ msgs = kcalloc(nr_clients, sizeof(struct i2c_msg), GFP_KERNEL);
+ if (!msgs)
+ return -ENOMEM;
+
+ for (i = 0; i < nr_clients; i++) {
+ msgs[i].addr = clients[i]->addr;
+ msgs[i].len = w_len + 1;
+
+ msgs[i].buf = kcalloc(ADM1266_PMBUS_BLOCK_MAX + 2, sizeof(u8), GFP_KERNEL);
+ if (!msgs[i].buf) {
+ ret = -ENOMEM;
+ goto cleanup;
+ }
+
+ msgs[i].buf[0] = cmd;
+ memcpy(&msgs[i].buf[1], data_w, w_len);
+
+ if (clients[i]->flags & I2C_CLIENT_PEC) {
+ u8 crc = 0;
+
+ addr = i2c_8bit_addr_from_msg(&msgs[i]);
+ crc = crc8(pmbus_crc_table, &addr, 1, crc);
+ crc = crc8(pmbus_crc_table, msgs[i].buf, msgs[i].len,
+ crc);
+
+ msgs[i].buf[msgs[i].len] = crc;
+ msgs[i].len++;
+ }
+ };
+
+ ret = i2c_transfer(data->client->adapter, msgs, nr_clients);
+
+cleanup:
+ for (i = i - 1; i >= 0; i--)
+ kfree(msgs[i].buf);
+
+ kfree(msgs);
+
+ return ret;
+}
+
/*
* Different from Block Read as it sends data and waits for the slave to
* return a value dependent on that data. The protocol is simply a Write Block