/*
 * 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 accommodate 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");
