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); }
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; }
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; }
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; }
static int cros_ec_probe(struct udevice *dev) { return cros_ec_register(dev); }
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" }, { } };
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; }