/*
 *
 * Copyright (C) 2012-2019, Samsung Electronics Co., Ltd.
 *
 * RMI4 library header file
 */

#ifndef __TSU_RMI_H__
#define __TSU_RMI_H__

#include <tee_internal_api.h>
#include <errno.h>
#include "base.h"
#include "dbg.h"

#define RMI_DBG(format, args...) dbgPrintf(format "\n", ##args)
#define RMI_ERR(format, args...) errPrintf(format "\n", ##args)

#define PACKED_STRUCT __attribute__ ((packed))

#define ERROR_RMI_OK         0
#define ERROR_RMI_NOMEM      (-ENOMEM)
#define ERROR_RMI_INVAL      (-EINVAL)
#define ERROR_RMI_FAILED     (-1)

/******************************************************************************
 * LOCAL TYPES
 ******************************************************************************/

enum finger_state_values {
    FN_NO_FINGER       = 0x00,
    FN_PRESENT         = 0x01,
    FN_PASSIVE_STYLUS  = 0x02,
    FN_PALM            = 0x03,
    FN_UNCLASSIFIED    = 0x04,
    FN_HOVER           = 0x05,
    FN_GLOVE           = 0x06
};

/*
 * @query_base_addr:   The RMI Query base address
 * @command_base_addr: The RMI Command base address
 * @control_base_addr: The RMI Control base address
 * @data_base_addr:    The RMI Data base address
 * @interrupt_source_count: The number of irqs this RMI function needs
 * @function_number:   The RMI function number
 * @num_of_irqs:       The number of irqs needed by this function
 * @irq_pos:           The position in the irq bitfield this function holds
 */
typedef struct {
    uint16_t query_base_addr;
    uint16_t command_base_addr;
    uint16_t control_base_addr;
    uint16_t data_base_addr;
    uint8_t interrupt_source_count;
    uint8_t function_number;

    int num_of_irqs;
    int irq_pos;
} rmi_function_descriptor_t;

struct rmi_device;
typedef struct rmi_device rmi_device_t;

/*
 * @func:      The RMI function number
 * @rmi_dev:   Pointer to the RMI device associated with this function container
 * @fd:        RMI function base addresses
 * @init:      Callback for RMI function init
 * @attention: Callback for RMI function attention
 * @suspend:   Callback for RMI function suspend
 * @resume:    Callback for RMI function resume
 * @remove:    Callback for RMI function removal
 * @data:      Private data pointer
 *
 */
struct rmi_function_container {
    int func;
    rmi_device_t *rmi_dev;
    rmi_function_descriptor_t fd;

    int (*init)(struct rmi_function_container *fc);
    int (*attention)(struct rmi_function_container *fc, uint8_t irq_bits);
    void (*remove)(struct rmi_function_container *fc);

    void *data;
};

typedef struct rmi_function_container rmi_function_container_t;

#define RMI_FUNCTIONS_COUNT         8
#define RMI_PRODUCT_ID_LENGTH       10

/*
 * @i2c_read:  Callback for i2c read function
 * @i2c_write: Callback for i2c read function
 * @rmi_functions: RMI functions list
 * @max_x:     Max X value
 * @max_y:     Max Y value
 * @page:      Current RMI page number
 * @manufacturer_id: Controller manufacturer id
 * @product_id: Product ID
 *
 */
struct rmi_device {
    int (*i2c_read)(uint16_t addr, uint8_t *data, uint16_t size);
    int (*i2c_write)(uint16_t addr, uint8_t *data, uint16_t size);
    rmi_function_container_t *rmi_functions[RMI_FUNCTIONS_COUNT];
    int max_x;
    int max_y;
    int page;
    uint8_t manufacturer_id;
    uint8_t product_id[RMI_PRODUCT_ID_LENGTH + 1];    /* product id + null termination */
};

/******************************************************************************
 * EXPORTED FUNCTIONS
 ******************************************************************************/

/* Transport level functions */
int rmi_transport_init(rmi_device_t *rmi_dev);
int rmi_read_byte(rmi_device_t *rmi_dev, uint16_t addr, uint8_t *buf);
int rmi_read_block(rmi_device_t *rmi_dev, uint16_t addr, uint8_t *buf, int len);
int rmi_write_byte(rmi_device_t *rmi_dev, uint16_t addr, uint8_t data);
int rmi_write_block(rmi_device_t *rmi_dev, uint16_t addr, uint8_t *buf, int len);

/* Bus level functions */
rmi_function_container_t *rmi_bus_get_function(rmi_device_t *rmi_dev, int id);
int rmi_bus_register_function(rmi_device_t *rmi_dev, rmi_function_container_t *fc, rmi_function_descriptor_t *fd);
int rmi_bus_unregister_function(rmi_device_t *rmi_dev, rmi_function_container_t *fc);
void rmi_bus_unregister_all(rmi_device_t *rmi_dev);

/* RMI function registration entry's */
int rmi_fn01_register(rmi_device_t *rmi_dev, rmi_function_descriptor_t *fd);
int rmi_fn11_register(rmi_device_t *rmi_dev, rmi_function_descriptor_t *fd);
int rmi_fn12_register(rmi_device_t *rmi_dev, rmi_function_descriptor_t *fd);

#endif  /*  __TSU_RMI_H__ */
