static int find_free_channel(void)
{
	int ret;
	int i;
	uint8_t data;

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

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

	
	for (i = 0; i < ADC_CHANLS_MAX; i++) {
		ret = intel_msic_reg_read(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;
}
/**
 * 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_msic_reg_read(INTEL_MSIC_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_msic_reg_read(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;
}
Beispiel #3
0
/**
* intel_pmic_reg_is_enabled - To check if the regulator is enabled
* @rdev:    regulator_dev structure
* @return value : 0 - Regulator is ON
*			  :1 - Regulator is OFF
*/
static int intel_pmic_reg_is_enabled(struct regulator_dev *rdev)
{
	struct intel_pmic_info *pmic_info = rdev_get_drvdata(rdev);
	u8 reg, mode;
	int ret;

	pmic_dbg("This is is_enabled function %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;
	}
	mode = reg & CTL_REG_MASK ;
	switch (mode) {
	case REGULATOR_NORMAL_MODE:
	case REGULATOR_AUTO_MODE:
	case REGULATOR_LOW_POWER_MODE:
		return 1;
	case REGULATOR_OFF_MODE:
		return 0;
	default:
		pmic_dbg("UNDEFINED MODE but returning OFF!!\n");
		return 0;
	}
}
Beispiel #4
0
/**
* intel_pmic_reg_getmode - Get the regulator mode
* @rdev:    regulator_dev structure
* Get the regulator mode
* @return value   : Returns  mode
*				: Return INTEL_REGULATOR_ERR
 */
static unsigned int intel_pmic_reg_getmode(struct regulator_dev *rdev)
{
	struct intel_pmic_info *pmic_info = rdev_get_drvdata(rdev);
	int ret;
	u8 reg, mode;

	pmic_dbg("This is intel_pmic_reg_getmode 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;
	}
	mode = (reg & CTL_REG_MASK);
	switch (mode) {
	case REGULATOR_NORMAL_MODE:
		return REGULATOR_MODE_NORMAL;
	case REGULATOR_AUTO_MODE:
		return REGULATOR_MODE_FAST;
	case REGULATOR_LOW_POWER_MODE:
		return REGULATOR_MODE_STANDBY;
	case REGULATOR_OFF_MODE:
		return REGULATOR_STATUS_OFF;
	default:
		pmic_dbg("Mode is not a valid one MODE %d", mode);
	}
	return INTEL_REGULATOR_ERR;
}
Beispiel #5
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));
}
Beispiel #9
0
static int msic_gpio_get(struct gpio_chip *chip, unsigned offset)
{
	u8 r;
	int ret;
	int reg;

	reg = msic_gpio_to_ireg(offset);
	if (reg < 0)
		return reg;

	ret = intel_msic_reg_read(reg, &r);
	if (ret < 0)
		return ret;

	return r & MSIC_GPIO_DIN_MASK;
}
/**
 * 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);
}
Beispiel #12
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;
}
static irqreturn_t mfld_pb_isr(int irq, void *dev_id)
{
	struct input_dev *input = dev_id;
	int ret;
	u8 pbstat;

	ret = intel_msic_reg_read(INTEL_MSIC_PBSTATUS, &pbstat);
	dev_dbg(input->dev.parent, "PB_INT status= %d\n", pbstat);

	if (ret < 0) {
		dev_err(input->dev.parent, "Read error %d while reading"
			       " MSIC_PB_STATUS\n", ret);
	} else {
		input_event(input, EV_KEY, KEY_POWER,
			       !(pbstat & MSIC_PB_LEVEL));
		input_sync(input);
	}

	return IRQ_HANDLED;
}
Beispiel #15
0
/**
* intel_pmic_reg_getvoltage - Return the current voltage value in  uV
* @rdev:    regulator_dev structure
*  @return value : Returns the voltage value.
*/
static int intel_pmic_reg_getvoltage(struct regulator_dev *rdev)
{
	struct intel_pmic_info *pmic_info = rdev_get_drvdata(rdev);
	u8  reg, vsel;
	int ret;

	pmic_dbg("intel_pmic_reg_getvoltage 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;
	}
	vsel = (reg & REG_VSEL_MASK) >> VSEL_SHIFT;
	if (vsel >= pmic_info->table_len) {
		pmic_err("vsel value is out of range\n");
		return INTEL_REGULATOR_ERR;
	}
	pmic_dbg("Voltage value is %d mV\n",
	pmic_info->table[vsel]);
	return pmic_info->table[vsel] * 1000;
}
Beispiel #16
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));
}