// Copyright 2012 Google Inc. All Rights Reserved.
// Author: kedong@google.com (Ke Dong)

#ifndef BRUNO_PLATFORM_PERIPHERAL_FANCONTROL_H_
#define BRUNO_PLATFORM_PERIPHERAL_FANCONTROL_H_

#include "bruno/constructormagic.h"
#include "platform.h"
#include "mailbox.h"

namespace bruno_platform_peripheral {

class Platform;

#define DUTY_CYCLE_PWM_MIN_VALUE    0
#define DUTY_CYCLE_PWM_MAX_VALUE    100


typedef struct FanControlParams {
  uint16_t  temp_setpt;
  uint16_t  temp_max;
  uint16_t  temp_step;
  uint16_t  duty_cycle_min;
  uint16_t  duty_cycle_max;
  uint16_t  pwm_step;
  uint16_t  temp_overheat;

  FanControlParams& operator = (const FanControlParams& param) {
    temp_setpt = param.temp_setpt;
    temp_max = param.temp_max;
    temp_step = param.temp_step;
    duty_cycle_min = param.duty_cycle_min;
    duty_cycle_max = param.duty_cycle_max;
    pwm_step = param.pwm_step;
    temp_overheat = param.temp_overheat;
    return *this;
  }

}FanControlParams;


class FanControl : public Mailbox {
 public:
  enum StateType {
    OFF,
    VAR_SPEED,
    FULL_SPEED
  };

  enum FanControlParamsTypes {
    BRUNO_SOC = 0,
    BRUNO_IS_HDD,
    BRUNO_AUX1,
    BRUNO_PARAMS_TYPES_MAX
  };

  static const unsigned int kPwmDefaultStartup;
  static const unsigned int kPwmMinValue;
  static const unsigned int kPwmMaxValue;
  static const unsigned int kFanSpeedNotSpinning;

  static const FanControlParams kGFMS100FanCtrlSocDefaults;
  static const FanControlParams kGFMS100FanCtrlHddDefaults;

  static const FanControlParams kGFRG200FanCtrlSocDefaults;

  static const FanControlParams kGFRG210FanCtrlSocDefaults;
  static const FanControlParams kGFRG210FanCtrlHddDefaults;

  static const FanControlParams kGFRG250FanCtrlSocDefaults;
  static const FanControlParams kGFRG250FanCtrlHddDefaults;
  static const FanControlParams kGFRG250FanCtrlAux1Defaults;

  static const FanControlParams kGFSC100FanCtrlSocDefaults;
  static const FanControlParams kGFSC100FanCtrlHddDefaults;

  static const FanControlParams kGFHD100FanCtrlSocDefaults;
  static const FanControlParams kGFHD200FanCtrlSocDefaults;

  static const FanControlParams kGFHD254FanCtrlSocDefaults;
  static const FanControlParams kGFHD254FanCtrlAux1Defaults;

  static const FanControlParams kGFLT110FanCtrlSocDefaults;
  static const FanControlParams kGFLT300FanCtrlSocDefaults;
  static const FanControlParams kGFLT400FanCtrlSocDefaults;

  static const FanControlParams kGFCH100FanCtrlSocDefaults;

  explicit FanControl(Platform *platform)
      : state_(OFF),
        auto_mode_(true),
        duty_cycle_pwm_(kPwmMinValue),
        duty_cycle_startup_(kPwmDefaultStartup),
        period_(DUTY_CYCLE_PWM_MAX_VALUE-1),
        pfan_ctrl_params_(NULL),
        platform_(platform) {}

  virtual ~FanControl();

  bool Init(bool *gpio_mailbox_ready);
  void Terminate(void);
  bool DrivePwm(uint16_t duty_cycle);
  bool AdjustSpeed(uint16_t soc_temp, uint16_t hdd_temp, uint16_t aux1_temp,
                   uint16_t fan_speed);
  void GetHddTemperature(uint16_t *phdd_temp);
  void GetOverheatTemperature(uint16_t *poverheat_temp);

 private:

  void InitParams(void);
  std::string ExecCmd(char* cmd, std::string *pattern);
  uint16_t __ComputeDutyCycle(uint16_t temp, uint16_t fan_speed,
                  const FanControlParams &params);
  void ComputeDutyCycle(uint16_t soc_temp, uint16_t hdd_temp, uint16_t aux1_temp,
                        uint16_t fan_speed, uint16_t *new_duty_cycle_pwm);

  void dbgUpdateFanControlParams(void);
  bool dbgGetFanControlParamsFromParamsFile(uint8_t fc_idx);

  StateType state_;
  bool auto_mode_;
  uint16_t duty_cycle_pwm_;     /* current pwm duty cycle */
  uint16_t duty_cycle_startup_; /* initial duty cycle */
  /*
   * Period = period_ + 1 where period_ is the register value in chip.
   * (I have no idea why BRCM need it to be one short...), in this class, the
   * period_ value is the value you will set in register. But the real Period is
   * period_+1 mathmatically.
   * To bump up the CPU with full duty cycle, the On register needs to be set as
   * Period a.k.a period_+1.
   */
  uint16_t period_;

  /* Fan control parameters table
   * idx BRUNO_SOC: depending upon GFMS100 (Bruno-IS) or GFHD100 (Thin Bruno);
   * idx BRUNO_IS_HDD: use by HDD GFMS100
   * */
  FanControlParams *pfan_ctrl_params_;
  Platform *platform_;

  FanControlParams *get_hdd_fan_ctrl_parms();
  FanControlParams *get_aux1_fan_ctrl_parms();

  DISALLOW_COPY_AND_ASSIGN(FanControl);
};

}  // namespace bruno_platform_peripheral

#endif // BRUNO_PLATFORM_PERIPHERAL_FANCONTROL_H_
