static int set_up_therm_channel(u16 base_addr)
{
	int ret;

	
	ret = intel_msic_reg_write(base_addr, SKIN_SENSOR0_CODE);
	if (ret)
		return ret;

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

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

	ret = intel_msic_reg_write(base_addr + 3,
			(MSIC_DIE_SENSOR_CODE | 0x10));
	if (ret)
		return ret;

	
	return configure_adc(1);
}
/**
 * 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_msic_reg_write(base_addr, SKIN_SENSOR0_CODE);
	if (ret)
		return ret;

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

	ret = intel_msic_reg_write(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_msic_reg_write(base_addr + 3,
			(MSIC_DIE_SENSOR_CODE | 0x10));
	if (ret)
		return ret;

	/* Enable ADC and start it */
	return configure_adc(1);
}
Ejemplo n.º 3
0
/**
* intel_pmic_reg_setvoltage - Set voltage to the regulator
* @rdev:    regulator_dev structure
* @min_uV: Minimum required voltage in uV
* @max_uV: Maximum acceptable voltage in uV
* @selector: Voltage value passed back to core layer
* Sets a voltage regulator to the desired output voltage
* @return value : Returns 0 if success
*			: Return INTEL_REGULATOR_ERR
*/
static int intel_pmic_reg_setvoltage(struct regulator_dev *rdev, int min_uV,
					int max_uV, unsigned *selector)
{
	struct intel_pmic_info *pmic_info = rdev_get_drvdata(rdev);
	int ret;
	u8 reg, vsel;

	pmic_dbg("This is intel_pmic_reg_setvoltage function for %s\n",
				rdev->desc->name);
	for (vsel = 0; vsel < pmic_info->table_len; vsel++) {
		int mV = pmic_info->table[vsel];
		int uV = mV * 1000;
		if (min_uV <= uV && uV <= max_uV) {
			*selector = vsel;
			ret = intel_msic_reg_read(pmic_info->pmic_reg, &reg);
			if (ret) {
				pmic_err("intel_msic_reg_read returns"
							"error %08x\n", ret);
				return INTEL_REGULATOR_ERR;
			}
			reg &= ~REG_VSEL_MASK;
			reg |= vsel << VSEL_SHIFT;
			pmic_dbg("intel_pmic_reg_setvoltage voltage is"
						"val %xuV\n", reg);
			return intel_msic_reg_write(pmic_info->pmic_reg,
						reg);
		}
	}
	return INTEL_REGULATOR_ERR;
}
/**
 * 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_msic_reg_write(INTEL_MSIC_ADC1CNTL3, MSIC_ADCRRDATA_ENBL);
	if (ret)
		return ret;

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

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

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

	ret = intel_msic_reg_read(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;
}
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;

	
	ret = intel_msic_reg_write(INTEL_MSIC_ADC1CNTL3, MSIC_ADCRRDATA_ENBL);
	if (ret)
		return ret;

	
	ret = intel_msic_reg_write(INTEL_MSIC_ADC1CNTL3, MSIC_ADCTHERM_ENBL);
	if (ret)
		return ret;

	
	ret = intel_msic_reg_read(addr, &data);
	if (ret)
		return ret;

	
	adc_val = (data << 2);
	addr++;

	ret = intel_msic_reg_read(addr, &data);
	if (ret)
		return ret;

	
	data &= 03;
	adc_val += data;

	
	ret = adc_to_temp(td_info->direct, adc_val, &curr_temp);
	if (ret == 0)
		*temp = td_info->curr_temp = curr_temp;
	return ret;
}
/**
 * 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_msic_reg_read(addr, &data);
	if (ret)
		return ret;
	/* Set the stop bit to zero */
	return intel_msic_reg_write(addr, (data & 0xEF));
}
/**
 * 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_msic_reg_read(INTEL_MSIC_ADC1CNTL3, &data);
	if (ret)
		return ret;

	data &= ~MSIC_ADCTHERM_MASK;
	ret = intel_msic_reg_write(INTEL_MSIC_ADC1CNTL3, data);
	if (ret)
		return ret;

	/* 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;
}
/**
 * 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_msic_reg_read(INTEL_MSIC_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_msic_reg_write(INTEL_MSIC_ADC1CNTL1, data);
}
Ejemplo n.º 9
0
/**
* intel_pmic_reg_enable - To enable the regulator
* @rdev:    regulator_dev structure
* @return value : 0 - Regulator enabling success
*			:1 - Regulator enabling failed
*/
static int intel_pmic_reg_enable(struct regulator_dev *rdev)
{
	struct intel_pmic_info *pmic_info = rdev_get_drvdata(rdev);
	u8  reg;
	int ret;

	pmic_dbg("This is enable function for %s\n", rdev->desc->name);
	ret = intel_msic_reg_read(pmic_info->pmic_reg, &reg);
	if (ret) {
		pmic_err("intel_msic_reg_read returns"
					"error %08x\n", ret);
		return INTEL_REGULATOR_ERR;
	}
	ret = intel_msic_reg_write(pmic_info->pmic_reg,
				((reg & REG_CTRL_MASK) | MSIC_REG_ON));
    if (!ret && pmic_info && pmic_info->after_vreg_on)
        ret = (pmic_info->after_vreg_on)();
    return ret;
}
static int mid_initialize_adc(struct device *dev)
{
	u8  data;
	u16 base_addr;
	int ret;

	ret = intel_msic_reg_read(INTEL_MSIC_ADC1CNTL3, &data);
	if (ret)
		return ret;

	data &= ~MSIC_ADCTHERM_MASK;
	ret = intel_msic_reg_write(INTEL_MSIC_ADC1CNTL3, data);
	if (ret)
		return ret;

	
	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)) {
		
		ret = reset_stopbit(base_addr);
		if (ret)
			return ret;

		
		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;
}
Ejemplo n.º 11
0
/**
* intel_pmic_reg_setmode - Set the regulator mode
* @rdev:    regulator_dev structure
* Set the regulator mode
* @return value:	Returns  0 if success
			:	Return INTEL_REGULATOR_ERR
*/
static int intel_pmic_reg_setmode(struct regulator_dev *rdev, unsigned mode)
{
	struct intel_pmic_info *pmic_info = rdev_get_drvdata(rdev);
	int ret;
	u8 reg, avp_mode;

	pmic_dbg("This is intel_pmic_reg_setmode function for %s\n",
				rdev->desc->name);
	ret = intel_msic_reg_read(pmic_info->pmic_reg, &reg);
	if (ret) {
		pmic_err("intel_msic_reg_read returns error %08x\n",
					ret);
		return INTEL_REGULATOR_ERR;
	}
	reg &= ~CTL_REG_MASK;
	switch (mode) {
	case REGULATOR_MODE_NORMAL:
		avp_mode = REGULATOR_NORMAL_MODE;
		break;
	case REGULATOR_MODE_FAST:
		avp_mode = REGULATOR_AUTO_MODE;
		break;
	case REGULATOR_MODE_IDLE:
	case REGULATOR_MODE_STANDBY:
		avp_mode = REGULATOR_LOW_POWER_MODE;
		break;
	case REGULATOR_STATUS_OFF:
		avp_mode = REGULATOR_OFF_MODE;
		break;
	default:
		pmic_dbg("Mode is not a valid one MODE %d", mode);
		return INTEL_REGULATOR_ERR;
	}
	pmic_dbg("intel_pmic_reg_setmode is %d\n", avp_mode);
	return intel_msic_reg_write(pmic_info->pmic_reg, (reg|avp_mode));
}