/*
 * intel_mid_thermal.c - Intel MID platform thermal driver
 *
 * Copyright (C) 2011 Intel Corporation
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * 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; version 2 of the License.
 *
 * 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.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * Author: Durgadoss R <durgadoss.r@intel.com>
 */

#define pr_fmt(fmt) "intel_mid_thermal: " fmt

#include <linux/module.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/param.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/pm.h>
#include <linux/thermal.h>

#include <asm/intel_scu_ipc.h>

/* Number of thermal sensors */
#define MSIC_THERMAL_SENSORS   4

/* ADC1 - thermal registers */
#define MSIC_THERM_ADC1CNTL1   0x1C0
#define MSIC_ADC_ENBL          0x10
#define MSIC_ADC_START         0x08

#define MSIC_THERM_ADC1CNTL3   0x1C2
#define MSIC_ADCTHERM_ENBL     0x04
#define MSIC_ADCRRDATA_ENBL    0x05
#define MSIC_CHANL_MASK_VAL    0x0F

#define MSIC_STOPBIT_MASK      16
#define MSIC_ADCTHERM_MASK     4
#define ADC_CHANLS_MAX         15 /* Number of ADC channels */
#define ADC_LOOP_MAX           (ADC_CHANLS_MAX - MSIC_THERMAL_SENSORS)

/* ADC channel code values */
#define SKIN_SENSOR0_CODE      0x08
#define SKIN_SENSOR1_CODE      0x09
#define SYS_SENSOR_CODE                0x0A
#define MSIC_DIE_SENSOR_CODE   0x03

#define SKIN_THERM_SENSOR0     0
#define SKIN_THERM_SENSOR1     1
#define SYS_THERM_SENSOR2      2
#define MSIC_DIE_THERM_SENSOR3 3

/* ADC code range */
#define ADC_MAX                        977
#define ADC_MIN                        162
#define ADC_VAL0C              887
#define ADC_VAL20C             720
#define ADC_VAL40C             508
#define ADC_VAL60C             315

/* ADC base addresses */
#define ADC_CHNL_START_ADDR    0x1C5   /* increments by 1 */
#define ADC_DATA_START_ADDR     0x1D4   /* increments by 2 */

/* MSIC die attributes */
#define MSIC_DIE_ADC_MIN       488
#define MSIC_DIE_ADC_MAX       1004

/* This holds the address of the first free ADC channel,
 * among the 15 channels
 */
static int channel_index;

struct platform_info {
       struct platform_device *pdev;
       struct thermal_zone_device *tzd[MSIC_THERMAL_SENSORS];
};

struct thermal_device_info {
       unsigned int chnl_addr;
       int direct;
       /* This holds the current temperature in millidegree celsius */
       long curr_temp;
};

/**
 * to_msic_die_temp - converts adc_val to msic_die temperature
 * @adc_val: ADC value to be converted
 *
 * Can sleep
 */
static int to_msic_die_temp(uint16_t adc_val)
{
       return (368 * (adc_val) / 1000) - 220;
}

/**
 * is_valid_adc - checks whether the adc code is within the defined range
 * @min: minimum value for the sensor
 * @max: maximum value for the sensor
 *
 * Can sleep
 */
static int is_valid_adc(uint16_t adc_val, uint16_t min, uint16_t max)
{
       return (adc_val >= min) && (adc_val <= max);
}

/**
 * adc_to_temp - converts the ADC code to temperature in C
 * @direct: true if ths channel is direct index
 * @adc_val: the adc_val that needs to be converted
 * @tp: temperature return value
 *
 * Linear approximation is used to covert the skin adc value into temperature.
 * This technique is used to avoid very long look-up table to get
 * the appropriate temp value from ADC value.
 * The adc code vs sensor temp curve is split into five parts
 * to achieve very close approximate temp value with less than
 * 0.5C error
 */
