/* Interrupt handlers */
static irqreturn_t vrd_changed_handler(int irq, void *_chip)
{
	int rc, old_current;
	u8 reg;
	struct qpnp_typec_chip *chip = _chip;

	pr_debug("vrd changed triggered\n");

	mutex_lock(&chip->typec_lock);
	rc = qpnp_typec_read(chip, &reg, TYPEC_UFP_STATUS_REG(chip->base), 1);
	if (rc) {
		pr_err("failed to read status reg rc=%d\n", rc);
		goto out;
	}

	old_current = chip->current_ma;
	chip->current_ma = get_max_current(reg & TYPEC_CURRENT_MASK);

	/* only notify if current is valid and changed at runtime */
	if (chip->current_ma && (old_current != chip->current_ma)) {
		rc = set_property_on_battery(chip,
				POWER_SUPPLY_PROP_CURRENT_CAPABILITY);
		if (rc)
			pr_err("failed to set INPUT CURRENT MAX on battery psy rc=%d\n",
					rc);
	}

	pr_debug("UFP status reg = 0x%x old current = %dma new current = %dma\n",
			reg, old_current, chip->current_ma);

out:
	mutex_unlock(&chip->typec_lock);
	return IRQ_HANDLED;
}
static irqreturn_t ufp_detect_handler(int irq, void *_chip)
{
	int rc;
	u8 reg;
	struct qpnp_typec_chip *chip = _chip;

	pr_debug("ufp detect triggered\n");

	mutex_lock(&chip->typec_lock);
	rc = qpnp_typec_read(chip, &reg, TYPEC_UFP_STATUS_REG(chip->base), 1);
	if (rc) {
		pr_err("failed to read status reg rc=%d\n", rc);
		goto out;
	}

	rc = qpnp_typec_handle_usb_insertion(chip, reg);
	if (rc) {
		pr_err("failed to handle USB insertion rc=%d\n", rc);
		goto out;
	}

	chip->current_ma = get_max_current(reg & TYPEC_CURRENT_MASK);
	/* device in UFP state */
	chip->typec_state = POWER_SUPPLY_TYPE_UFP;
	chip->type_c_psy.type = POWER_SUPPLY_TYPE_UFP;
	rc = set_property_on_battery(chip, POWER_SUPPLY_PROP_TYPEC_MODE);
	if (rc)
		pr_err("failed to set TYPEC MODE on battery psy rc=%d\n", rc);

	pr_debug("UFP status reg = 0x%x current = %dma\n",
			reg, chip->current_ma);

out:
	mutex_unlock(&chip->typec_lock);
	return IRQ_HANDLED;
}
//////////////////////////////////////////////////////////////////////////////
/// \brief Saves the complete current configuration parameters to the eeprom
///  When this function is called, it marks the given memory area with a flag and writes the current config parameters to the specified addresses (.h)
/// \param config The Memory Area where the configuration should be saved [1...4]
//////////////////////////////////////////////////////////////////////////////
VMC_UCHAR_8 save_configuration(VMC_UCHAR_8 config ) {

	
	//loop counter
	VMC_UCHAR_8 i;

	//variables to save the calculated memory addresses
	VMC_UINT_16 base;
	VMC_UINT_16 motor;



	// Which memory area is the target-->which address is the actual base address
	base = (_OFFSET_CONFIG_ * config) + _OFFSET_BASE_;

	i2c_init();
	//Set the flag
	i2c_storeByte(0xaa, base + _ADDR_FLAG_);


	//Write the motor independent Parameter to the eeprom, addresses in headerfile

	i2c_storeInt(get_timeout(), base + (2* _ADDR_TIMEOUT_) );

	//For every motor: calculate a motorspecific offset
	for(i = 0; i < _NUM_MOTORS_; i++) {

		motor = base + ((i + 1) * _OFFSET_MOTOR_ );
		//and write all motorrdepending parameters to the eeprom
		i2c_storeInt(get_max_current(i), 	motor + (2 * _ADDR_MAX_CURRENT_) );
		i2c_storeInt(get_max_RPM(i), 		motor + (2 * _ADDR_MAX_RPM_) );
		i2c_storeInt(get_nom_current(i), 	motor + (2 * _ADDR_NOM_CURRENT_) );
		i2c_storeInt(get_nom_RPM(i), 		motor + (2 * _ADDR_NOM_RPM_) );
		i2c_storeInt(get_gear_reduction(i), motor + (2 * _ADDR_GEAR_REDUCTION_) );
		i2c_storeInt(get_wheel_radius(i), 	motor + (2 * _ADDR_WHEEL_RADIUS_) );

		i2c_storeInt(get_spec_torque(i), 	motor + (2 * _ADDR_SPEC_TORQUE_) );
		i2c_storeInt(get_ticks_rot(i), 		motor + (2 * _ADDR_TICKS_ROT_) );
		i2c_storeInt(get_max_temp(i), 		motor + (2 * _ADDR_MAX_TEMP_) );
		i2c_storeInt(get_nom_temp(i), 		motor + (2 * _ADDR_NOM_TEMP_) );
		i2c_storeInt(get_winding_t(i), 		motor + (2 * _ADDR_WINDING_T_) );
		i2c_storeInt(get_winding_g_z(i), 	motor + (2 * _ADDR_WINDING_G_Z_) );
		i2c_storeInt(get_winding_g_n(i), 	motor + (2 * _ADDR_WINDING_G_N_) );
		i2c_storeInt(get_chassis_t(i), 		motor + (2 * _ADDR_CHASSIS_T_) );
		i2c_storeInt(get_chassis_g_z(i), 	motor + (2 * _ADDR_CHASSIS_G_Z_) );	
		i2c_storeInt(get_chassis_g_n(i), 	motor + (2 * _ADDR_CHASSIS_G_N_) );

		// Controller Parameters
		i2c_storeInt(ctrl_get_Kpr(i), 		motor + (2 * _ADDR_KP_) );
		i2c_storeInt(ctrl_get_Tn(i), 		motor + (2 * _ADDR_TN_) );
		i2c_storeInt(ctrl_get_Tv(i), 		motor + (2 * _ADDR_TV_) );
		i2c_storeInt(ctrl_get_deadband(i), 	motor + (2 * _ADDR_DEADBAND_) );

		i2c_storeInt(ctrl_get_nRamp(i), 	motor + (2 * _ADDR_NRAMP_) );
		i2c_storeInt(ctrl_get_pRamp(i), 	motor + (2 * _ADDR_PRAMP_) );

		i2c_storeInt(get_direction(i), 				motor + (2 * _ADDR_DIRECTION_) );
		i2c_storeInt(get_controller_active(i), 		motor + (2 * _ADDR_CONTROLLER_) );
		i2c_storeInt(get_use_PWM(i), 				motor + (2 * _ADDR_USEPWM_) );
		i2c_storeInt(get_currentlimiter_active(i), 	motor + (2 * _ADDR_LIMITER_) );

	}
	//Initializize the cycletime counter because of the "break"

	init_cycletime_counter();
    return 1;
}