示例#1
0
int cros_ec_probe(struct udevice *dev)
{
	struct ec_state *ec = dev->priv;
	struct cros_ec_dev *cdev = dev->uclass_priv;
	const void *blob = gd->fdt_blob;
	struct udevice *keyb_dev;
	int node;
	int err;

	memcpy(ec, &s_state, sizeof(*ec));
	err = cros_ec_decode_ec_flash(blob, dev_of_offset(dev), &ec->ec_config);
	if (err)
		return err;

	node = -1;
	for (device_find_first_child(dev, &keyb_dev);
	     keyb_dev;
	     device_find_next_child(&keyb_dev)) {
		if (device_get_uclass_id(keyb_dev) == UCLASS_KEYBOARD) {
			node = dev_of_offset(keyb_dev);
			break;
		}
	}
	if (node < 0) {
		debug("%s: No cros_ec keyboard found\n", __func__);
	} else if (keyscan_read_fdt_matrix(ec, blob, node)) {
		debug("%s: Could not read key matrix\n", __func__);
		return -1;
	}

	/* If we loaded EC data, check that the length matches */
	if (ec->flash_data &&
	    ec->flash_data_len != ec->ec_config.flash.length) {
		printf("EC data length is %x, expected %x, discarding data\n",
		       ec->flash_data_len, ec->ec_config.flash.length);
		os_free(ec->flash_data);
		ec->flash_data = NULL;
	}

	/* Otherwise allocate the memory */
	if (!ec->flash_data) {
		ec->flash_data_len = ec->ec_config.flash.length;
		ec->flash_data = os_malloc(ec->flash_data_len);
		if (!ec->flash_data)
			return -ENOMEM;
	}

	cdev->dev = dev;
	g_state = ec;
	return cros_ec_register(dev);
}
示例#2
0
static int cros_ec_lpc_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct cros_ec_device *ec_dev;
	int ret;

	if (!devm_request_region(dev, EC_LPC_ADDR_MEMMAP, EC_MEMMAP_SIZE,
				 dev_name(dev))) {
		dev_err(dev, "couldn't reserve memmap region\n");
		return -EBUSY;
	}

	if ((inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID) != 'E') ||
	    (inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID + 1) != 'C')) {
		dev_err(dev, "EC ID not detected\n");
		return -ENODEV;
	}

	if (!devm_request_region(dev, EC_HOST_CMD_REGION0,
				 EC_HOST_CMD_REGION_SIZE, dev_name(dev))) {
		dev_err(dev, "couldn't reserve region0\n");
		return -EBUSY;
	}
	if (!devm_request_region(dev, EC_HOST_CMD_REGION1,
				 EC_HOST_CMD_REGION_SIZE, dev_name(dev))) {
		dev_err(dev, "couldn't reserve region1\n");
		return -EBUSY;
	}

	ec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL);
	if (!ec_dev)
		return -ENOMEM;

	platform_set_drvdata(pdev, ec_dev);
	ec_dev->dev = dev;
	ec_dev->ec_name = pdev->name;
	ec_dev->phys_name = dev_name(dev);
	ec_dev->parent = dev;
	ec_dev->cmd_xfer = cros_ec_cmd_xfer_lpc;
	ec_dev->cmd_readmem = cros_ec_lpc_readmem;

	ret = cros_ec_register(ec_dev);
	if (ret) {
		dev_err(dev, "couldn't register ec_dev (%d)\n", ret);
		return ret;
	}

	return 0;
}
示例#3
0
static int cros_ec_spi_probe(struct spi_device *spi)
{
	struct device *dev = &spi->dev;
	struct cros_ec_device *ec_dev;
	struct cros_ec_spi *ec_spi;
	int err;

	spi->bits_per_word = 8;
	spi->mode = SPI_MODE_0;
	err = spi_setup(spi);
	if (err < 0)
		return err;

	ec_spi = devm_kzalloc(dev, sizeof(*ec_spi), GFP_KERNEL);
	if (ec_spi == NULL)
		return -ENOMEM;
	ec_spi->spi = spi;
	ec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL);
	if (!ec_dev)
		return -ENOMEM;

	/* Check for any DT properties */
	cros_ec_spi_dt_probe(ec_spi, dev);

	spi_set_drvdata(spi, ec_dev);
	ec_dev->dev = dev;
	ec_dev->priv = ec_spi;
	ec_dev->irq = spi->irq;
	ec_dev->cmd_xfer = cros_ec_cmd_xfer_spi;
	ec_dev->pkt_xfer = cros_ec_pkt_xfer_spi;
	ec_dev->phys_name = dev_name(&ec_spi->spi->dev);
	ec_dev->din_size = EC_MSG_PREAMBLE_COUNT +
			   sizeof(struct ec_host_response) +
			   sizeof(struct ec_response_get_protocol_info);
	ec_dev->dout_size = sizeof(struct ec_host_request);


	err = cros_ec_register(ec_dev);
	if (err) {
		dev_err(dev, "cannot register EC\n");
		return err;
	}

	device_init_wakeup(&spi->dev, true);

	return 0;
}
示例#4
0
static int cros_ec_spi_probe(struct spi_device *spi)
{
	struct device *dev = &spi->dev;
	struct cros_ec_device *ec_dev;
	struct cros_ec_spi *ec_spi;
	int err;

	spi->bits_per_word = 8;
	spi->mode = SPI_MODE_0;
	err = spi_setup(spi);
	if (err < 0)
		return err;

	ec_spi = devm_kzalloc(dev, sizeof(*ec_spi), GFP_KERNEL);
	if (ec_spi == NULL)
		return -ENOMEM;
	ec_spi->spi = spi;
	mutex_init(&ec_spi->lock);
	ec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL);
	if (!ec_dev)
		return -ENOMEM;

	/* Check for any DT properties */
	cros_ec_spi_dt_probe(ec_spi, dev);

	spi_set_drvdata(spi, ec_dev);
	ec_dev->name = "SPI";
	ec_dev->dev = dev;
	ec_dev->priv = ec_spi;
	ec_dev->irq = spi->irq;
	ec_dev->command_xfer = cros_ec_command_spi_xfer;
	ec_dev->ec_name = ec_spi->spi->modalias;
	ec_dev->phys_name = dev_name(&ec_spi->spi->dev);
	ec_dev->parent = &ec_spi->spi->dev;
	ec_dev->din_size = EC_MSG_BYTES + EC_MSG_PREAMBLE_COUNT;
	ec_dev->dout_size = EC_MSG_BYTES;

	err = cros_ec_register(ec_dev);
	if (err) {
		dev_err(dev, "cannot register EC\n");
		return err;
	}

	return 0;
}
示例#5
0
static int cros_ec_probe(struct udevice *dev)
{
	return cros_ec_register(dev);
}
示例#6
0
int cros_ec_sandbox_packet(struct udevice *udev, int out_bytes, int in_bytes)
{
	struct cros_ec_dev *dev = udev->uclass_priv;
	struct ec_state *ec = dev_get_priv(dev->dev);
#else
int cros_ec_sandbox_packet(struct cros_ec_dev *dev, int out_bytes,
			   int in_bytes)
{
	struct ec_state *ec = &s_state;
#endif
	struct ec_host_request *req_hdr = (struct ec_host_request *)dev->dout;
	const void *req_data = req_hdr + 1;
	struct ec_host_response *resp_hdr = (struct ec_host_response *)dev->din;
	void *resp_data = resp_hdr + 1;
	int len;

	len = process_cmd(ec, req_hdr, req_data, resp_hdr, resp_data);
	if (len < 0)
		return len;

	resp_hdr->struct_version = 3;
	resp_hdr->result = EC_RES_SUCCESS;
	resp_hdr->data_len = len;
	resp_hdr->reserved = 0;
	len += sizeof(*resp_hdr);
	resp_hdr->checksum = 0;
	resp_hdr->checksum = (uint8_t)
		-cros_ec_calc_checksum((const uint8_t *)resp_hdr, len);

	return in_bytes;
}

int cros_ec_sandbox_decode_fdt(struct cros_ec_dev *dev, const void *blob)
{
	return 0;
}

void cros_ec_check_keyboard(struct cros_ec_dev *dev)
{
#ifdef CONFIG_DM_CROS_EC
	struct ec_state *ec = dev_get_priv(dev->dev);
#else
	struct ec_state *ec = &s_state;
#endif
	ulong start;

	printf("Press keys for EC to detect on reset (ESC=recovery)...");
	start = get_timer(0);
	while (get_timer(start) < 1000)
		;
	putc('\n');
	if (!sandbox_sdl_key_pressed(KEY_ESC)) {
		ec->recovery_req = true;
		printf("   - EC requests recovery\n");
	}
}

#ifdef CONFIG_DM_CROS_EC
int cros_ec_probe(struct udevice *dev)
{
	struct ec_state *ec = dev->priv;
	struct cros_ec_dev *cdev = dev->uclass_priv;
	const void *blob = gd->fdt_blob;
	int node;
	int err;

	memcpy(ec, &s_state, sizeof(*ec));
	err = cros_ec_decode_ec_flash(blob, dev->of_offset, &ec->ec_config);
	if (err)
		return err;

	node = fdtdec_next_compatible(blob, 0, COMPAT_GOOGLE_CROS_EC_KEYB);
	if (node < 0) {
		debug("%s: No cros_ec keyboard found\n", __func__);
	} else if (keyscan_read_fdt_matrix(ec, blob, node)) {
		debug("%s: Could not read key matrix\n", __func__);
		return -1;
	}

	/* If we loaded EC data, check that the length matches */
	if (ec->flash_data &&
	    ec->flash_data_len != ec->ec_config.flash.length) {
		printf("EC data length is %x, expected %x, discarding data\n",
		       ec->flash_data_len, ec->ec_config.flash.length);
		os_free(ec->flash_data);
		ec->flash_data = NULL;
	}

	/* Otherwise allocate the memory */
	if (!ec->flash_data) {
		ec->flash_data_len = ec->ec_config.flash.length;
		ec->flash_data = os_malloc(ec->flash_data_len);
		if (!ec->flash_data)
			return -ENOMEM;
	}

	cdev->dev = dev;
	g_state = ec;
	return cros_ec_register(dev);
}

#else

/**
 * Initialize sandbox EC emulation.
 *
 * @param dev		CROS_EC device
 * @param blob		Device tree blob
 * @return 0 if ok, -1 on error
 */
int cros_ec_sandbox_init(struct cros_ec_dev *dev, const void *blob)
{
	struct ec_state *ec = &s_state;
	int node;
	int err;

	node = fdtdec_next_compatible(blob, 0, COMPAT_GOOGLE_CROS_EC);
	if (node < 0) {
		debug("Failed to find chrome-ec node'\n");
		return -1;
	}

	err = cros_ec_decode_ec_flash(blob, node, &ec->ec_config);
	if (err)
		return err;

	node = fdtdec_next_compatible(blob, 0, COMPAT_GOOGLE_CROS_EC_KEYB);
	if (node < 0) {
		debug("%s: No cros_ec keyboard found\n", __func__);
	} else if (keyscan_read_fdt_matrix(ec, blob, node)) {
		debug("%s: Could not read key matrix\n", __func__);
		return -1;
	}

	/* If we loaded EC data, check that the length matches */
	if (ec->flash_data &&
	    ec->flash_data_len != ec->ec_config.flash.length) {
		printf("EC data length is %x, expected %x, discarding data\n",
		       ec->flash_data_len, ec->ec_config.flash.length);
		os_free(ec->flash_data);
		ec->flash_data = NULL;
	}

	/* Otherwise allocate the memory */
	if (!ec->flash_data) {
		ec->flash_data_len = ec->ec_config.flash.length;
		ec->flash_data = os_malloc(ec->flash_data_len);
		if (!ec->flash_data)
			return -ENOMEM;
	}

	return 0;
}
#endif

#ifdef CONFIG_DM_CROS_EC
struct dm_cros_ec_ops cros_ec_ops = {
	.packet = cros_ec_sandbox_packet,
};

static const struct udevice_id cros_ec_ids[] = {
	{ .compatible = "google,cros-ec" },
	{ }
};
示例#7
0
文件: cros_ec_lpc.c 项目: mdamt/linux
static int cros_ec_lpc_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct acpi_device *adev;
	acpi_status status;
	struct cros_ec_device *ec_dev;
	u8 buf[2];
	int ret;

	if (!devm_request_region(dev, EC_LPC_ADDR_MEMMAP, EC_MEMMAP_SIZE,
				 dev_name(dev))) {
		dev_err(dev, "couldn't reserve memmap region\n");
		return -EBUSY;
	}

	cros_ec_lpc_read_bytes(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID, 2, buf);
	if (buf[0] != 'E' || buf[1] != 'C') {
		dev_err(dev, "EC ID not detected\n");
		return -ENODEV;
	}

	if (!devm_request_region(dev, EC_HOST_CMD_REGION0,
				 EC_HOST_CMD_REGION_SIZE, dev_name(dev))) {
		dev_err(dev, "couldn't reserve region0\n");
		return -EBUSY;
	}
	if (!devm_request_region(dev, EC_HOST_CMD_REGION1,
				 EC_HOST_CMD_REGION_SIZE, dev_name(dev))) {
		dev_err(dev, "couldn't reserve region1\n");
		return -EBUSY;
	}

	ec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL);
	if (!ec_dev)
		return -ENOMEM;

	platform_set_drvdata(pdev, ec_dev);
	ec_dev->dev = dev;
	ec_dev->phys_name = dev_name(dev);
	ec_dev->cmd_xfer = cros_ec_cmd_xfer_lpc;
	ec_dev->pkt_xfer = cros_ec_pkt_xfer_lpc;
	ec_dev->cmd_readmem = cros_ec_lpc_readmem;
	ec_dev->din_size = sizeof(struct ec_host_response) +
			   sizeof(struct ec_response_get_protocol_info);
	ec_dev->dout_size = sizeof(struct ec_host_request);

	ret = cros_ec_register(ec_dev);
	if (ret) {
		dev_err(dev, "couldn't register ec_dev (%d)\n", ret);
		return ret;
	}

	/*
	 * Connect a notify handler to process MKBP messages if we have a
	 * companion ACPI device.
	 */
	adev = ACPI_COMPANION(dev);
	if (adev) {
		status = acpi_install_notify_handler(adev->handle,
						     ACPI_ALL_NOTIFY,
						     cros_ec_lpc_acpi_notify,
						     ec_dev);
		if (ACPI_FAILURE(status))
			dev_warn(dev, "Failed to register notifier %08x\n",
				 status);
	}

	return 0;
}