static int adc_to_temp(int direct, uint16_t adc_val, unsigned long *tp)
{
       int temp;

       /* Direct conversion for die temperature */
       if (direct) {
               if (is_valid_adc(adc_val, MSIC_DIE_ADC_MIN, MSIC_DIE_ADC_MAX)) {
                       *tp = to_msic_die_temp(adc_val) * 1000;
                       return 0;
               }
               return -ERANGE;
       }

       if (!is_valid_adc(adc_val, ADC_MIN, ADC_MAX))
               return -ERANGE;

       /* Linear approximation for skin temperature */
       if (adc_val > ADC_VAL0C)
               temp = 177 - (adc_val/5);
       else if ((adc_val <= ADC_VAL0C) && (adc_val > ADC_VAL20C))
               temp = 111 - (adc_val/8);
       else if ((adc_val <= ADC_VAL20C) && (adc_val > ADC_VAL40C))
               temp = 92 - (adc_val/10);
       else if ((adc_val <= ADC_VAL40C) && (adc_val > ADC_VAL60C))
               temp = 91 - (adc_val/10);
       else
               temp = 112 - (adc_val/6);

       /* Convert temperature in celsius to milli degree celsius */
       *tp = temp * 1000;
       return 0;
}

/**
 * mid_read_temp - read sensors for temperature
 * @temp: holds the current temperature for the sensor after reading
 *
 * reads the adc_code from the channel and converts it to real
 * temperature. The converted value is stored in temp.
 *
 * Can sleep
 */
static int mid_read_temp(struct thermal_zone_device *tzd, unsigned long *temp)
{
       struct thermal_device_info *td_info = tzd->devdata;
       uint16_t adc_val, addr;
       uint8_t data = 0;
       int ret;
       unsigned long curr_temp;


       addr = td_info->chnl_addr;

       /* Enable the msic for conversion before reading */
       ret = intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL3, MSIC_ADCRRDATA_ENBL);
       if (ret)
               return ret;

       /* Re-toggle the RRDATARD bit (temporary workaround) */
       ret = intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL3, MSIC_ADCTHERM_ENBL);
       if (ret)
               return ret;

       /* Read the higher bits of data */
       ret = intel_scu_ipc_ioread8(addr, &data);
       if (ret)
               return ret;

       /* Shift bits to accomodate the lower two data bits */
       adc_val = (data << 2);
       addr++;

       ret = intel_scu_ipc_ioread8(addr, &data);/* Read lower bits */
       if (ret)
               return ret;

       /* Adding lower two bits to the higher bits */
       data &= 03;
       adc_val += data;

       /* Convert ADC value to temperature */
       ret = adc_to_temp(td_info->direct, adc_val, &curr_temp);
       if (ret == 0)
               *temp = td_info->curr_temp = curr_temp;
       return ret;
}

/**
 * configure_adc - enables/disables the ADC for conversion
 * @val: zero: disables the ADC non-zero:enables the ADC
 *
 * Enable/Disable the ADC depending on the argument
 *
 * Can sleep
 */
static int configure_adc(int val)
{
       int ret;
       uint8_t data;

       ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL1, &data);
       if (ret)
               return ret;

       if (val) {
               /* Enable and start the ADC */
               data |= (MSIC_ADC_ENBL | MSIC_ADC_START);
       } else {
               /* Just stop the ADC */
               data &= (~MSIC_ADC_START);
       }

       return intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL1, data);
}

/**
 * set_up_therm_channel - enable thermal channel for conversion
 * @base_addr: index of free msic ADC channel
 *
 * Enable all the three channels for conversion
 *
 * Can sleep
 */
static int set_up_therm_channel(u16 base_addr)
{
       int ret;

       /* Enable all the sensor channels */
       ret = intel_scu_ipc_iowrite8(base_addr, SKIN_SENSOR0_CODE);
       if (ret)
               return ret;

       ret = intel_scu_ipc_iowrite8(base_addr + 1, SKIN_SENSOR1_CODE);
       if (ret)
               return ret;

       ret = intel_scu_ipc_iowrite8(base_addr + 2, SYS_SENSOR_CODE);
       if (ret)
               return ret;

       /* Since this is the last channel, set the stop bit
          to 1 by ORing the DIE_SENSOR_CODE with 0x10 */
       ret = intel_scu_ipc_iowrite8(base_addr + 3,
                                       (MSIC_DIE_SENSOR_CODE | 0x10));
       if (ret)
               return ret;

       /* Enable ADC and start it */
       return configure_adc(1);
}

