aspeed-pwm-tacho.c (95c4629d92d15d10e5f7c55bfb72583f96a91374) | aspeed-pwm-tacho.c (1e276292bf25d288b645d3026f6c026ac9347061) |
---|---|
1/* 2 * Copyright (c) 2016 Google, Inc 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 or later as 6 * published by the Free Software Foundation. 7 */ 8 --- 132 unchanged lines hidden (view full) --- 141/* TYPE O */ 142#define ASPEED_PTCR_CLK_CTRL_TYPEO_MASK GENMASK(15, 0) 143#define ASPEED_PTCR_CLK_CTRL_TYPEO_UNIT 8 144#define ASPEED_PTCR_CLK_CTRL_TYPEO_H 4 145#define ASPEED_PTCR_CLK_CTRL_TYPEO_L 0 146 147#define PWM_MAX 255 148 | 1/* 2 * Copyright (c) 2016 Google, Inc 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 or later as 6 * published by the Free Software Foundation. 7 */ 8 --- 132 unchanged lines hidden (view full) --- 141/* TYPE O */ 142#define ASPEED_PTCR_CLK_CTRL_TYPEO_MASK GENMASK(15, 0) 143#define ASPEED_PTCR_CLK_CTRL_TYPEO_UNIT 8 144#define ASPEED_PTCR_CLK_CTRL_TYPEO_H 4 145#define ASPEED_PTCR_CLK_CTRL_TYPEO_L 0 146 147#define PWM_MAX 255 148 |
149#define BOTH_EDGES 0x02 /* 10b */ 150 |
|
149#define M_PWM_DIV_H 0x00 150#define M_PWM_DIV_L 0x05 151#define M_PWM_PERIOD 0x5F 152#define M_TACH_CLK_DIV 0x00 | 151#define M_PWM_DIV_H 0x00 152#define M_PWM_DIV_L 0x05 153#define M_PWM_PERIOD 0x5F 154#define M_TACH_CLK_DIV 0x00 |
153#define M_TACH_MODE 0x00 | 155/* 156 * 5:4 Type N fan tach mode selection bit: 157 * 00: falling 158 * 01: rising 159 * 10: both 160 * 11: reserved. 161 */ 162#define M_TACH_MODE 0x02 /* 10b */ |
154#define M_TACH_UNIT 0x1000 155#define INIT_FAN_CTRL 0xFF 156 157struct aspeed_pwm_tacho_data { 158 struct regmap *regmap; 159 unsigned long clk_freq; 160 bool pwm_present[8]; 161 bool fan_tach_present[16]; 162 u8 type_pwm_clock_unit[3]; 163 u8 type_pwm_clock_division_h[3]; 164 u8 type_pwm_clock_division_l[3]; 165 u8 type_fan_tach_clock_division[3]; | 163#define M_TACH_UNIT 0x1000 164#define INIT_FAN_CTRL 0xFF 165 166struct aspeed_pwm_tacho_data { 167 struct regmap *regmap; 168 unsigned long clk_freq; 169 bool pwm_present[8]; 170 bool fan_tach_present[16]; 171 u8 type_pwm_clock_unit[3]; 172 u8 type_pwm_clock_division_h[3]; 173 u8 type_pwm_clock_division_l[3]; 174 u8 type_fan_tach_clock_division[3]; |
175 u8 type_fan_tach_mode[3]; |
|
166 u16 type_fan_tach_unit[3]; 167 u8 pwm_port_type[8]; 168 u8 pwm_port_fan_ctrl[8]; 169 u8 fan_tach_ch_source[16]; 170 const struct attribute_group *groups[3]; 171}; 172 173enum type { TYPEM, TYPEN, TYPEO }; --- 320 unchanged lines hidden (view full) --- 494 tacho_div = 0x4 << (tacho_div * 2); 495 return clk / (clk_unit * div_h * div_l * tacho_div * tacho_unit); 496} 497 498static int aspeed_get_fan_tach_ch_rpm(struct aspeed_pwm_tacho_data *priv, 499 u8 fan_tach_ch) 500{ 501 u32 raw_data, tach_div, clk_source, sec, val; | 176 u16 type_fan_tach_unit[3]; 177 u8 pwm_port_type[8]; 178 u8 pwm_port_fan_ctrl[8]; 179 u8 fan_tach_ch_source[16]; 180 const struct attribute_group *groups[3]; 181}; 182 183enum type { TYPEM, TYPEN, TYPEO }; --- 320 unchanged lines hidden (view full) --- 504 tacho_div = 0x4 << (tacho_div * 2); 505 return clk / (clk_unit * div_h * div_l * tacho_div * tacho_unit); 506} 507 508static int aspeed_get_fan_tach_ch_rpm(struct aspeed_pwm_tacho_data *priv, 509 u8 fan_tach_ch) 510{ 511 u32 raw_data, tach_div, clk_source, sec, val; |
502 u8 fan_tach_ch_source, type; | 512 u8 fan_tach_ch_source, type, mode, both; |
503 504 regmap_write(priv->regmap, ASPEED_PTCR_TRIGGER, 0); 505 regmap_write(priv->regmap, ASPEED_PTCR_TRIGGER, 0x1 << fan_tach_ch); 506 507 fan_tach_ch_source = priv->fan_tach_ch_source[fan_tach_ch]; 508 type = priv->pwm_port_type[fan_tach_ch_source]; 509 510 sec = (1000 / aspeed_get_fan_tach_ch_measure_period(priv, type)); 511 msleep(sec); 512 513 regmap_read(priv->regmap, ASPEED_PTCR_RESULT, &val); 514 if (!(val & RESULT_STATUS_MASK)) 515 return -ETIMEDOUT; 516 517 raw_data = val & RESULT_VALUE_MASK; 518 tach_div = priv->type_fan_tach_clock_division[type]; | 513 514 regmap_write(priv->regmap, ASPEED_PTCR_TRIGGER, 0); 515 regmap_write(priv->regmap, ASPEED_PTCR_TRIGGER, 0x1 << fan_tach_ch); 516 517 fan_tach_ch_source = priv->fan_tach_ch_source[fan_tach_ch]; 518 type = priv->pwm_port_type[fan_tach_ch_source]; 519 520 sec = (1000 / aspeed_get_fan_tach_ch_measure_period(priv, type)); 521 msleep(sec); 522 523 regmap_read(priv->regmap, ASPEED_PTCR_RESULT, &val); 524 if (!(val & RESULT_STATUS_MASK)) 525 return -ETIMEDOUT; 526 527 raw_data = val & RESULT_VALUE_MASK; 528 tach_div = priv->type_fan_tach_clock_division[type]; |
519 tach_div = 0x4 << (tach_div * 2); | 529 /* 530 * We need the mode to determine if the raw_data is double (from 531 * counting both edges). 532 */ 533 mode = priv->type_fan_tach_mode[type]; 534 both = (mode & BOTH_EDGES) ? 1 : 0; 535 536 tach_div = (0x4 << both) << (tach_div * 2); |
520 clk_source = priv->clk_freq; 521 522 if (raw_data == 0) 523 return 0; 524 525 return (clk_source * 60) / (2 * raw_data * tach_div); 526} 527 --- 169 unchanged lines hidden (view full) --- 697 priv->type_pwm_clock_division_h[TYPEM] = M_PWM_DIV_H; 698 priv->type_pwm_clock_division_l[TYPEM] = M_PWM_DIV_L; 699 priv->type_pwm_clock_unit[TYPEM] = M_PWM_PERIOD; 700 aspeed_set_pwm_clock_values(priv->regmap, TYPEM, M_PWM_DIV_H, 701 M_PWM_DIV_L, M_PWM_PERIOD); 702 aspeed_set_tacho_type_enable(priv->regmap, TYPEM, true); 703 priv->type_fan_tach_clock_division[TYPEM] = M_TACH_CLK_DIV; 704 priv->type_fan_tach_unit[TYPEM] = M_TACH_UNIT; | 537 clk_source = priv->clk_freq; 538 539 if (raw_data == 0) 540 return 0; 541 542 return (clk_source * 60) / (2 * raw_data * tach_div); 543} 544 --- 169 unchanged lines hidden (view full) --- 714 priv->type_pwm_clock_division_h[TYPEM] = M_PWM_DIV_H; 715 priv->type_pwm_clock_division_l[TYPEM] = M_PWM_DIV_L; 716 priv->type_pwm_clock_unit[TYPEM] = M_PWM_PERIOD; 717 aspeed_set_pwm_clock_values(priv->regmap, TYPEM, M_PWM_DIV_H, 718 M_PWM_DIV_L, M_PWM_PERIOD); 719 aspeed_set_tacho_type_enable(priv->regmap, TYPEM, true); 720 priv->type_fan_tach_clock_division[TYPEM] = M_TACH_CLK_DIV; 721 priv->type_fan_tach_unit[TYPEM] = M_TACH_UNIT; |
722 priv->type_fan_tach_mode[TYPEM] = M_TACH_MODE; |
|
705 aspeed_set_tacho_type_values(priv->regmap, TYPEM, M_TACH_MODE, 706 M_TACH_UNIT, M_TACH_CLK_DIV); 707} 708 709static void aspeed_create_pwm_port(struct aspeed_pwm_tacho_data *priv, 710 u8 pwm_port) 711{ 712 aspeed_set_pwm_port_enable(priv->regmap, pwm_port, true); --- 128 unchanged lines hidden --- | 723 aspeed_set_tacho_type_values(priv->regmap, TYPEM, M_TACH_MODE, 724 M_TACH_UNIT, M_TACH_CLK_DIV); 725} 726 727static void aspeed_create_pwm_port(struct aspeed_pwm_tacho_data *priv, 728 u8 pwm_port) 729{ 730 aspeed_set_pwm_port_enable(priv->regmap, pwm_port, true); --- 128 unchanged lines hidden --- |