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; }
/** * 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, ®); 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; } }
/** * 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, ®); 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; }
/** * 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, ®); 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)); }
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); }
/** * 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, ®); 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; }
/** * 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, ®); 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; }
/** * 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, ®); 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)); }