/**
 * reset_stopbit - sets the stop bit to 0 on the given channel
 * @addr: address of the channel
 *
 * Can sleep
 */
static int reset_stopbit(uint16_t addr)
{
       int ret;
       uint8_t data;
       ret = intel_scu_ipc_ioread8(addr, &data);
       if (ret)
               return ret;
       /* Set the stop bit to zero */
       return intel_scu_ipc_iowrite8(addr, (data & 0xEF));
}

/**
 * find_free_channel - finds an empty channel for conversion
 *
 * If the ADC is not enabled then start using 0th channel
 * itself. Otherwise find an empty channel by looking for a
 * channel in which the stopbit is set to 1. returns the index
 * of the first free channel if succeeds or an error code.
 *
 * Context: can sleep
 *
 * FIXME: Ultimately the channel allocator will move into the intel_scu_ipc
 * code.
 */
static int find_free_channel(void)
{
       int ret;
       int i;
       uint8_t data;

       /* check whether ADC is enabled */
       ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL1, &data);
       if (ret)
               return ret;

       if ((data & MSIC_ADC_ENBL) == 0)
               return 0;

       /* ADC is already enabled; Looking for an empty channel */
       for (i = 0; i < ADC_CHANLS_MAX; i++) {
               ret = intel_scu_ipc_ioread8(ADC_CHNL_START_ADDR + i, &data);
               if (ret)
                       return ret;

               if (data & MSIC_STOPBIT_MASK) {
                       ret = i;
                       break;
               }
       }
       return (ret > ADC_LOOP_MAX) ? (-EINVAL) : ret;
}

/**
 * mid_initialize_adc - initializing the ADC
 * @dev: our device structure
 *
 * Initialize the ADC for reading thermistor values. Can sleep.
 */
static int mid_initialize_adc(struct device *dev)
{
       u8  data;
       u16 base_addr;
       int ret;

       /*
        * Ensure that adctherm is disabled before we
        * initialize the ADC
        */
       ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL3, &data);
       if (ret)
               return ret;

       if (data & MSIC_ADCTHERM_MASK)
               dev_warn(dev, "ADCTHERM already set");

       /* Index of the first channel in which the stop bit is set */
       channel_index = find_free_channel();
       if (channel_index < 0) {
               dev_err(dev, "No free ADC channels");
               return channel_index;
       }

       base_addr = ADC_CHNL_START_ADDR + channel_index;

       if (!(channel_index == 0 || channel_index == ADC_LOOP_MAX)) {
               /* Reset stop bit for channels other than 0 and 12 */
               ret = reset_stopbit(base_addr);
               if (ret)
                       return ret;

               /* Index of the first free channel */
               base_addr++;
               channel_index++;
       }

       ret = set_up_therm_channel(base_addr);
       if (ret) {
               dev_err(dev, "unable to enable ADC");
               return ret;
       }
       dev_dbg(dev, "ADC initialization successful");
       return ret;
}

/**
 * initialize_sensor - sets default temp and timer ranges
 * @index: index of the sensor
 *
 * Context: can sleep
 */
static struct thermal_device_info *initialize_sensor(int index)
{
       struct thermal_device_info *td_info =
               kzalloc(sizeof(struct thermal_device_info), GFP_KERNEL);

       if (!td_info)
               return NULL;

       /* Set the base addr of the channel for this sensor */
       td_info->chnl_addr = ADC_DATA_START_ADDR + 2 * (channel_index + index);
       /* Sensor 3 is direct conversion */
       if (index == 3)
               td_info->direct = 1;
       return td_info;
}

/**
 * mid_thermal_resume - resume routine
 * @pdev: platform device structure
 *
 * mid thermal resume: re-initializes the adc. Can sleep.
 */
static int mid_thermal_resume(struct platform_device *pdev)
{
       return mid_initialize_adc(&pdev->dev);
}

/**
 * mid_thermal_suspend - suspend routine
 * @pdev: platform device structure
 *
 * mid thermal suspend implements the suspend functionality
 * by stopping the ADC. Can sleep.
 */
