static void pc87360_init_device()

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);
		}
	}
}