コード例 #1
0
ファイル: max77660_haptic.c プロジェクト: FrozenCow/FIRE-ICE
static int max77660_haptic_set_duty_cycle(struct max77660_haptic *chip)
{
	int duty, i;
	u8 duty_index = 0;
	int ret = 0;
	int reg1 = 0xFF, reg2 = 0xFF;
	bool internal_mode_valid = true;

	if (chip->mode == MAX77660_EXTERNAL_MODE) {
		duty = chip->pwm_period * chip->level / 100;
		ret = pwm_config(chip->pwm, duty, chip->pwm_period);
	} else {
		for (i = 0; i < 64; i++) {
			if (chip->level <= (i + 1) * 100 / 64) {
				duty_index = i;
				break;
			}
		}
		switch (chip->internal_mode_pattern) {
		case 0:
			reg1 = MAX77660_HAPTIC_REG_SIGDC1;
			reg2 = MAX77660_HAPTIC_REG_SIGPWMDC1;
			break;
		case 1:
			reg1 = MAX77660_HAPTIC_REG_SIGDC1;
			reg2 = MAX77660_HAPTIC_REG_SIGPWMDC2;
			break;
		case 2:
			reg1 = MAX77660_HAPTIC_REG_SIGDC2;
			reg2 = MAX77660_HAPTIC_REG_SIGPWMDC3;
			break;
		case 3:
			reg1 = MAX77660_HAPTIC_REG_SIGDC1;
			reg2 = MAX77660_HAPTIC_REG_SIGPWMDC4;
			break;
		default:
			internal_mode_valid = false;
			break;
		}

		if (internal_mode_valid) {
			if (chip->internal_mode_pattern % 2 == 1)
				max77660_reg_write(chip->dev->parent,
					MAX77660_HAPTIC_SLAVE, reg1,
					chip->feedback_duty_cycle);
			else
				max77660_reg_write(chip->dev->parent,
					MAX77660_HAPTIC_SLAVE, reg1,
					chip->feedback_duty_cycle << 4);

			max77660_reg_write(chip->dev->parent,
				MAX77660_HAPTIC_SLAVE, reg2, duty_index);
		}
	}
	return ret;
}
コード例 #2
0
static int max77660_adc_enable(struct max77660_adc *adc, int enable)
{
	int ret;

	if (enable)
		ret = max77660_reg_write(adc->parent, MAX77660_PWR_SLAVE,
				MAX77660_REG_ADCCTRL,
				adc->adc_control | MAX77660_ADCCTRL_ADCEN);
	else
		ret = max77660_reg_write(adc->parent, MAX77660_PWR_SLAVE,
				MAX77660_REG_ADCCTRL, adc->adc_control);
	if (ret < 0)
		dev_err(adc->dev, "ADCCTRL write failed: %d\n", ret);
	return ret;
}
コード例 #3
0
static void max77660_haptic_enable(struct max77660_haptic *chip, bool enable)
{
//  printk("Ivan max77660_haptic_enable = %d \n", enable);
	if (chip->enabled == enable)
		return;

//	mutex_lock(&chip->enable_lock);
	chip->enabled = enable;

	if (enable) {
//  printk("Ivan max77660_haptic_enable ENABLE! \n");	  
		regulator_enable(chip->regulator);
		max77660_haptic_configure(chip);
		if (chip->mode == MAX77660_EXTERNAL_MODE)
			pwm_enable(chip->pwm);
//		haptic_enable_processing = 0;		//Ivan
	} else {
//  printk("Ivan max77660_haptic_enable DISABLE! \n");	  
		max77660_haptic_configure(chip);
		
	max77660_reg_write(chip->dev->parent, MAX77660_HAPTIC_SLAVE,
		MAX77660_HAPTIC_REG_CONF2, 2);
	
		if (chip->mode == MAX77660_EXTERNAL_MODE)
			pwm_disable(chip->pwm);
		regulator_disable(chip->regulator);
	}
//	mutex_unlock(&chip->enable_lock);
}
コード例 #4
0
static void max77660_power_reset(void)
{
	struct max77660_chip *chip = max77660_chip;

	if (!chip)
		return;

	dev_info(chip->dev, "%s: PMIC Reset\n", __func__);
	/*
	 * ES1.0 errata suggest that in place of doing read modify write,
	 * write direct valid value.
	 */
	max77660_reg_write(chip->dev, MAX77660_PWR_SLAVE,
			MAX77660_REG_GLOBAL_CFG0, 1);
	do { } while (1);
}
コード例 #5
0
void max77660_power_forceoff(void)
{
	struct max77660_chip *chip = max77660_chip;

	if (!chip)
		return;
	mdelay(500);
	dev_info(chip->dev, "%s: Global shutdown\n", __func__);
	/*
	 * ES1.0 errata suggest that in place of doing read modify write,
	 * write direct valid value.
	 */

	max77660_reg_write(chip->dev, MAX77660_PWR_SLAVE,
			MAX77660_REG_GLOBAL_CFG0,
			GLBLCNFG0_SFT_OFF_SYSRST_MASK);

}
コード例 #6
0
static int max77660_adc_wakeup_reset(struct max77660_adc *adc)
{
	int ret;

	ret = max77660_reg_write(adc->parent, MAX77660_PWR_SLAVE,
			MAX77660_REG_ADCINTM, 0xFF);
	if (ret < 0) {
		dev_err(adc->dev, "ADCINTM write failed\n");
		return ret;
	}

	ret = max77660_reg_update(adc->parent, MAX77660_PWR_SLAVE,
		MAX77660_REG_ADCCTRL, 0, MAX77660_ADCCTRL_ADCCONT);
	if (ret < 0) {
		dev_err(adc->dev, "ADCCTR update failed: %d\n", ret);
		return ret;
	}
	return 0;
}
コード例 #7
0
ファイル: max77660_haptic.c プロジェクト: FrozenCow/FIRE-ICE
static void max77660_haptic_configure(struct max77660_haptic *chip)
{
	u8 value1, value2, reg1, reg2;
	bool internal_mode_valid = true;

	value1 = chip->type << MAX77660_MOTOR_TYPE_SHIFT |
		chip->enabled << MAX77660_ENABLE_SHIFT |
		chip->mode << MAX77660_MODE_SHIFT | chip->pwm_divisor;
	max77660_reg_write(chip->dev->parent, MAX77660_HAPTIC_SLAVE,
		MAX77660_HAPTIC_REG_CONF2, value1);

	value1 = chip->invert << MAX77660_INVERT_SHIFT |
		chip->cont_mode << MAX77660_CONT_MODE_SHIFT |
		chip->motor_startup_val << MAX77660_MOTOR_STRT_SHIFT |
		chip->scf_val;

	max77660_reg_write(chip->dev->parent, MAX77660_HAPTIC_SLAVE,
		MAX77660_HAPTIC_REG_CONF1, value1);

	if (chip->mode == MAX77660_INTERNAL_MODE) {
		if (chip->enabled) {

			switch (chip->internal_mode_pattern) {
			case 0:
				value1 = chip->pattern_cycle << 4;
				reg1 = MAX77660_HAPTIC_REG_CYCLECONF1;
				value2 = chip->pattern_signal_period;
				reg2 = MAX77660_HAPTIC_REG_SIGCONF1;
				break;
			case 1:
				value1 = chip->pattern_cycle;
				reg1 = MAX77660_HAPTIC_REG_CYCLECONF1;
				value2 = chip->pattern_signal_period;
				reg2 = MAX77660_HAPTIC_REG_SIGCONF2;
				break;
			case 2:
				value1 = chip->pattern_cycle << 4;
				reg1 = MAX77660_HAPTIC_REG_CYCLECONF2;
				value2 = chip->pattern_signal_period;
				reg2 = MAX77660_HAPTIC_REG_SIGCONF3;
				break;
			case 3:
				value1 = chip->pattern_cycle;
				reg1 = MAX77660_HAPTIC_REG_CYCLECONF2;
				value2 = chip->pattern_signal_period;
				reg2 = MAX77660_HAPTIC_REG_SIGCONF4;
				break;
			default:
				internal_mode_valid = false;
				break;
			}

			if (internal_mode_valid) {
				max77660_reg_write(chip->dev->parent,
					MAX77660_HAPTIC_SLAVE, reg1, value1);
				max77660_reg_write(chip->dev->parent,
					MAX77660_HAPTIC_SLAVE, reg2, value2);
				value1 = chip->internal_mode_pattern
						<< MAX77660_CYCLE_SHIFT |
				      chip->internal_mode_pattern
						<< MAX77660_SIG_PERIOD_SHIFT |
				      chip->internal_mode_pattern
						<< MAX77660_SIG_DUTY_SHIFT |
				      chip->internal_mode_pattern
						<< MAX77660_PWM_DUTY_SHIFT;
				max77660_reg_write(chip->dev->parent,
					MAX77660_HAPTIC_SLAVE,
					MAX77660_HAPTIC_REG_DRVCONF, value1);
			}
		}
	}
}
コード例 #8
0
static int max77660_adc_wakeup_configure(struct max77660_adc *adc)
{
	int thres_h, thres_l, ch;
	u8 int_mask, ch1, ch0;
	u8 adc_avg;
	int ret;

	thres_h = 0;
	thres_l = 0;
	int_mask = 0xFF;
	ch = adc->adc_wake_props.adc_channel_number;
	if (adc->adc_wake_props.adc_high_threshold > 0) {
		thres_h = adc->adc_wake_props.adc_high_threshold & 0xFFF;
		int_mask &= ~MAX77660_ADCINT_DTRINT;
	}
	if (adc->adc_wake_props.adc_low_threshold > 0) {
		thres_l = adc->adc_wake_props.adc_low_threshold & 0xFFF;
		int_mask &= ~MAX77660_ADCINT_DTFINT;
	}

	ch0 = (ch > 7) ? 0 : BIT(ch);
	ch1 = (ch > 7) ? BIT(ch - 8) : 0;

	if (adc->adc_wake_props.adc_avg_sample <= 1)
		adc_avg = MAX77660_ADCCTRL_ADCAVG(0);
	else if (adc->adc_wake_props.adc_avg_sample <= 2)
		adc_avg = MAX77660_ADCCTRL_ADCAVG(1);
	else if (adc->adc_wake_props.adc_avg_sample <= 16)
		adc_avg = MAX77660_ADCCTRL_ADCAVG(2);
	else
		adc_avg = MAX77660_ADCCTRL_ADCAVG(3);

	ret = max77660_reg_write(adc->parent, MAX77660_PWR_SLAVE,
			MAX77660_REG_DTRL, thres_h & 0xFF);
	if (ret < 0) {
		dev_err(adc->dev, "DTRL write failed: %d\n", ret);
		return ret;
	}
	ret = max77660_reg_write(adc->parent, MAX77660_PWR_SLAVE,
			MAX77660_REG_DTRH, (thres_h >> 8) & 0xF);
	if (ret < 0) {
		dev_err(adc->dev, "DTRH write failed: %d\n", ret);
		return ret;
	}

	ret = max77660_reg_write(adc->parent, MAX77660_PWR_SLAVE,
			MAX77660_REG_DTFL, thres_l & 0xFF);
	if (ret < 0) {
		dev_err(adc->dev, "DTFL write failed: %d\n", ret);
		return ret;
	}
	ret = max77660_reg_write(adc->parent, MAX77660_PWR_SLAVE,
			MAX77660_REG_DTFH, (thres_l >> 8) & 0xF);
	if (ret < 0) {
		dev_err(adc->dev, "DTFH write failed: %d\n", ret);
		return ret;
	}

	ret = max77660_reg_write(adc->parent, MAX77660_PWR_SLAVE,
			MAX77660_REG_ADCSEL0, ch0);
	if (ret < 0) {
		dev_err(adc->dev, "ADCSEL0 write failed: %d\n", ret);
		return ret;
	}
	ret = max77660_reg_write(adc->parent, MAX77660_PWR_SLAVE,
			MAX77660_REG_ADCSEL1, ch1);
	if (ret < 0) {
		dev_err(adc->dev, "ADCSEL1 write failed: %d\n", ret);
		return ret;
	}

	ret = max77660_reg_update(adc->parent, MAX77660_PWR_SLAVE,
			MAX77660_REG_ADCCTRL, adc_avg,
			MAX77660_ADCCTRL_ADCAVG_MASK);
	if (ret < 0) {
		dev_err(adc->dev, "ADCCTRL update failed: %d\n", ret);
		return ret;
	}

	ret = max77660_reg_write(adc->parent, MAX77660_PWR_SLAVE,
			MAX77660_REG_ADCINTM, int_mask);
	if (ret < 0) {
		dev_err(adc->dev, "ADCINTM write failed\n");
		return ret;
	}

	ret = max77660_reg_update(adc->parent, MAX77660_PWR_SLAVE,
		MAX77660_REG_ADCCTRL, MAX77660_ADCCTRL_ADCCONT,
		MAX77660_ADCCTRL_ADCCONT);
	if (ret < 0) {
		dev_err(adc->dev, "ADCCTR update failed: %d\n", ret);
		return ret;
	}
	return 0;
}
コード例 #9
0
static int max77660_adc_start_convertion(struct max77660_adc *adc, int adc_chan)
{
	u8 adc_l;
	u8 adc_h;
	int ret;
	u8 chan0 = 0;
	u8 chan1 = 0;

	ret = max77660_adc_enable(adc, true);
	if (ret < 0)
		return ret;

	ret = max77660_adc_start_mask_interrupt(adc,
				MAX77660_ADCINT_ADCCONVINT, 0);
	if (ret < 0)
		goto out;

	if (adc_chan < 8)
		chan0 = BIT(adc_chan);
	else
		chan1 = BIT(adc_chan - 8);

	ret = max77660_reg_write(adc->parent, MAX77660_PWR_SLAVE,
		MAX77660_REG_ADCSEL0, chan0);
	if (ret < 0) {
		dev_err(adc->dev, "ADCSEL0 write failed: %d\n", ret);
		goto out;
	}

	ret = max77660_reg_write(adc->parent, MAX77660_PWR_SLAVE,
		MAX77660_REG_ADCSEL1, chan1);
	if (ret < 0) {
		dev_err(adc->dev, "ADCSEL1 write failed: %d\n", ret);
		goto out;
	}

	ret = max77660_reg_write(adc->parent, MAX77660_PWR_SLAVE,
		MAX77660_REG_ADCCHSEL, adc_chan);
	if (ret < 0) {
		dev_err(adc->dev, "ADCCHSEL write failed: %d\n", ret);
		goto out;
	}

	if (adc_chan >= MAX77660_ADC_CH_ADC0) {
		int chan_num = adc_chan - MAX77660_ADC_CH_ADC0;
		u8 iadc = adc->iadc_val;
		iadc |= MAX77660_IADC_IADCMUX(chan_num);
		ret = max77660_reg_write(adc->parent, MAX77660_PWR_SLAVE,
			MAX77660_REG_IADC, iadc);
		if (ret < 0) {
			dev_err(adc->dev, "IADC write failed: %d\n", ret);
			goto out;
		}
	}

	if (adc->adc_info[adc_chan].acquisition_time_us)
		udelay(adc->adc_info[adc_chan].acquisition_time_us);

	INIT_COMPLETION(adc->conv_completion);
	ret = max77660_reg_update(adc->parent, MAX77660_PWR_SLAVE,
			MAX77660_REG_ADCCTRL, MAX77660_ADCCTRL_ADCCONV,
			MAX77660_ADCCTRL_ADCCONV);
	if (ret < 0) {
		dev_err(adc->dev, "ADCCTR write failed: %d\n", ret);
		goto out;
	}

	ret = wait_for_completion_timeout(&adc->conv_completion,
				ADC_CONVERTION_TIMEOUT);
	if (ret == 0) {
		dev_err(adc->dev, "ADC conversion not completed\n");
		ret = -ETIMEDOUT;
		goto out;
	}

	ret = max77660_reg_read(adc->parent, MAX77660_PWR_SLAVE,
			MAX77660_REG_ADCDATAL, &adc_l);
	if (ret < 0) {
		dev_err(adc->dev, "ADCDATAL read failed: %d\n", ret);
		goto out;
	}

	ret = max77660_reg_read(adc->parent, MAX77660_PWR_SLAVE,
			MAX77660_REG_ADCDATAH, &adc_h);
	if (ret < 0) {
		dev_err(adc->dev, "ADCDATAH read failed: %d\n", ret);
		goto out;
	}

	ret = ((adc_h & 0xF) << 8) | adc_l;

out:
	max77660_adc_start_mask_interrupt(adc, MAX77660_ADCINT_ADCCONVINT, 1);
	max77660_adc_enable(adc, false);
	return ret;
}