예제 #1
0
static void nct5572d_init(struct device *dev)
{
	uint8_t byte;
	uint8_t power_status;
	uint8_t mouse_detected;

	if (!dev->enabled)
		return;

	switch (dev->path.pnp.device) {
	/* TODO: Might potentially need code for HWM or FDC etc. */
	case NCT5572D_KBC:
		/* Enable mouse controller */
		pnp_enter_conf_mode_8787(dev);
		byte = pnp_read_config(dev, 0x2a);
		byte &= ~(0x1 << 1);
		pnp_write_config(dev, 0x2a, byte);
		pnp_exit_conf_mode_aa(dev);

		mouse_detected = pc_keyboard_init(PROBE_AUX_DEVICE);

		if (!mouse_detected) {
			printk(BIOS_INFO, "%s: Disable mouse controller.",
					__func__);
			pnp_enter_conf_mode_8787(dev);
			byte = pnp_read_config(dev, 0x2a);
			byte |= 0x1 << 1;
			pnp_write_config(dev, 0x2a, byte);
			pnp_exit_conf_mode_aa(dev);
		}
		break;
	case NCT5572D_ACPI:
		/* Set power state after power fail */
		power_status = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
		get_option(&power_status, "power_on_after_fail");
		pnp_enter_conf_mode_8787(dev);
		pnp_set_logical_device(dev);
		byte = pnp_read_config(dev, 0xe4);
		byte &= ~0x60;
		if (power_status == 1)
			byte |= (0x1 << 5);    /* Force power on */
		else if (power_status == 2)
			byte |= (0x2 << 5);    /* Use last power state */
		pnp_write_config(dev, 0xe4, byte);
		pnp_exit_conf_mode_aa(dev);
		printk(BIOS_INFO, "set power %s after power fail\n", power_status ? "on" : "off");
		break;
	}
}
예제 #2
0
/**
 * Enable the logical devices of the Super I/O chip.
 *
 * TODO: Think about how to handle the case when a mainboard has multiple
 *       Super I/O chips soldered on.
 * TODO: Can this code be simplified a bit?
 *
 * @param dev The device to use.
 */
static void enable_dev(struct device *dev)
{
	int i, j, fn;
	int tmp[MAX_LOGICAL_DEVICES];
	u8 test7;

	if (first_time) {

		pnp_enter_conf_mode_55(dev);

		/* Read the device ID and revision of the Super I/O chip. */
		superio_id = pnp_read_config(dev, DEVICE_ID_REG);
		superio_rev = pnp_read_config(dev, DEVICE_REV_REG);

		/* TODO: Error handling? */

		printk(BIOS_INFO, "Found SMSC Super I/O (ID = 0x%02x, "
		       "rev = 0x%02x)\n", superio_id, superio_rev);
		first_time = 0;

		if (superio_id == LPC47M172) {
			/*
			 * Do not use the default logical device number but
			 * instead the standard SMSC registers set.
			 */

			/*
			 * TEST7 configuration register (0x29)
			 * Bit 0: LD_NUM (0 = new, 1 = std SMSC)
			 */
			test7 = pnp_read_config(dev, DEVICE_TEST7_REG);
			test7 |= (1 << 0);
			pnp_write_config(dev, DEVICE_TEST7_REG, test7);
		}

		pnp_exit_conf_mode_aa(dev);
	}

	/* Find the correct Super I/O. */
	for (i = 0; i < ARRAY_SIZE(logical_device_table); i++)
		if (logical_device_table[i].superio_id == superio_id)
			break;

	/* If no Super I/O was found, return. */
	if (i == ARRAY_SIZE(logical_device_table))
		return;

	/* Temporarily save the LD_FOO values. */
	for (j = 0; j < ARRAY_SIZE(pnp_dev_info); j++)
		tmp[j] = pnp_dev_info[j].function;

	/*
	 * Replace the LD_FOO markers in pnp_dev_info[] with
	 * the real logical device IDs of this Super I/O chip.
	 */
	for (j = 0; j < ARRAY_SIZE(pnp_dev_info); j++) {
		fn = pnp_dev_info[j].function;
		pnp_dev_info[j].function = logical_device_table[i].devs[fn];
	}

	/* Enable the specified devices (if present on the chip). */
	pnp_enable_devices(dev, &ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info);

	/* Restore LD_FOO values. */
	for (j = 0; j < ARRAY_SIZE(pnp_dev_info); j++)
		pnp_dev_info[j].function = tmp[j];
}