/*
 * Copyright (C) 2013 Paul Kocialkowski
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define LOG_TAG "exynos_sensors"
#include 
#include "exynos_sensors.h"
struct lps331ap_data {
	char path_enable[PATH_MAX];
	char path_delay[PATH_MAX];
};
int lps331ap_init(struct exynos_sensors_handlers *handlers,
	struct exynos_sensors_device *device)
{
	struct lps331ap_data *data = NULL;
	char path[PATH_MAX] = { 0 };
	int input_fd = -1;
	int rc;
	ALOGD("%s(%p, %p)", __func__, handlers, device);
	if (handlers == NULL)
		return -EINVAL;
	data = (struct lps331ap_data *) calloc(1, sizeof(struct lps331ap_data));
	input_fd = input_open("barometer_sensor");
	if (input_fd < 0) {
		ALOGE("%s: Unable to open input", __func__);
		goto error;
	}
	rc = sysfs_path_prefix("barometer_sensor", (char *) &path);
	if (rc < 0 || path[0] == '\0') {
		ALOGE("%s: Unable to open sysfs", __func__);
		goto error;
	}
	snprintf(data->path_enable, PATH_MAX, "%s/enable", path);
	snprintf(data->path_delay, PATH_MAX, "%s/poll_delay", path);
	handlers->poll_fd = input_fd;
	handlers->data = (void *) data;
	return 0;
error:
	if (data != NULL)
		free(data);
	if (input_fd >= 0)
		close(input_fd);
	handlers->poll_fd = -1;
	handlers->data = NULL;
	return -1;
}
int lps331ap_deinit(struct exynos_sensors_handlers *handlers)
{
	ALOGD("%s(%p)", __func__, handlers);
	if (handlers == NULL)
		return -EINVAL;
	if (handlers->poll_fd >= 0)
		close(handlers->poll_fd);
	handlers->poll_fd = -1;
	if (handlers->data != NULL)
		free(handlers->data);
	handlers->data = NULL;
	return 0;
}
int lps331ap_activate(struct exynos_sensors_handlers *handlers)
{
	struct lps331ap_data *data;
	int rc;
	ALOGD("%s(%p)", __func__, handlers);
	if (handlers == NULL || handlers->data == NULL)
		return -EINVAL;
	data = (struct lps331ap_data *) handlers->data;
	rc = sysfs_value_write(data->path_enable, 1);
	if (rc < 0) {
		ALOGE("%s: Unable to write sysfs value", __func__);
		return -1;
	}
	handlers->activated = 1;
	return 0;
}
int lps331ap_deactivate(struct exynos_sensors_handlers *handlers)
{
	struct lps331ap_data *data;
	int rc;
	ALOGD("%s(%p)", __func__, handlers);
	if (handlers == NULL || handlers->data == NULL)
		return -EINVAL;
	data = (struct lps331ap_data *) handlers->data;
	rc = sysfs_value_write(data->path_enable, 0);
	if (rc < 0) {
		ALOGE("%s: Unable to write sysfs value", __func__);
		return -1;
	}
	handlers->activated = 1;
	return 0;
}
int lps331ap_set_delay(struct exynos_sensors_handlers *handlers, long int delay)
{
	struct lps331ap_data *data;
	int rc;
	ALOGD("%s(%p, %ld)", __func__, handlers, delay);
	if (handlers == NULL || handlers->data == NULL)
		return -EINVAL;
	data = (struct lps331ap_data *) handlers->data;
	rc = sysfs_value_write(data->path_delay, (int) delay / 1000000);
	if (rc < 0) {
		ALOGE("%s: Unable to write sysfs value", __func__);
		return -1;
	}
	return 0;
}
float lps331ap_convert(int value)
{
	return (float) value / 4096.0f;
}
int lps331ap_get_data(struct exynos_sensors_handlers *handlers,
	struct sensors_event_t *event)
{
	struct input_event input_event;
	int input_fd;
	int rc;
//	ALOGD("%s(%p, %p)", __func__, handlers, event);
	if (handlers == NULL || event == NULL)
		return -EINVAL;
	input_fd = handlers->poll_fd;
	if (input_fd < 0)
		return -EINVAL;
	event->version = sizeof(struct sensors_event_t);
	event->sensor = handlers->handle;
	event->type = handlers->handle;
	do {
		rc = read(input_fd, &input_event, sizeof(input_event));
		if (rc < (int) sizeof(input_event))
			break;
		if (input_event.type == EV_REL) {
			if (input_event.code == REL_X)
				event->pressure = lps331ap_convert(input_event.value);
		} else if (input_event.type == EV_SYN) {
			if (input_event.code == SYN_REPORT)
				event->timestamp = input_timestamp(&input_event);
		}
	} while (input_event.type != EV_SYN);
	return 0;
}
struct exynos_sensors_handlers lps331ap = {
	.name = "LPS331AP",
	.handle = SENSOR_TYPE_PRESSURE,
	.init = lps331ap_init,
	.deinit = lps331ap_deinit,
	.activate = lps331ap_activate,
	.deactivate = lps331ap_deactivate,
	.set_delay = lps331ap_set_delay,
	.get_data = lps331ap_get_data,
	.activated = 0,
	.needed = 0,
	.poll_fd = -1,
	.data = NULL,
};