/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/* Temperature sensor module for Chrome EC */

#include "common.h"
#include "console.h"
#include "hooks.h"
#include "host_command.h"
#include "task.h"
#include "temp_sensor.h"
#include "thermal.h"
#include "timer.h"
#include "util.h"

int temp_sensor_read(enum temp_sensor_id id, int *temp_ptr)
{
	const struct temp_sensor_t *sensor;

	if (id < 0 || id >= TEMP_SENSOR_COUNT)
		return EC_ERROR_INVAL;
	sensor = temp_sensors + id;

	return sensor->read(sensor->idx, temp_ptr);
}

static void update_mapped_memory(void)
{
	int i, t;
	uint8_t *mptr = host_get_memmap(EC_MEMMAP_TEMP_SENSOR);

	for (i = 0; i < TEMP_SENSOR_COUNT; i++, mptr++) {
		/*
		 * Switch to second range if first one is full, or stop if
		 * second range is also full.
		 */
		if (i == EC_TEMP_SENSOR_ENTRIES)
			mptr = host_get_memmap(EC_MEMMAP_TEMP_SENSOR_B);
		else if (i >= EC_TEMP_SENSOR_ENTRIES +
			 EC_TEMP_SENSOR_B_ENTRIES)
			break;

		switch (temp_sensor_read(i, &t)) {
		case EC_ERROR_NOT_POWERED:
			*mptr = EC_TEMP_SENSOR_NOT_POWERED;
			break;
		case EC_ERROR_NOT_CALIBRATED:
			*mptr = EC_TEMP_SENSOR_NOT_CALIBRATED;
			break;
		case EC_SUCCESS:
			*mptr = t - EC_TEMP_SENSOR_OFFSET;
			break;
		default:
			*mptr = EC_TEMP_SENSOR_ERROR;
		}
	}
}
/* Run after other TEMP tasks, so sensors will have updated first. */
DECLARE_HOOK(HOOK_SECOND, update_mapped_memory, HOOK_PRIO_TEMP_SENSOR_DONE);

static void temp_sensor_init(void)
{
	int i;
	uint8_t *base, *base_b;

	/*
	 * Initialize memory-mapped data so that if a temperature value is read
	 * before we actually poll the sensors, we don't end up with an insane
	 * value.
	 */
	base = host_get_memmap(EC_MEMMAP_TEMP_SENSOR);
	base_b = host_get_memmap(EC_MEMMAP_TEMP_SENSOR_B);
	for (i = 0; i < TEMP_SENSOR_COUNT; ++i) {
		if (i < EC_TEMP_SENSOR_ENTRIES)
			base[i] = EC_TEMP_SENSOR_DEFAULT;
		else
			base_b[i - EC_TEMP_SENSOR_ENTRIES] =
				EC_TEMP_SENSOR_DEFAULT;
	}

	/* Set the rest of memory region to SENSOR_NOT_PRESENT */
	for (; i < EC_TEMP_SENSOR_ENTRIES + EC_TEMP_SENSOR_B_ENTRIES; ++i) {
		if (i < EC_TEMP_SENSOR_ENTRIES)
			base[i] = EC_TEMP_SENSOR_NOT_PRESENT;
		else
			base_b[i - EC_TEMP_SENSOR_ENTRIES] =
				EC_TEMP_SENSOR_NOT_PRESENT;
	}

	/* Temp sensor data is present, with B range supported. */
	*host_get_memmap(EC_MEMMAP_THERMAL_VERSION) = 2;
}
DECLARE_HOOK(HOOK_INIT, temp_sensor_init, HOOK_PRIO_DEFAULT);

/*****************************************************************************/
/* Console commands */

static int command_temps(int argc, char **argv)
{
	int t, i;
	int rv, rv1 = EC_SUCCESS;

	for (i = 0; i < TEMP_SENSOR_COUNT; ++i) {
		ccprintf("  %-20s: ", temp_sensors[i].name);
		rv = temp_sensor_read(i, &t);
		if (rv)
			rv1 = rv;

		switch (rv) {
		case EC_SUCCESS:
			ccprintf("%d K = %d C", t, K_TO_C(t));
			if (thermal_params[i].temp_fan_off &&
			    thermal_params[i].temp_fan_max)
				ccprintf("  %d%%",
					 thermal_fan_percent(
						 thermal_params[i].temp_fan_off,
						 thermal_params[i].temp_fan_max,
						 t));
			ccprintf("\n");
			break;
		case EC_ERROR_NOT_POWERED:
			ccprintf("Not powered\n");
			break;
		case EC_ERROR_NOT_CALIBRATED:
			ccprintf("Not calibrated\n");
			break;
		default:
			ccprintf("Error %d\n", rv);
		}
	}

	return rv1;
}
DECLARE_CONSOLE_COMMAND(temps, command_temps,
			NULL,
			"Print temp sensors",
			NULL);

/*****************************************************************************/
/* Host commands */

int temp_sensor_command_get_info(struct host_cmd_handler_args *args)
{
	const struct ec_params_temp_sensor_get_info *p = args->params;
	struct ec_response_temp_sensor_get_info *r = args->response;
	int id = p->id;

	if (id >= TEMP_SENSOR_COUNT)
		return EC_RES_ERROR;

	strzcpy(r->sensor_name, temp_sensors[id].name, sizeof(r->sensor_name));
	r->sensor_type = temp_sensors[id].type;

	args->response_size = sizeof(*r);

	return EC_RES_SUCCESS;
}
DECLARE_HOST_COMMAND(EC_CMD_TEMP_SENSOR_GET_INFO,
		     temp_sensor_command_get_info,
		     EC_VER_MASK(0));