static int mid_thermal_suspend(struct platform_device *pdev, pm_message_t mesg)
{
       /*
        * This just stops the ADC and does not disable it.
        * temporary workaround until we have a generic ADC driver.
        * If 0 is passed, it disables the ADC.
        */
       return configure_adc(0);
}

/**
 * read_curr_temp - reads the current temperature and stores in temp
 * @temp: holds the current temperature value after reading
 *
 * Can sleep
 */
static int read_curr_temp(struct thermal_zone_device *tzd, unsigned long *temp)
{
       WARN_ON(tzd == NULL);
       return mid_read_temp(tzd, temp);
}

/* Can't be const */
static struct thermal_zone_device_ops tzd_ops = {
       .get_temp = read_curr_temp,
};


/**
 * mid_thermal_probe - mfld thermal initialize
 * @pdev: platform device structure
 *
 * mid thermal probe initializes the hardware and registers
 * all the sensors with the generic thermal framework. Can sleep.
 */
static int mid_thermal_probe(struct platform_device *pdev)
{
       static char *name[MSIC_THERMAL_SENSORS] = {
               "skin0", "skin1", "sys", "msicdie"
       };

       int ret;
       int i;
       struct platform_info *pinfo;

       pinfo = kzalloc(sizeof(struct platform_info), GFP_KERNEL);
       if (!pinfo)
               return -ENOMEM;

       /* Initializing the hardware */
       ret = mid_initialize_adc(&pdev->dev);
       if (ret) {
               dev_err(&pdev->dev, "ADC init failed");
               kfree(pinfo);
               return ret;
       }

       /* Register each sensor with the generic thermal framework*/
       for (i = 0; i < MSIC_THERMAL_SENSORS; i++) {
               pinfo->tzd[i] = thermal_zone_device_register(name[i],
                                       0, initialize_sensor(i),
                                       &tzd_ops, 0, 0, 0, 0);
               if (IS_ERR(pinfo->tzd[i]))
                       goto reg_fail;
       }

       pinfo->pdev = pdev;
       platform_set_drvdata(pdev, pinfo);
       return 0;

reg_fail:
       ret = PTR_ERR(pinfo->tzd[i]);
       while (--i >= 0)
               thermal_zone_device_unregister(pinfo->tzd[i]);
       configure_adc(0);
       kfree(pinfo);
       return ret;
}

/**
 * mid_thermal_remove - mfld thermal finalize
 * @dev: platform device structure
 *
 * MLFD thermal remove unregisters all the sensors from the generic
 * thermal framework. Can sleep.
 */
static int mid_thermal_remove(struct platform_device *pdev)
{
       int i;
       struct platform_info *pinfo = platform_get_drvdata(pdev);

       for (i = 0; i < MSIC_THERMAL_SENSORS; i++)
               thermal_zone_device_unregister(pinfo->tzd[i]);

       platform_set_drvdata(pdev, NULL);

       /* Stop the ADC */
       return configure_adc(0);
}

/*********************************************************************
 *             Driver initialisation and finalization
 *********************************************************************/

#define DRIVER_NAME "msic_sensor"

static const struct platform_device_id therm_id_table[] = {
       { DRIVER_NAME, 1 },
       { }
};

static struct platform_driver mid_thermal_driver = {
       .driver = {
               .name = DRIVER_NAME,
               .owner = THIS_MODULE,
       },
       .probe = mid_thermal_probe,
       .suspend = mid_thermal_suspend,
       .resume = mid_thermal_resume,
       .remove = __devexit_p(mid_thermal_remove),
       .id_table = therm_id_table,
};

static int __init mid_thermal_module_init(void)
{
       return platform_driver_register(&mid_thermal_driver);
}

static void __exit mid_thermal_module_exit(void)
{
       platform_driver_unregister(&mid_thermal_driver);
}

module_init(mid_thermal_module_init);
module_exit(mid_thermal_module_exit);

MODULE_AUTHOR("Durgadoss R <durgadoss.r@intel.com>");
MODULE_DESCRIPTION("Intel Medfield Platform Thermal Driver");
MODULE_LICENSE("GPL");
