in pc87360.c [1395:1533]
static void pc87360_init_device(struct platform_device *pdev,
int use_thermistors)
{
struct pc87360_data *data = platform_get_drvdata(pdev);
int i, nr;
const u8 init_in[14] = { 2, 2, 2, 2, 2, 2, 2, 1, 1, 3, 1, 2, 2, 2 };
const u8 init_temp[3] = { 2, 2, 1 };
u8 reg;
if (init >= 2 && data->innr) {
reg = pc87360_read_value(data, LD_IN, NO_BANK,
PC87365_REG_IN_CONVRATE);
dev_info(&pdev->dev,
"VLM conversion set to 1s period, 160us delay\n");
pc87360_write_value(data, LD_IN, NO_BANK,
PC87365_REG_IN_CONVRATE,
(reg & 0xC0) | 0x11);
}
nr = data->innr < 11 ? data->innr : 11;
for (i = 0; i < nr; i++) {
reg = pc87360_read_value(data, LD_IN, i,
PC87365_REG_IN_STATUS);
dev_dbg(&pdev->dev, "bios in%d status:0x%02x\n", i, reg);
if (init >= init_in[i]) {
/* Forcibly enable voltage channel */
if (!(reg & CHAN_ENA)) {
dev_dbg(&pdev->dev, "Forcibly enabling in%d\n",
i);
pc87360_write_value(data, LD_IN, i,
PC87365_REG_IN_STATUS,
(reg & 0x68) | 0x87);
}
}
}
/*
* We can't blindly trust the Super-I/O space configuration bit,
* most BIOS won't set it properly
*/
dev_dbg(&pdev->dev, "bios thermistors:%d\n", use_thermistors);
for (i = 11; i < data->innr; i++) {
reg = pc87360_read_value(data, LD_IN, i,
PC87365_REG_TEMP_STATUS);
use_thermistors = use_thermistors || (reg & CHAN_ENA);
/* thermistors are temp[4-6], measured on vin[11-14] */
dev_dbg(&pdev->dev, "bios temp%d_status:0x%02x\n", i-7, reg);
}
dev_dbg(&pdev->dev, "using thermistors:%d\n", use_thermistors);
i = use_thermistors ? 2 : 0;
for (; i < data->tempnr; i++) {
reg = pc87360_read_value(data, LD_TEMP, i,
PC87365_REG_TEMP_STATUS);
dev_dbg(&pdev->dev, "bios temp%d_status:0x%02x\n", i + 1, reg);
if (init >= init_temp[i]) {
/* Forcibly enable temperature channel */
if (!(reg & CHAN_ENA)) {
dev_dbg(&pdev->dev,
"Forcibly enabling temp%d\n", i + 1);
pc87360_write_value(data, LD_TEMP, i,
PC87365_REG_TEMP_STATUS,
0xCF);
}
}
}
if (use_thermistors) {
for (i = 11; i < data->innr; i++) {
if (init >= init_in[i]) {
/*
* The pin may already be used by thermal
* diodes
*/
reg = pc87360_read_value(data, LD_TEMP,
(i - 11) / 2, PC87365_REG_TEMP_STATUS);
if (reg & CHAN_ENA) {
dev_dbg(&pdev->dev,
"Skipping temp%d, pin already in use by temp%d\n",
i - 7, (i - 11) / 2);
continue;
}
/* Forcibly enable thermistor channel */
reg = pc87360_read_value(data, LD_IN, i,
PC87365_REG_IN_STATUS);
if (!(reg & CHAN_ENA)) {
dev_dbg(&pdev->dev,
"Forcibly enabling temp%d\n",
i - 7);
pc87360_write_value(data, LD_IN, i,
PC87365_REG_TEMP_STATUS,
(reg & 0x60) | 0x8F);
}
}
}
}
if (data->innr) {
reg = pc87360_read_value(data, LD_IN, NO_BANK,
PC87365_REG_IN_CONFIG);
dev_dbg(&pdev->dev, "bios vin-cfg:0x%02x\n", reg);
if (reg & CHAN_ENA) {
dev_dbg(&pdev->dev,
"Forcibly enabling monitoring (VLM)\n");
pc87360_write_value(data, LD_IN, NO_BANK,
PC87365_REG_IN_CONFIG,
reg & 0xFE);
}
}
if (data->tempnr) {
reg = pc87360_read_value(data, LD_TEMP, NO_BANK,
PC87365_REG_TEMP_CONFIG);
dev_dbg(&pdev->dev, "bios temp-cfg:0x%02x\n", reg);
if (reg & CHAN_ENA) {
dev_dbg(&pdev->dev,
"Forcibly enabling monitoring (TMS)\n");
pc87360_write_value(data, LD_TEMP, NO_BANK,
PC87365_REG_TEMP_CONFIG,
reg & 0xFE);
}
if (init >= 2) {
/* Chip config as documented by National Semi. */
pc87360_write_value(data, LD_TEMP, 0xF, 0xA, 0x08);
/*
* We voluntarily omit the bank here, in case the
* sequence itself matters. It shouldn't be a problem,
* since nobody else is supposed to access the
* device at that point.
*/
pc87360_write_value(data, LD_TEMP, NO_BANK, 0xB, 0x04);
pc87360_write_value(data, LD_TEMP, NO_BANK, 0xC, 0x35);
pc87360_write_value(data, LD_TEMP, NO_BANK, 0xD, 0x05);
pc87360_write_value(data, LD_TEMP, NO_BANK, 0xE, 0x05);
}
}
}