// 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_PARAMS_TYPES
  };

  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 kGFSC100FanCtrlSocDefaults;
  static const FanControlParams kGFSC100FanCtrlHddDefaults;

  static const FanControlParams kGFHD100FanCtrlSocDefaults;
  static const FanControlParams kGFHD200FanCtrlSocDefaults;
  static const FanControlParams kGFHD254FanCtrlSocDefaults;

  static const FanControlParams kGFLT110FanCtrlSocDefaults;

  explicit FanControl(Platform *platform)
      : state_(OFF),
        auto_mode_(true),
        duty_cycle_pwm_(kPwmMinValue),
        duty_cycle_startup_(kPwmDefaultStartup),
        period_(DUTY_CYCLE_PWM_MAX_VALUE-1),
        platform_(BRUNO_GFHD100),
        pfan_ctrl_params_(NULL),
        allocatedPlatformInstanceLocal_(false),
        platformInstance_(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 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);
  void ComputeDutyCycle(uint16_t soc_temp, uint16_t hdd_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
   * */
  enum BrunoPlatformTypes platform_;
  FanControlParams *pfan_ctrl_params_;
  bool allocatedPlatformInstanceLocal_;
  Platform *platformInstance_;

  FanControlParams *get_hdd_fan_ctrl_parms();
  bool if_hdd_temp_over_temp_max(const uint16_t hdd_temp, const FanControlParams *phdd) const;
  bool if_hdd_temp_over_temp_setpt(const uint16_t hdd_temp, const FanControlParams *phdd) const;
  bool if_hdd_temp_lower_than_temp_setpt(const uint16_t hdd_temp, const FanControlParams *phdd) const;

  DISALLOW_COPY_AND_ASSIGN(FanControl);
};

}  // namespace bruno_platform_peripheral

#endif // BRUNO_PLATFORM_PERIPHERAL_FANCONTROL_H_
