/*
    it8705.c - A user-space library to access the it8705 chip.
    Copyright (c) 2006 Andrew Calkin <calkina@geexbox.org>

    Copyright (c) 2005 Richard Taylor <richard@artaylor.co.uk>


    Heavily based on code for accessing/initializing it8712/it8705
    written by
    (C) Copyright 2004 Wojtek Kaniewski <wojtekka@toxygen.net>

    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 2 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, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <sys/io.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <unistd.h>
#include <time.h>
#include "digitools.h"
#include "i2c-dev.h"
#include "it8705.h"

extern unsigned char addr;
extern unsigned char data;

unsigned char it87_read_byte(unsigned char addr)
{
  outb(addr, IT87_ACCESS_REG);
  return inb(IT87_RETURN_REG);
}

unsigned char it87_read_ec_byte(unsigned char addr)
{
  outb(addr, IT8705_EC_ACCESS_REG);
  return inb(IT8705_EC_RETURN_REG);
}

int it87_write_ec_byte (unsigned char addr, unsigned char data)
{
  outb(addr, IT8705_EC_ACCESS_REG);
  outb(data, IT8705_EC_RETURN_REG);

  if (it87_read_ec_byte(addr) != data)
  {
#ifndef SILENT
    printf("Error Writing EC addr: 0x%02X, wrote: 0x%02X, read: 0x%02X\n",
            addr, data, it87_read_ec_byte(addr));
#endif
    return -1;
  }
  return 0;
}

int it87_write_byte (unsigned char addr, unsigned char data)
{
  outb(addr, IT87_ACCESS_REG);
  outb(data, IT87_RETURN_REG);

  if ((addr != IT8705_CFG_CTRL) && (it87_read_byte(addr) != data))
  {
#ifndef SILENT
    printf("Error Writing addr: 0x%02X, wrote: 0x%02X, read: 0x%02X\n",
       addr, data, it87_read_byte(addr));
#endif
    return -1;
  }
  return 0;
}

int it87_ec_port_open(void)
{
  if (ioperm(IT8705_EC_ACCESS_REG, 2, 1) == -1)
  {
#ifndef SILENT
    printf("Error getting access\n");
#endif
    exit(1);
  }
  else
    return 0;
}

void it87_ec_port_close(void)
{
  ioperm(IT8705_EC_ACCESS_REG, 2, 0);
}

int it87_open(void)
{
  if (ioperm(IT87_ACCESS_REG, 2, 1) == -1)
  {
#ifndef SILENT
    printf("Error getting access!\n");
#endif
    exit(1);
  }

  outb(0x87, IT87_ACCESS_REG);
  outb(0x01, IT87_ACCESS_REG);
  outb(0x55, IT87_ACCESS_REG);
  outb(0x55, IT87_ACCESS_REG);

  if (it87_read_byte(0x20) != 0x87 || it87_read_byte(0x21) != 0x05)
  {
#ifndef SILENT
    printf("IT8705 not found!\nIdent values are %02X%02X.\n"
             "Should be 8705\n",it87_read_byte(0x20),
             it87_read_byte(0x21));
#endif
    exit(1);
  }
  return 0;
}

void it87_close(void)
{
    /* To exit pnp mode we need to set bit 1 of IT8705_CFG_CTRL
       bit 0 is the reset bit. This register is write only */
    it87_write_byte(IT8705_CFG_CTRL, 0x02);
    ioperm(IT87_ACCESS_REG, 2, 0);
}

/* Note: Returns hexified version of temperature:
         Temp = 34 DegC, return will be 0x34
         On error, returns 0 to fail gracefully */
char it87_get_temp(void)
{
  int temp;
  char temp_dec = 0;

  /* Get the temperature from the IT87 */
  temp=it87_read_ec_byte(IT8705_TEMP_REG1);

  temp &= 0xFF;
  temp_dec = ((temp / 10) << 4) & 0xf0;
  temp_dec |= (temp % 10) & 0x0f;

  return temp_dec;
}

void it87_ldn_set(unsigned char ldn)
{
  outb(0x07,IT87_ACCESS_REG);
  outb(ldn,IT87_RETURN_REG);
}

unsigned char it87_read_cir_byte(unsigned char addr)
{
  return inb(IT87_CIR_DEFAULT_IOBASE + addr);
}

int it87_write_cir_byte (unsigned char addr, unsigned char data)
{
  outb(data, IT87_CIR_DEFAULT_IOBASE + addr);

  if (it87_read_cir_byte(addr) != data)
  {
#ifndef SILENT
    printf("Error Writing CIR addr: 0x%02X, wrote: 0x%02X, read: 0x%02X\n",
       addr, data, it87_read_cir_byte(addr));
#endif
    return -1;
  }
  return 0;
}

int it87_cir_port_open(void)
{
  if (ioperm(IT87_CIR_DEFAULT_IOBASE, 10, 1) == -1)
  {
#ifndef SILENT
    printf("Error getting access!\n");
#endif
    exit(1);
  }
  else
    return 0;
}

void it87_cir_port_close(void)
{
  ioperm(IT87_CIR_DEFAULT_IOBASE, 10, 0);
}
