/* * Use a raw i2c transfer, since we need more bytes * than Linux I2C supports through smbus xfr (only 32).
*/
rc = i2c_transfer(psu->client->adapter, msg, 2);
pmbus_unlock(psu->client); if (rc < 0) return rc;
}
static ssize_t ibm_cffps_debugfs_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{ int i, rc; int *idxp = file->private_data; int idx = *idxp; struct ibm_cffps *psu = to_psu(idxp, idx); char data[I2C_SMBUS_BLOCK_MAX + 2] = { 0 };
rc = pmbus_lock_interruptible(psu->client); if (rc) return rc;
rc = pmbus_set_page(psu->client, 0, 0xff); if (rc) goto unlock;
switch (idx) { case CFFPS_DEBUGFS_MAX_POWER_OUT: if (psu->version == cffps1)
rc = i2c_smbus_read_word_swapped(psu->client, PMBUS_MFR_POUT_MAX); else
rc = i2c_smbus_read_word_data(psu->client, PMBUS_MFR_POUT_MAX); if (rc >= 0)
rc = snprintf(data, I2C_SMBUS_BLOCK_MAX, "%d", rc); break; case CFFPS_DEBUGFS_CCIN:
rc = i2c_smbus_read_word_swapped(psu->client, CFFPS_CCIN_CMD); if (rc >= 0)
rc = snprintf(data, 5, "%04X", rc); break; case CFFPS_DEBUGFS_FW: switch (psu->version) { case cffps1: for (i = 0; i < CFFPS1_FW_NUM_BYTES; ++i) {
rc = i2c_smbus_read_byte_data(psu->client, CFFPS_FW_CMD + i); if (rc < 0) goto unlock;
snprintf(&data[i * 2], 3, "%02X", rc);
}
rc = i * 2; break; case cffps2: for (i = 0; i < CFFPS2_FW_NUM_WORDS; ++i) {
rc = i2c_smbus_read_word_data(psu->client, CFFPS_FW_CMD + i); if (rc < 0) goto unlock;
staticint ibm_cffps_read_byte_data(struct i2c_client *client, int page, int reg)
{ int rc, mfr;
switch (reg) { case PMBUS_STATUS_VOUT: case PMBUS_STATUS_IOUT: case PMBUS_STATUS_TEMPERATURE: case PMBUS_STATUS_FAN_12:
rc = pmbus_read_byte_data(client, page, reg); if (rc < 0) return rc;
mfr = pmbus_read_byte_data(client, page,
PMBUS_STATUS_MFR_SPECIFIC); if (mfr < 0) /* * Return the status register instead of an error, * since we successfully read status.
*/ return rc;
/* Add MFR_SPECIFIC bits to the standard pmbus status regs. */ if (reg == PMBUS_STATUS_FAN_12) { if (mfr & CFFPS_MFR_FAN_FAULT)
rc |= PB_FAN_FAN1_FAULT;
} elseif (reg == PMBUS_STATUS_TEMPERATURE) { if (mfr & CFFPS_MFR_THERMAL_FAULT)
rc |= PB_TEMP_OT_FAULT;
} elseif (reg == PMBUS_STATUS_VOUT) { if (mfr & (CFFPS_MFR_OV_FAULT | CFFPS_MFR_VAUX_FAULT))
rc |= PB_VOLTAGE_OV_FAULT; if (mfr & CFFPS_MFR_UV_FAULT)
rc |= PB_VOLTAGE_UV_FAULT;
} elseif (reg == PMBUS_STATUS_IOUT) { if (mfr & CFFPS_MFR_OC_FAULT)
rc |= PB_IOUT_OC_FAULT; if (mfr & CFFPS_MFR_CURRENT_SHARE_WARNING)
rc |= PB_CURRENT_SHARE_FAULT;
} break; default:
rc = -ENODATA; break;
}
return rc;
}
staticint ibm_cffps_read_word_data(struct i2c_client *client, int page, int phase, int reg)
{ int rc, mfr;
switch (reg) { case PMBUS_STATUS_WORD:
rc = pmbus_read_word_data(client, page, phase, reg); if (rc < 0) return rc;
mfr = pmbus_read_byte_data(client, page,
PMBUS_STATUS_MFR_SPECIFIC); if (mfr < 0) /* * Return the status register instead of an error, * since we successfully read status.
*/ return rc;
rc = i2c_smbus_read_block_data(client, PMBUS_MFR_ID, mfg_id); if (rc < 0) {
dev_err(&client->dev, "Failed to read Manufacturer ID\n"); return rc;
}
switch (ccin_version) { default: case CFFPS_CCIN_VERSION_1: if ((strncmp(mfg_id, "ACBE", 4) == 0) ||
(strncmp(mfg_id, "ARTE", 4) == 0))
vs = cffps1; else
vs = cffps2; break; case CFFPS_CCIN_VERSION_2:
vs = cffps2; break; case CFFPS_CCIN_VERSION_3: if (ccin_revision == CFFPS_CCIN_REVISION_LEGACY)
vs = cffps1; else
vs = cffps2; break;
}
/* Set the client name to include the version number. */
snprintf(client->name, I2C_NAME_SIZE, "cffps%d", vs + 1);
}
/* * Don't fail the probe if there isn't enough memory for leds and * debugfs.
*/
psu = devm_kzalloc(&client->dev, sizeof(*psu), GFP_KERNEL); if (!psu) return 0;
psu->version = vs;
psu->client = client;
ibm_cffps_create_led_class(psu);
/* Don't fail the probe if we can't create debugfs */
debugfs = pmbus_get_debugfs_dir(client); if (!debugfs) return 0;
for (i = 0; i < CFFPS_DEBUGFS_NUM_ENTRIES; ++i)
psu->debugfs_entries[i] = i;
MODULE_AUTHOR("Eddie James");
MODULE_DESCRIPTION("PMBus driver for IBM Common Form Factor power supplies");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS("PMBUS");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.