/*
 * ec_access.c
 *
 * Copyright (C) 2010 SUSE Linux Products GmbH
 * Author:
 *      Thomas Renninger <trenn@suse.de>
 *
 * This work is licensed under the terms of the GNU GPL, version 2.
 */

#include <fcntl.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <libgen.h>
#include <unistd.h>
#include <getopt.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>


#define EC_SPACE_SIZE 256
#define SYSFS_PATH "/sys/kernel/debug/ec/ec0/io"

/* TBD/Enhancements:
   - Provide param for accessing different ECs (not supported by kernel yet)
*/

static int read_mode = -1;
static int sleep_time;
static int write_byte_offset = -1;
static int read_byte_offset = -1;
static uint8_t write_value = -1;

void usage(char progname[], int exit_status)
{
	printf("Usage:\n");
	printf("1) %s -r [-s sleep]\n", basename(progname));
	printf("2) %s -b byte_offset\n", basename(progname));
	printf("3) %s -w byte_offset -v value\n\n", basename(progname));

	puts("\t-r [-s sleep]      : Dump EC registers");
	puts("\t                     If sleep is given, sleep x seconds,");
	puts("\t                     re-read EC registers and show changes");
	puts("\t-b offset          : Read value at byte_offset (in hex)");
	puts("\t-w offset -v value : Write value at byte_offset");
	puts("\t-h                 : Print this help\n\n");
	puts("Offsets and values are in hexadecimal number system.");
	puts("The offset and value must be between 0 and 0xff.");
	exit(exit_status);
}

void parse_opts(int argc, char *argv[])
{
	int c;

	while ((c = getopt(argc, argv, "rs:b:w:v:h")) != -1) {

		switch (c) {
		case 'r':
			if (read_mode != -1)
				usage(argv[0], EXIT_FAILURE);
			read_mode = 1;
			break;
		case 's':
			if (read_mode != -1 && read_mode != 1)
				usage(argv[0], EXIT_FAILURE);

			sleep_time = atoi(optarg);
			if (sleep_time <= 0) {
				sleep_time = 0;
				usage(argv[0], EXIT_FAILURE);
				printf("Bad sleep time: %s\n", optarg);
			}
			break;
		case 'b':
			if (read_mode != -1)
				usage(argv[0], EXIT_FAILURE);
			read_mode = 1;
			read_byte_offset = strtoul(optarg, NULL, 16);
			break;
		case 'w':
			if (read_mode != -1)
				usage(argv[0], EXIT_FAILURE);
			read_mode = 0;
			write_byte_offset = strtoul(optarg, NULL, 16);
			break;
		case 'v':
			write_value = strtoul(optarg, NULL, 16);
			break;
		case 'h':
			usage(argv[0], EXIT_SUCCESS);
		default:
			fprintf(stderr, "Unknown option!\n");
			usage(argv[0], EXIT_FAILURE);
		}
	}
	if (read_mode == 0) {
		if (write_byte_offset < 0 ||
		    write_byte_offset >= EC_SPACE_SIZE) {
			fprintf(stderr, "Wrong byte offset 0x%.2x, valid: "
				"[0-0x%.2x]\n",
				write_byte_offset, EC_SPACE_SIZE - 1);
			usage(argv[0], EXIT_FAILURE);
		}
		if (write_value < 0 ||
		    write_value >= 255) {
			fprintf(stderr, "Wrong byte offset 0x%.2x, valid:"
				"[0-0xff]\n", write_byte_offset);
			usage(argv[0], EXIT_FAILURE);
		}
	}
	if (read_mode == 1 && read_byte_offset != -1) {
		if (read_byte_offset < -1 ||
		    read_byte_offset >= EC_SPACE_SIZE) {
			fprintf(stderr, "Wrong byte offset 0x%.2x, valid: "
				"[0-0x%.2x]\n",
				read_byte_offset, EC_SPACE_SIZE - 1);
			usage(argv[0], EXIT_FAILURE);
		}
	}
	/* Add additional parameter checks here */
}

