/*
 * Copyright (C) 2014 Andrew Duggan
 * Copyright (C) 2014 Synaptics Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdio.h>
#include <time.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>

#include "rmidevice.h"

#define RMI_DEVICE_PDT_ENTRY_SIZE		6
#define RMI_DEVICE_PAGE_SELECT_REGISTER		0xFF
#define RMI_DEVICE_MAX_PAGE			0xFF
#define RMI_DEVICE_PAGE_SIZE			0x100
#define RMI_DEVICE_PAGE_SCAN_START		0x00e9
#define RMI_DEVICE_PAGE_SCAN_END		0x0005
#define RMI_DEVICE_F01_BASIC_QUERY_LEN		11
#define RMI_DEVICE_F01_QRY5_YEAR_MASK		0x1f
#define RMI_DEVICE_F01_QRY6_MONTH_MASK		0x0f
#define RMI_DEVICE_F01_QRY7_DAY_MASK		0x1f

#define RMI_DEVICE_F01_QRY1_HAS_LTS		(1 << 2)
#define RMI_DEVICE_F01_QRY1_HAS_SENSOR_ID	(1 << 3)
#define RMI_DEVICE_F01_QRY1_HAS_CHARGER_INP	(1 << 4)
#define RMI_DEVICE_F01_QRY1_HAS_ADJ_DOZE	(1 << 5)
#define RMI_DEVICE_F01_QRY1_HAS_ADJ_DOZE_HOFF	(1 << 6)
#define RMI_DEVICE_F01_QRY1_HAS_PROPS_2		(1 << 7)

#define RMI_DEVICE_F01_LTS_RESERVED_SIZE	19

#define RMI_DEVICE_F01_QRY42_DS4_QUERIES	(1 << 0)
#define RMI_DEVICE_F01_QRY42_MULTI_PHYS		(1 << 1)

#define RMI_DEVICE_F01_QRY43_01_PACKAGE_ID     (1 << 0)
#define RMI_DEVICE_F01_QRY43_01_BUILD_ID       (1 << 1)

#define PACKAGE_ID_BYTES			4
#define CONFIG_ID_BYTES				4
#define BUILD_ID_BYTES				3

#define RMI_F01_CMD_DEVICE_RESET	1
#define RMI_F01_DEFAULT_RESET_DELAY_MS	100

int RMIDevice::SetRMIPage(unsigned char page)
{
	int rc;

	if (m_page == page)
		return 0;

	m_page = page;
	rc = Write(RMI_DEVICE_PAGE_SELECT_REGISTER, &page, 1);
	if (rc < 0 || rc < 1) {
		m_page = -1;
		return rc;
	}
	return 0;
}

int RMIDevice::QueryBasicProperties()
{
	int rc;
	unsigned char basicQuery[RMI_DEVICE_F01_BASIC_QUERY_LEN];
	unsigned char configid[CONFIG_ID_BYTES];
	unsigned short queryAddr;
	unsigned short controlAddr;
	unsigned char infoBuf[4];
	unsigned short prodInfoAddr;
	RMIFunction f01;
	RMIFunction f34;

	SetRMIPage(0x00);

	if (GetFunction(f01, 1)) {
		queryAddr = f01.GetQueryBase();

		rc = Read(queryAddr, basicQuery, RMI_DEVICE_F01_BASIC_QUERY_LEN);
		if (rc < 0 || rc < RMI_DEVICE_F01_BASIC_QUERY_LEN) {
			fprintf(stderr, "Failed to read the basic query: %s\n", strerror(errno));
			return rc;
		}
		m_manufacturerID = basicQuery[0];
		m_hasLTS = basicQuery[1] & RMI_DEVICE_F01_QRY1_HAS_LTS;
		m_hasSensorID = basicQuery[1] & RMI_DEVICE_F01_QRY1_HAS_SENSOR_ID;
		m_hasAdjustableDoze = basicQuery[1] & RMI_DEVICE_F01_QRY1_HAS_ADJ_DOZE;
		m_hasAdjustableDozeHoldoff = basicQuery[1] & RMI_DEVICE_F01_QRY1_HAS_ADJ_DOZE_HOFF;
		m_hasQuery42 = basicQuery[1] & RMI_DEVICE_F01_QRY1_HAS_PROPS_2;
		m_firmwareVersionMajor = basicQuery[2];
		m_firmwareVersionMinor = basicQuery[3];

		snprintf(m_dom, sizeof(m_dom), "20%02d/%02d/%02d",
				basicQuery[5] & RMI_DEVICE_F01_QRY5_YEAR_MASK,
		 		basicQuery[6] & RMI_DEVICE_F01_QRY6_MONTH_MASK,
		 		basicQuery[7] & RMI_DEVICE_F01_QRY7_DAY_MASK);

		queryAddr += 11;
		rc = Read(queryAddr, m_productID, RMI_PRODUCT_ID_LENGTH);
		if (rc < 0 || rc < RMI_PRODUCT_ID_LENGTH) {
			fprintf(stderr, "Failed to read the product id: %s\n", strerror(errno));
			return rc;
		}
		m_productID[RMI_PRODUCT_ID_LENGTH] = '\0';

		prodInfoAddr = queryAddr + 6;
		queryAddr += 10;

		if (m_hasLTS)
			++queryAddr;

		if (m_hasSensorID) {
			rc = Read(queryAddr++, &m_sensorID, 1);
			if (rc < 0 || rc < 1) {
				fprintf(stderr, "Failed to read sensor id: %s\n", strerror(errno));
				return rc;
			}
		}

		if (m_hasLTS)
			queryAddr += RMI_DEVICE_F01_LTS_RESERVED_SIZE;

		if (m_hasQuery42) {
			rc = Read(queryAddr++, infoBuf, 1);
			if (rc < 0 || rc < 1) {
				fprintf(stderr, "Failed to read query 42: %s\n", strerror(errno));
				return rc;
			}

			m_hasDS4Queries = infoBuf[0] & RMI_DEVICE_F01_QRY42_DS4_QUERIES;
			m_hasMultiPhysical = infoBuf[0] & RMI_DEVICE_F01_QRY42_MULTI_PHYS;
		}

		if (m_hasDS4Queries) {
			rc = Read(queryAddr++, &m_ds4QueryLength, 1);
			if (rc < 0 || rc < 1) {
				fprintf(stderr, "Failed to read DS4 query length: %s\n", strerror(errno));
				return rc;
			}
		}

		for (int i = 1; i <= m_ds4QueryLength; ++i) {
			unsigned char val;
			rc = Read(queryAddr++, &val, 1);
			if (rc < 0 || rc < 1) {
				fprintf(stderr, "Failed to read F01 Query43.%02d: %s\n", i, strerror(errno));
				continue;
			}

			switch(i) {
				case 1:
					m_hasPackageIDQuery = val & RMI_DEVICE_F01_QRY43_01_PACKAGE_ID;
					m_hasBuildIDQuery = val & RMI_DEVICE_F01_QRY43_01_BUILD_ID;
					break;
				case 2:
				case 3:
				default:
					break;
			}
		}

		if (m_hasPackageIDQuery) {
			rc = Read(prodInfoAddr++, infoBuf, PACKAGE_ID_BYTES);
			if (rc >= PACKAGE_ID_BYTES) {
				unsigned short *val = (unsigned short *)infoBuf;
				m_packageID = *val;
				val = (unsigned short *)(infoBuf + 2);
				m_packageRev = *val;
			}
		}

		if (m_hasBuildIDQuery) {
			rc = Read(prodInfoAddr, infoBuf, BUILD_ID_BYTES);
			if (rc >= BUILD_ID_BYTES) {
				unsigned short *val = (unsigned short *)infoBuf;
				m_buildID = *val;
				m_buildID += infoBuf[2] * 65536;
			}
		}
	}

	if (GetFunction(f34, 0x34)) {
		controlAddr = f34.GetControlBase();
		rc = Read(controlAddr, configid, CONFIG_ID_BYTES);
		if (rc < 0 || rc < CONFIG_ID_BYTES) {
			fprintf(stderr, "Failed to read the config id: %s\n", strerror(errno));
			return rc;
		}
		m_configID = (configid[0] << 24 | configid[1] << 16
				| configid[2] << 8 | configid[3]) & 0xFFFFFFFF;
	}

	return 0;
}

void RMIDevice::Close()
{
	m_functionList.clear();
	m_bCancel = false;
	m_bytesPerReadRequest = 0;
	m_page = -1;
	m_deviceType = RMI_DEVICE_TYPE_ANY;
}

void RMIDevice::PrintProperties()
{
	fprintf(stdout, "manufacturerID:\t\t%d\n", m_manufacturerID);
	fprintf(stdout, "Has LTS?:\t\t%d\n", m_hasLTS);
	fprintf(stdout, "Has Sensor ID?:\t\t%d\n", m_hasSensorID);
	fprintf(stdout, "Has Adjustable Doze?:\t%d\n", m_hasAdjustableDoze);
	fprintf(stdout, "Has Query 42?:\t\t%d\n", m_hasQuery42);
	fprintf(stdout, "Date of Manufacturer:\t%s\n", m_dom);
	fprintf(stdout, "Product ID:\t\t%s\n", m_productID);
	fprintf(stdout, "Firmware Version:\t%d.%d\n", m_firmwareVersionMajor, m_firmwareVersionMinor);
	fprintf(stdout, "Package ID:\t\t%d\n", m_packageID);
	fprintf(stdout, "Package Rev:\t\t%d\n", m_packageRev);
	fprintf(stdout, "Build ID:\t\t%ld\n", m_buildID);
	fprintf(stdout, "Sensor ID:\t\t%d\n", m_sensorID);
	fprintf(stdout, "Has DS4 Queries?:\t%d\n", m_hasDS4Queries);
	fprintf(stdout, "Has Multi Phys?:\t%d\n", m_hasMultiPhysical);
	fprintf(stdout, "\n");
}

int RMIDevice::Reset()
{
	int rc;
	RMIFunction f01;
	const unsigned char deviceReset = RMI_F01_CMD_DEVICE_RESET;

	if (!GetFunction(f01, 1))
		return -1;

	fprintf(stdout, "Resetting...\n");
	rc = Write(f01.GetCommandBase(), &deviceReset, 1);
	if (rc < 0 || rc < 1)
		return rc;

	rc = Sleep(RMI_F01_DEFAULT_RESET_DELAY_MS);
	if (rc < 0)
		return -1;
	fprintf(stdout, "Reset completed.\n");
	return 0;
}

bool RMIDevice::GetFunction(RMIFunction &func, int functionNumber)
{
	std::vector<RMIFunction>::iterator funcIter;

	for (funcIter = m_functionList.begin(); funcIter != m_functionList.end(); ++funcIter) {
		if (funcIter->GetFunctionNumber() == functionNumber) {
			func = *funcIter;
			return true;
		}
	}
	return false;
}

void RMIDevice::PrintFunctions()
{
	std::vector<RMIFunction>::iterator funcIter;

	for (funcIter = m_functionList.begin(); funcIter != m_functionList.end(); ++funcIter)
		fprintf(stdout, "0x%02x (%d) (%d) (0x%x): 0x%02x 0x%02x 0x%02x 0x%02x\n",
				funcIter->GetFunctionNumber(), funcIter->GetFunctionVersion(),
				funcIter->GetInterruptSourceCount(),
				funcIter->GetInterruptMask(),
				funcIter->GetDataBase(),
				funcIter->GetControlBase(), funcIter->GetCommandBase(),
				funcIter->GetQueryBase());
}

int RMIDevice::ScanPDT(int endFunc, int endPage)
{
	int rc;
	unsigned int page;
	unsigned int maxPage;
	unsigned int addr;
	unsigned char entry[RMI_DEVICE_PDT_ENTRY_SIZE];
	unsigned int interruptCount = 0;

	maxPage = (unsigned int)((endPage < 0) ? RMI_DEVICE_MAX_PAGE : endPage);

	m_functionList.clear();

	for (page = 0; page < maxPage; ++page) {
		unsigned int page_start = RMI_DEVICE_PAGE_SIZE * page;
		unsigned int pdt_start = page_start + RMI_DEVICE_PAGE_SCAN_START;
		unsigned int pdt_end = page_start + RMI_DEVICE_PAGE_SCAN_END;
		bool found = false;

		SetRMIPage(page);

		for (addr = pdt_start; addr >= pdt_end; addr -= RMI_DEVICE_PDT_ENTRY_SIZE) {
			rc = Read(addr, entry, RMI_DEVICE_PDT_ENTRY_SIZE);
			if (rc < 0 || rc < RMI_DEVICE_PDT_ENTRY_SIZE) {
				fprintf(stderr, "Failed to read PDT entry at address (0x%04x)\n", addr);
				return rc;
			}
			
			RMIFunction func(entry, page_start, interruptCount);
			if (func.GetFunctionNumber() == 0)
				break;

			m_functionList.push_back(func);
			interruptCount += func.GetInterruptSourceCount();
			found = true;

			if (func.GetFunctionNumber() == endFunc)
				return 0;
		}

		if (!found && (endPage < 0))
			break;
	}

	m_numInterruptRegs = (interruptCount + 7) / 8;

	return 0;
}

bool RMIDevice::InBootloader()
{
	RMIFunction f01;
	if (GetFunction(f01, 0x01)) {
		int rc;
		unsigned char status;

		rc = Read(f01.GetDataBase(), &status, 1);
		if (rc < 0 || rc < 1)
			return true;

		return !!(status & 0x40);
	}
	return true;
}