blob: dc97cb19eabf3b1a8bc9b5cde9f7e9dc6b5a5ec8 [file] [edit]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <lib/ddk/debug.h>
#include <lib/ddk/metadata.h>
#include "gt6853.h"
namespace {
enum {
// These values are shared with the bootloader, and must be kept in sync.
kPanelTypeKdFiti9364 = 1,
kPanelTypeBoeFiti9364 = 2,
kPanelTypeInxFiti9364 = 3,
kPanelTypeKdFiti9365 = 4,
kPanelTypeBoeFiti9365 = 5,
kPanelTypeBoeSit7703 = 6,
};
// There are three config files, one for each DDIC. A config file may contain multiple configs; the
// correct one is chosen based on the sensor ID reported by the touch controller.
inline const char* PanelTypeToConfigPath(uint32_t panel_type_id) {
switch (panel_type_id) {
case kPanelTypeKdFiti9364:
case kPanelTypeBoeFiti9364:
case kPanelTypeInxFiti9364:
return GT6853_CONFIG_9364_PATH;
case kPanelTypeKdFiti9365:
case kPanelTypeBoeFiti9365:
return GT6853_CONFIG_9365_PATH;
case kPanelTypeBoeSit7703:
return GT6853_CONFIG_7703_PATH;
default:
return nullptr;
}
}
inline const char* PanelTypeToNameString(uint32_t panel_type_id) {
switch (panel_type_id) {
case kPanelTypeKdFiti9364:
return "kd_fiti9364";
case kPanelTypeBoeFiti9364:
return "boe_fiti9364";
case kPanelTypeInxFiti9364:
return "inx_fiti9364";
case kPanelTypeKdFiti9365:
return "kd_fiti9365";
case kPanelTypeBoeFiti9365:
return "boe_fiti9365";
case kPanelTypeBoeSit7703:
return "boe_sit7703";
default:
return "unknown";
}
}
} // namespace
namespace touch {
zx::result<fuchsia_mem::wire::Range> Gt6853Device::GetConfigFileVmo() {
size_t actual = 0;
uint32_t panel_type_id = 0;
zx_status_t status = DdkGetFragmentMetadata("pdev", DEVICE_METADATA_BOARD_PRIVATE, &panel_type_id,
sizeof(panel_type_id), &actual);
// The only case to let through is when metadata isn't provided, which could happen after
// netbooting. All other unexpected conditions are fatal, which should help them be discovered
// more easily.
if (status == ZX_ERR_NOT_FOUND) {
config_status_.Set("skipped, no metadata");
return zx::ok(fuchsia_mem::wire::Range{});
}
if (status != ZX_OK) {
zxlogf(ERROR, "Failed to get panel type: %d", status);
return zx::error(status);
}
if (actual != sizeof(panel_type_id)) {
zxlogf(ERROR, "Expected metadata size %zu, got %zu", sizeof(panel_type_id), actual);
return zx::error(ZX_ERR_INTERNAL);
}
panel_type_id_ = root_.CreateInt("panel_type_id", panel_type_id);
panel_type_ = root_.CreateString("panel_type", PanelTypeToNameString(panel_type_id));
// The panel should be identified correctly by the bootloader for P2 boards and beyond. This
// driver isn't be used on boards earlier than P2, so not finding the panel ID is an error.
const char* config_path = PanelTypeToConfigPath(panel_type_id);
if (!config_path) {
zxlogf(ERROR, "Failed to find config for panel type %u", panel_type_id);
return zx::error(ZX_ERR_INTERNAL);
}
// There's a chance we can proceed without a config, but we should always have one on Nelson, so
// error out if it can't be loaded.
fuchsia_mem::wire::Range config = {};
status = load_firmware(parent(), config_path, config.vmo.reset_and_get_address(), &config.size);
if (status != ZX_OK) {
zxlogf(ERROR, "Failed to load config binary: %d", status);
return zx::error(status);
}
return zx::ok(std::move(config));
}
} // namespace touch