blob: 1c3d0d5e2e72e9374bb2e5a92333dec113e07973 [file] [log] [blame]
// Copyright 2018 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.
#pragma once
#include <atomic>
#include <ddk/device.h>
#include <ddktl/device.h>
#include <ddktl/i2c-channel.h>
#include <ddktl/pdev.h>
#include <ddktl/protocol/gpio.h>
#include <ddktl/protocol/hidbus.h>
#include <fbl/mutex.h>
#include <hid/gt92xx.h>
#include <lib/zx/interrupt.h>
#include <threads.h>
#include <utility>
#include <zircon/types.h>
// clang-format off
#define GT_REG_SLEEP 0x8040
#define GT_REG_CONFIG_DATA 0x8047
#define GT_REG_MAX_X_LO 0x8048
#define GT_REG_MAX_X_HI 0x8049
#define GT_REG_MAX_Y_LO 0x804a
#define GT_REG_MAX_Y_HI 0x804b
#define GT_REG_NUM_FINGERS 0x804c
#define GT_REG_CONFIG_REFRESH 0x812a
#define GT_REG_VERSION 0x8140
#define GT_REG_SENSOR_ID 0x814a
#define GT_REG_TOUCH_STATUS 0x814e
#define GT_REG_REPORTS 0x814f
#define GT_REG_FIRMWARE 0x41e4
#define GT_FIRMWARE_MAGIC 0xbe
// clang-format on
namespace goodix {
class Gt92xxDevice : public ddk::Device<Gt92xxDevice, ddk::Unbindable>,
public ddk::HidbusProtocol<Gt92xxDevice, ddk::base_protocol> {
public:
Gt92xxDevice(zx_device_t* device, ddk::I2cChannel i2c,
ddk::GpioProtocolClient intr, ddk::GpioProtocolClient reset)
: ddk::Device<Gt92xxDevice, ddk::Unbindable>(device),
i2c_(std::move(i2c)), int_gpio_(std::move(intr)),
reset_gpio_(std::move(reset)){};
static zx_status_t Create(zx_device_t* device);
void DdkRelease();
void DdkUnbind() __TA_EXCLUDES(client_lock_);
// Hidbus required methods
void HidbusStop();
zx_status_t HidbusGetDescriptor(uint8_t desc_type, void** data, size_t* len);
zx_status_t HidbusGetReport(uint8_t rpt_type, uint8_t rpt_id, void* data,
size_t len, size_t* out_len);
zx_status_t HidbusSetReport(uint8_t rpt_type, uint8_t rpt_id, const void* data,
size_t len);
zx_status_t HidbusGetIdle(uint8_t rpt_id, uint8_t* duration);
zx_status_t HidbusSetIdle(uint8_t rpt_id, uint8_t duration);
zx_status_t HidbusGetProtocol(uint8_t* protocol);
zx_status_t HidbusSetProtocol(uint8_t protocol);
zx_status_t HidbusStart(const hidbus_ifc_t* ifc) __TA_EXCLUDES(client_lock_);
zx_status_t HidbusQuery(uint32_t options, hid_info_t* info) __TA_EXCLUDES(client_lock_);
private:
// Format of data as it is read from the device
struct FingerReport {
uint8_t id;
uint16_t x;
uint16_t y;
uint16_t size;
uint8_t reserved;
} __PACKED;
static constexpr uint32_t kMaxPoints = 5;
zx_status_t ShutDown() __TA_EXCLUDES(client_lock_);
// performs hardware reset using gpio
void HWReset();
zx_status_t Init();
uint8_t Read(uint16_t addr);
zx_status_t Read(uint16_t addr, uint8_t* buf, uint8_t len);
zx_status_t Write(uint16_t addr, uint8_t val);
int Thread();
ddk::I2cChannel i2c_;
ddk::GpioProtocolClient int_gpio_;
ddk::GpioProtocolClient reset_gpio_;
gt92xx_touch_t gt_rpt_ __TA_GUARDED(client_lock_);
zx::interrupt irq_;
thrd_t thread_;
std::atomic<bool> running_;
fbl::Mutex client_lock_;
ddk::HidbusIfcClient client_ __TA_GUARDED(client_lock_);
};
}