/*  digiwake.c - Program to set IT87 registers to allow Wake-on-CIR
 *             (consumer infra-red remote) for the ASUS Digimatrix
 *
 *  (C) Copyright 2006 Ben Potter <linux@bpuk.org>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License Version 2 as
 *  published by the Free Software Foundation.
 *
 *  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, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <sys/io.h>
#include <unistd.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <getopt.h>
#include <errno.h>
#include <getopt.h>
#include "digiwake.h"
#include "it8705.h"
#include "digitools.h"

static struct option digiwake_longopts[] = {
  { "read",       0, 0, 'r' },
  { "write",      0, 0, 'w' },
  { "help",       0, 0, 'h' },
  { "version",    0, 0, 'v' },
  { NULL,         0, 0,  0  }
};


static void digiwake_help(char *argv0)
{
#ifndef SILENT
  printf(
"\n"
"Usage: %s [OPTIONS]\n"
"\n"
"  WARNING: If you are using this on a system other than the ASUS\n"
"  DigiMatrix, then there is a chance that you may cause damage.\n"
"  This program needs to be run as root.\n"
"\n"
"  -r, --read             Attempts to read keycode.\n"
"  -w, --write            Attempts to write keycode.\n"
"  -v, --version          Print version number.\n"
"  -h, --help             Display this help message.\n"
"\n", argv0);
#endif
}

int digiwake_main(int argc, char **argv)
{
/*
  unsigned char writeData[10] = {0x46, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x35, 0x30, 0xcf};
*/
  int i = 0;
  int ch = 0;
  int longindex = 0;
  BOOL b_read = FALSE;
  BOOL b_write = FALSE;

  if ( (int)getuid() != 0)
  {
#ifndef SILENT
    fprintf(stderr,"Must be root to run this program!\n");
#endif
    return -1;
  }

  if (argc == 1)
  {
#ifndef SILENT
    printf("\nPlease supply some parameters.\n"
             "Use %s -h for list.\n\n", argv[0]);
#endif
    return 1;
  }


  /* Parse input params */
  for (;;)
    {
      if ((ch = getopt_long(argc, argv, "rwvh",
                  digiwake_longopts, &longindex)) == -1)
        break;

      switch (ch)
      {
        case 'r':
          b_read = TRUE;
          break;

        case 'w':
          b_write = TRUE;
          break;

        case 'v':
#ifndef SILENT
          printf("ASUS DigiMatrix Wake-On-CIR, from DigiTools "
                  "Version %s\n", DIGI_VER);
#endif
          break;

        case 'h':
        default:
          digiwake_help(argv[0]);
          return 0;
          break;
      }
    }

  if(b_read)
  {
    it87_open();
    it87_ldn_set(IT8705_PME_LDN);
    printf("Read Data: ");
    for (i=0; i<18; i++)
    {
      it87_write_byte(PME_INDX_REG,BASE_ADDR+i);
      printf("0x%02X ",it87_read_byte(PME_DATA_REG));
    }
    printf("\n");

    it87_ldn_set(IT8705_CIR_LDN); /* Switch to CIR */
    (void)it87_cir_port_open();

    printf("CIR-DR:    0x%02X\n",it87_read_cir_byte(IT87_CIR_DR));
    printf("CIR-IER:   0x%02X\n",it87_read_cir_byte(IT87_CIR_IER));
    printf("CIR-RCR:   0x%02X\n",it87_read_cir_byte(IT87_CIR_RCR));
    printf("CIR-TCR1:  0x%02X\n",it87_read_cir_byte(IT87_CIR_TCR1));
    printf("CIR-TCR2:  0x%02X\n",it87_read_cir_byte(IT87_CIR_TCR2));
    printf("CIR-TSR:   0x%02X\n",it87_read_cir_byte(IT87_CIR_TSR));
    printf("CIR-RSR:   0x%02X\n",it87_read_cir_byte(IT87_CIR_RSR));
    printf("CIR-BDLR:  0x%02X\n",it87_read_cir_byte(IT87_CIR_BDLR));
    printf("CIR-BDHR:  0x%02X\n",it87_read_cir_byte(IT87_CIR_BDHR));
    printf("CIR-IIR:   0x%02X\n",it87_read_cir_byte(IT87_CIR_IIR));

    it87_cir_port_close();

    it87_close();
  }

  if(b_write)
  {
    it87_open();
    it87_ldn_set(IT8705_PME_LDN);
/*
    for (i=0; i<10; i++)
    {
      it87_write_byte(PME_INDX_REG,BASE_ADDR+i);
      it87_write_byte(PME_DATA_REG,writeData[(int)i]);
    }
    it87_write_byte(PME_ENABLE,0x1);
*/
    it87_ldn_set(IT8705_CIR_LDN); /* Switch to CIR */
    (void)it87_cir_port_open();

    it87_write_cir_byte(IT87_CIR_IER,0x1C); /* Allow us to reset baudrate */
    it87_write_cir_byte(IT87_CIR_BDHR,0x0); /* Baudrate */
    it87_write_cir_byte(IT87_CIR_BDLR,0x45); /* Baudrate */
    it87_write_cir_byte(IT87_CIR_IER,0x0C); /* Prevent change of baudrate */

    it87_cir_port_close();

    it87_close();
  }

#ifndef SILENT
  printf("Program exiting...\n\n");
#endif
  return 0;
}