void dump_ec(int fd)
{
	char buf[EC_SPACE_SIZE];
	char buf2[EC_SPACE_SIZE];
	int byte_off, bytes_read;

	bytes_read = read(fd, buf, EC_SPACE_SIZE);

	if (bytes_read == -1)
		err(EXIT_FAILURE, "Could not read from %s\n", SYSFS_PATH);

	if (bytes_read != EC_SPACE_SIZE)
		fprintf(stderr, "Could only read %d bytes\n", bytes_read);

	printf("     00  01  02  03  04  05  06  07  08  09  0A  0B  0C  0D  0E  0F");
	for (byte_off = 0; byte_off < bytes_read; byte_off++) {
		if ((byte_off % 16) == 0)
			printf("\n%.2X: ", byte_off);
		printf(" %.2x ", (uint8_t)buf[byte_off]);
	}
	printf("\n");

	if (!sleep_time)
		return;

	printf("\n");
	lseek(fd, 0, SEEK_SET);
	sleep(sleep_time);

	bytes_read = read(fd, buf2, EC_SPACE_SIZE);

	if (bytes_read == -1)
		err(EXIT_FAILURE, "Could not read from %s\n", SYSFS_PATH);

	if (bytes_read != EC_SPACE_SIZE)
		fprintf(stderr, "Could only read %d bytes\n", bytes_read);

	printf("     00  01  02  03  04  05  06  07  08  09  0A  0B  0C  0D  0E  0F");
	for (byte_off = 0; byte_off < bytes_read; byte_off++) {
		if ((byte_off % 16) == 0)
			printf("\n%.2X: ", byte_off);

		if (buf[byte_off] == buf2[byte_off])
			printf(" %.2x ", (uint8_t)buf2[byte_off]);
		else
			printf("*%.2x ", (uint8_t)buf2[byte_off]);
	}
	printf("\n");
}

void read_ec_val(int fd, int byte_offset)
{
	uint8_t buf;
	int error;

	error = lseek(fd, byte_offset, SEEK_SET);
	if (error != byte_offset)
		err(EXIT_FAILURE, "Cannot set offset to 0x%.2x", byte_offset);

	error = read(fd, &buf, 1);
	if (error != 1)
		err(EXIT_FAILURE, "Could not read byte 0x%.2x from %s\n",
		    byte_offset, SYSFS_PATH);
	printf("0x%.2x\n", buf);
	return;
}

void write_ec_val(int fd, int byte_offset, uint8_t value)
{
	int error;

	error = lseek(fd, byte_offset, SEEK_SET);
	if (error != byte_offset)
		err(EXIT_FAILURE, "Cannot set offset to 0x%.2x", byte_offset);

	error = write(fd, &value, 1);
	if (error != 1)
		err(EXIT_FAILURE, "Cannot write value 0x%.2x to offset 0x%.2x",
		    value, byte_offset);
}

int main(int argc, char *argv[])
{
	int file_mode = O_RDONLY;
	int fd;

	parse_opts(argc, argv);

	if (read_mode == 0)
		file_mode = O_WRONLY;
	else if (read_mode == 1)
		file_mode = O_RDONLY;
	else
		usage(argv[0], EXIT_FAILURE);

	fd = open(SYSFS_PATH, file_mode);
	if (fd == -1)
		err(EXIT_FAILURE, "%s", SYSFS_PATH);

	if (read_mode)
		if (read_byte_offset == -1)
			dump_ec(fd);
		else if (read_byte_offset < 0 ||
			 read_byte_offset >= EC_SPACE_SIZE)
			usage(argv[0], EXIT_FAILURE);
		else
			read_ec_val(fd, read_byte_offset);
	else
		write_ec_val(fd, write_byte_offset, write_value);
	close(fd);

	exit(EXIT_SUCCESS);
}
