Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (c) 2016 Google, Inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/hwmon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/hwmon-sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/reset.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/thermal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) /* ASPEED PWM & FAN Tach Register Definition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define ASPEED_PTCR_CTRL		0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define ASPEED_PTCR_CLK_CTRL		0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define ASPEED_PTCR_DUTY0_CTRL		0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define ASPEED_PTCR_DUTY1_CTRL		0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define ASPEED_PTCR_TYPEM_CTRL		0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define ASPEED_PTCR_TYPEM_CTRL1		0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define ASPEED_PTCR_TYPEN_CTRL		0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define ASPEED_PTCR_TYPEN_CTRL1		0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define ASPEED_PTCR_TACH_SOURCE		0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define ASPEED_PTCR_TRIGGER		0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define ASPEED_PTCR_RESULT		0x2c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define ASPEED_PTCR_INTR_CTRL		0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define ASPEED_PTCR_INTR_STS		0x34
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define ASPEED_PTCR_TYPEM_LIMIT		0x38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define ASPEED_PTCR_TYPEN_LIMIT		0x3C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define ASPEED_PTCR_CTRL_EXT		0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define ASPEED_PTCR_CLK_CTRL_EXT	0x44
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define ASPEED_PTCR_DUTY2_CTRL		0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #define ASPEED_PTCR_DUTY3_CTRL		0x4c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define ASPEED_PTCR_TYPEO_CTRL		0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define ASPEED_PTCR_TYPEO_CTRL1		0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define ASPEED_PTCR_TACH_SOURCE_EXT	0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define ASPEED_PTCR_TYPEO_LIMIT		0x78
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) /* ASPEED_PTCR_CTRL : 0x00 - General Control Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #define ASPEED_PTCR_CTRL_SET_PWMD_TYPE_PART1	15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define ASPEED_PTCR_CTRL_SET_PWMD_TYPE_PART2	6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define ASPEED_PTCR_CTRL_SET_PWMD_TYPE_MASK	(BIT(7) | BIT(15))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define ASPEED_PTCR_CTRL_SET_PWMC_TYPE_PART1	14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #define ASPEED_PTCR_CTRL_SET_PWMC_TYPE_PART2	5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define ASPEED_PTCR_CTRL_SET_PWMC_TYPE_MASK	(BIT(6) | BIT(14))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define ASPEED_PTCR_CTRL_SET_PWMB_TYPE_PART1	13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define ASPEED_PTCR_CTRL_SET_PWMB_TYPE_PART2	4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #define ASPEED_PTCR_CTRL_SET_PWMB_TYPE_MASK	(BIT(5) | BIT(13))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #define ASPEED_PTCR_CTRL_SET_PWMA_TYPE_PART1	12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #define ASPEED_PTCR_CTRL_SET_PWMA_TYPE_PART2	3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) #define ASPEED_PTCR_CTRL_SET_PWMA_TYPE_MASK	(BIT(4) | BIT(12))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) #define	ASPEED_PTCR_CTRL_FAN_NUM_EN(x)	BIT(16 + (x))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) #define	ASPEED_PTCR_CTRL_PWMD_EN	BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) #define	ASPEED_PTCR_CTRL_PWMC_EN	BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) #define	ASPEED_PTCR_CTRL_PWMB_EN	BIT(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) #define	ASPEED_PTCR_CTRL_PWMA_EN	BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) #define	ASPEED_PTCR_CTRL_CLK_SRC	BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) #define	ASPEED_PTCR_CTRL_CLK_EN		BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) /* ASPEED_PTCR_CLK_CTRL : 0x04 - Clock Control Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) /* TYPE N */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) #define ASPEED_PTCR_CLK_CTRL_TYPEN_MASK		GENMASK(31, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) #define ASPEED_PTCR_CLK_CTRL_TYPEN_UNIT		24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) #define ASPEED_PTCR_CLK_CTRL_TYPEN_H		20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) #define ASPEED_PTCR_CLK_CTRL_TYPEN_L		16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) /* TYPE M */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) #define ASPEED_PTCR_CLK_CTRL_TYPEM_MASK         GENMASK(15, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) #define ASPEED_PTCR_CLK_CTRL_TYPEM_UNIT		8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) #define ASPEED_PTCR_CLK_CTRL_TYPEM_H		4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) #define ASPEED_PTCR_CLK_CTRL_TYPEM_L		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)  * ASPEED_PTCR_DUTY_CTRL/1/2/3 : 0x08/0x0C/0x48/0x4C - PWM-FAN duty control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)  * 0/1/2/3 register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) #define DUTY_CTRL_PWM2_FALL_POINT	24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) #define DUTY_CTRL_PWM2_RISE_POINT	16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) #define DUTY_CTRL_PWM2_RISE_FALL_MASK	GENMASK(31, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) #define DUTY_CTRL_PWM1_FALL_POINT	8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) #define DUTY_CTRL_PWM1_RISE_POINT	0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) #define DUTY_CTRL_PWM1_RISE_FALL_MASK   GENMASK(15, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) /* ASPEED_PTCR_TYPEM_CTRL : 0x10/0x18/0x50 - Type M/N/O Ctrl 0 Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) #define TYPE_CTRL_FAN_MASK		(GENMASK(5, 1) | GENMASK(31, 16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define TYPE_CTRL_FAN1_MASK		GENMASK(31, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define TYPE_CTRL_FAN_PERIOD		16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define TYPE_CTRL_FAN_MODE		4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define TYPE_CTRL_FAN_DIVISION		1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define TYPE_CTRL_FAN_TYPE_EN		1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* ASPEED_PTCR_TACH_SOURCE : 0x20/0x60 - Tach Source Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /* bit [0,1] at 0x20, bit [2] at 0x60 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define TACH_PWM_SOURCE_BIT01(x)	((x) * 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define TACH_PWM_SOURCE_BIT2(x)		((x) * 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define TACH_PWM_SOURCE_MASK_BIT01(x)	(0x3 << ((x) * 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define TACH_PWM_SOURCE_MASK_BIT2(x)	BIT((x) * 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /* ASPEED_PTCR_RESULT : 0x2c - Result Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define RESULT_STATUS_MASK		BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define RESULT_VALUE_MASK		0xfffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /* ASPEED_PTCR_CTRL_EXT : 0x40 - General Control Extension #1 Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define ASPEED_PTCR_CTRL_SET_PWMH_TYPE_PART1	15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define ASPEED_PTCR_CTRL_SET_PWMH_TYPE_PART2	6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define ASPEED_PTCR_CTRL_SET_PWMH_TYPE_MASK	(BIT(7) | BIT(15))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define ASPEED_PTCR_CTRL_SET_PWMG_TYPE_PART1	14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define ASPEED_PTCR_CTRL_SET_PWMG_TYPE_PART2	5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define ASPEED_PTCR_CTRL_SET_PWMG_TYPE_MASK	(BIT(6) | BIT(14))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define ASPEED_PTCR_CTRL_SET_PWMF_TYPE_PART1	13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define ASPEED_PTCR_CTRL_SET_PWMF_TYPE_PART2	4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define ASPEED_PTCR_CTRL_SET_PWMF_TYPE_MASK	(BIT(5) | BIT(13))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define ASPEED_PTCR_CTRL_SET_PWME_TYPE_PART1	12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define ASPEED_PTCR_CTRL_SET_PWME_TYPE_PART2	3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define ASPEED_PTCR_CTRL_SET_PWME_TYPE_MASK	(BIT(4) | BIT(12))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define	ASPEED_PTCR_CTRL_PWMH_EN	BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define	ASPEED_PTCR_CTRL_PWMG_EN	BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define	ASPEED_PTCR_CTRL_PWMF_EN	BIT(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define	ASPEED_PTCR_CTRL_PWME_EN	BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /* ASPEED_PTCR_CLK_EXT_CTRL : 0x44 - Clock Control Extension #1 Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /* TYPE O */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define ASPEED_PTCR_CLK_CTRL_TYPEO_MASK         GENMASK(15, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define ASPEED_PTCR_CLK_CTRL_TYPEO_UNIT		8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define ASPEED_PTCR_CLK_CTRL_TYPEO_H		4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define ASPEED_PTCR_CLK_CTRL_TYPEO_L		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define PWM_MAX 255
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define BOTH_EDGES 0x02 /* 10b */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define M_PWM_DIV_H 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define M_PWM_DIV_L 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define M_PWM_PERIOD 0x5F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define M_TACH_CLK_DIV 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)  * 5:4 Type N fan tach mode selection bit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)  * 00: falling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)  * 01: rising
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)  * 10: both
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)  * 11: reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define M_TACH_MODE 0x02 /* 10b */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define M_TACH_UNIT 0x0210
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define INIT_FAN_CTRL 0xFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /* How long we sleep in us while waiting for an RPM result. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #define ASPEED_RPM_STATUS_SLEEP_USEC	500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define MAX_CDEV_NAME_LEN 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct aspeed_cooling_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	char name[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	struct aspeed_pwm_tacho_data *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	struct thermal_cooling_device *tcdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	int pwm_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	u8 *cooling_levels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	u8 max_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	u8 cur_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct aspeed_pwm_tacho_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	struct reset_control *rst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	unsigned long clk_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	bool pwm_present[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	bool fan_tach_present[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	u8 type_pwm_clock_unit[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	u8 type_pwm_clock_division_h[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	u8 type_pwm_clock_division_l[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	u8 type_fan_tach_clock_division[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	u8 type_fan_tach_mode[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	u16 type_fan_tach_unit[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	u8 pwm_port_type[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	u8 pwm_port_fan_ctrl[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	u8 fan_tach_ch_source[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	struct aspeed_cooling_device *cdev[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	const struct attribute_group *groups[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) enum type { TYPEM, TYPEN, TYPEO };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct type_params {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	u32 l_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	u32 h_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	u32 unit_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	u32 clk_ctrl_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	u32 clk_ctrl_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	u32 ctrl_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	u32 ctrl_reg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static const struct type_params type_params[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	[TYPEM] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		.l_value = ASPEED_PTCR_CLK_CTRL_TYPEM_L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		.h_value = ASPEED_PTCR_CLK_CTRL_TYPEM_H,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		.unit_value = ASPEED_PTCR_CLK_CTRL_TYPEM_UNIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		.clk_ctrl_mask = ASPEED_PTCR_CLK_CTRL_TYPEM_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		.clk_ctrl_reg = ASPEED_PTCR_CLK_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		.ctrl_reg = ASPEED_PTCR_TYPEM_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		.ctrl_reg1 = ASPEED_PTCR_TYPEM_CTRL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	[TYPEN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		.l_value = ASPEED_PTCR_CLK_CTRL_TYPEN_L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		.h_value = ASPEED_PTCR_CLK_CTRL_TYPEN_H,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		.unit_value = ASPEED_PTCR_CLK_CTRL_TYPEN_UNIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		.clk_ctrl_mask = ASPEED_PTCR_CLK_CTRL_TYPEN_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		.clk_ctrl_reg = ASPEED_PTCR_CLK_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		.ctrl_reg = ASPEED_PTCR_TYPEN_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		.ctrl_reg1 = ASPEED_PTCR_TYPEN_CTRL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	[TYPEO] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		.l_value = ASPEED_PTCR_CLK_CTRL_TYPEO_L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		.h_value = ASPEED_PTCR_CLK_CTRL_TYPEO_H,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		.unit_value = ASPEED_PTCR_CLK_CTRL_TYPEO_UNIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		.clk_ctrl_mask = ASPEED_PTCR_CLK_CTRL_TYPEO_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		.clk_ctrl_reg = ASPEED_PTCR_CLK_CTRL_EXT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		.ctrl_reg = ASPEED_PTCR_TYPEO_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		.ctrl_reg1 = ASPEED_PTCR_TYPEO_CTRL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) enum pwm_port { PWMA, PWMB, PWMC, PWMD, PWME, PWMF, PWMG, PWMH };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct pwm_port_params {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	u32 pwm_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	u32 ctrl_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	u32 type_part1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	u32 type_part2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	u32 type_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	u32 duty_ctrl_rise_point;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	u32 duty_ctrl_fall_point;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	u32 duty_ctrl_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	u32 duty_ctrl_rise_fall_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) static const struct pwm_port_params pwm_port_params[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	[PWMA] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		.pwm_en = ASPEED_PTCR_CTRL_PWMA_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		.ctrl_reg = ASPEED_PTCR_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		.type_part1 = ASPEED_PTCR_CTRL_SET_PWMA_TYPE_PART1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		.type_part2 = ASPEED_PTCR_CTRL_SET_PWMA_TYPE_PART2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		.type_mask = ASPEED_PTCR_CTRL_SET_PWMA_TYPE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		.duty_ctrl_rise_point = DUTY_CTRL_PWM1_RISE_POINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		.duty_ctrl_fall_point = DUTY_CTRL_PWM1_FALL_POINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		.duty_ctrl_reg = ASPEED_PTCR_DUTY0_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		.duty_ctrl_rise_fall_mask = DUTY_CTRL_PWM1_RISE_FALL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	[PWMB] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		.pwm_en = ASPEED_PTCR_CTRL_PWMB_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		.ctrl_reg = ASPEED_PTCR_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		.type_part1 = ASPEED_PTCR_CTRL_SET_PWMB_TYPE_PART1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		.type_part2 = ASPEED_PTCR_CTRL_SET_PWMB_TYPE_PART2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		.type_mask = ASPEED_PTCR_CTRL_SET_PWMB_TYPE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		.duty_ctrl_rise_point = DUTY_CTRL_PWM2_RISE_POINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		.duty_ctrl_fall_point = DUTY_CTRL_PWM2_FALL_POINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		.duty_ctrl_reg = ASPEED_PTCR_DUTY0_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		.duty_ctrl_rise_fall_mask = DUTY_CTRL_PWM2_RISE_FALL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	[PWMC] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		.pwm_en = ASPEED_PTCR_CTRL_PWMC_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		.ctrl_reg = ASPEED_PTCR_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		.type_part1 = ASPEED_PTCR_CTRL_SET_PWMC_TYPE_PART1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		.type_part2 = ASPEED_PTCR_CTRL_SET_PWMC_TYPE_PART2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		.type_mask = ASPEED_PTCR_CTRL_SET_PWMC_TYPE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		.duty_ctrl_rise_point = DUTY_CTRL_PWM1_RISE_POINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		.duty_ctrl_fall_point = DUTY_CTRL_PWM1_FALL_POINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		.duty_ctrl_reg = ASPEED_PTCR_DUTY1_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		.duty_ctrl_rise_fall_mask = DUTY_CTRL_PWM1_RISE_FALL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	[PWMD] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		.pwm_en = ASPEED_PTCR_CTRL_PWMD_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		.ctrl_reg = ASPEED_PTCR_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		.type_part1 = ASPEED_PTCR_CTRL_SET_PWMD_TYPE_PART1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		.type_part2 = ASPEED_PTCR_CTRL_SET_PWMD_TYPE_PART2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		.type_mask = ASPEED_PTCR_CTRL_SET_PWMD_TYPE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		.duty_ctrl_rise_point = DUTY_CTRL_PWM2_RISE_POINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		.duty_ctrl_fall_point = DUTY_CTRL_PWM2_FALL_POINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		.duty_ctrl_reg = ASPEED_PTCR_DUTY1_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		.duty_ctrl_rise_fall_mask = DUTY_CTRL_PWM2_RISE_FALL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	[PWME] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		.pwm_en = ASPEED_PTCR_CTRL_PWME_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		.ctrl_reg = ASPEED_PTCR_CTRL_EXT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		.type_part1 = ASPEED_PTCR_CTRL_SET_PWME_TYPE_PART1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		.type_part2 = ASPEED_PTCR_CTRL_SET_PWME_TYPE_PART2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		.type_mask = ASPEED_PTCR_CTRL_SET_PWME_TYPE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		.duty_ctrl_rise_point = DUTY_CTRL_PWM1_RISE_POINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		.duty_ctrl_fall_point = DUTY_CTRL_PWM1_FALL_POINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		.duty_ctrl_reg = ASPEED_PTCR_DUTY2_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 		.duty_ctrl_rise_fall_mask = DUTY_CTRL_PWM1_RISE_FALL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	[PWMF] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		.pwm_en = ASPEED_PTCR_CTRL_PWMF_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		.ctrl_reg = ASPEED_PTCR_CTRL_EXT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		.type_part1 = ASPEED_PTCR_CTRL_SET_PWMF_TYPE_PART1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		.type_part2 = ASPEED_PTCR_CTRL_SET_PWMF_TYPE_PART2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		.type_mask = ASPEED_PTCR_CTRL_SET_PWMF_TYPE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		.duty_ctrl_rise_point = DUTY_CTRL_PWM2_RISE_POINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		.duty_ctrl_fall_point = DUTY_CTRL_PWM2_FALL_POINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		.duty_ctrl_reg = ASPEED_PTCR_DUTY2_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		.duty_ctrl_rise_fall_mask = DUTY_CTRL_PWM2_RISE_FALL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	[PWMG] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		.pwm_en = ASPEED_PTCR_CTRL_PWMG_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		.ctrl_reg = ASPEED_PTCR_CTRL_EXT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		.type_part1 = ASPEED_PTCR_CTRL_SET_PWMG_TYPE_PART1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		.type_part2 = ASPEED_PTCR_CTRL_SET_PWMG_TYPE_PART2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		.type_mask = ASPEED_PTCR_CTRL_SET_PWMG_TYPE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 		.duty_ctrl_rise_point = DUTY_CTRL_PWM1_RISE_POINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		.duty_ctrl_fall_point = DUTY_CTRL_PWM1_FALL_POINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		.duty_ctrl_reg = ASPEED_PTCR_DUTY3_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		.duty_ctrl_rise_fall_mask = DUTY_CTRL_PWM1_RISE_FALL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	[PWMH] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		.pwm_en = ASPEED_PTCR_CTRL_PWMH_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		.ctrl_reg = ASPEED_PTCR_CTRL_EXT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		.type_part1 = ASPEED_PTCR_CTRL_SET_PWMH_TYPE_PART1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		.type_part2 = ASPEED_PTCR_CTRL_SET_PWMH_TYPE_PART2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		.type_mask = ASPEED_PTCR_CTRL_SET_PWMH_TYPE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		.duty_ctrl_rise_point = DUTY_CTRL_PWM2_RISE_POINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		.duty_ctrl_fall_point = DUTY_CTRL_PWM2_FALL_POINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		.duty_ctrl_reg = ASPEED_PTCR_DUTY3_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		.duty_ctrl_rise_fall_mask = DUTY_CTRL_PWM2_RISE_FALL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) static int regmap_aspeed_pwm_tacho_reg_write(void *context, unsigned int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 					     unsigned int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	void __iomem *regs = (void __iomem *)context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	writel(val, regs + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) static int regmap_aspeed_pwm_tacho_reg_read(void *context, unsigned int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 					    unsigned int *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	void __iomem *regs = (void __iomem *)context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	*val = readl(regs + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) static const struct regmap_config aspeed_pwm_tacho_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	.reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	.val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	.reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	.max_register = ASPEED_PTCR_TYPEO_LIMIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	.reg_write = regmap_aspeed_pwm_tacho_reg_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	.reg_read = regmap_aspeed_pwm_tacho_reg_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	.fast_io = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) static void aspeed_set_clock_enable(struct regmap *regmap, bool val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	regmap_update_bits(regmap, ASPEED_PTCR_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 			   ASPEED_PTCR_CTRL_CLK_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 			   val ? ASPEED_PTCR_CTRL_CLK_EN : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static void aspeed_set_clock_source(struct regmap *regmap, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	regmap_update_bits(regmap, ASPEED_PTCR_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 			   ASPEED_PTCR_CTRL_CLK_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 			   val ? ASPEED_PTCR_CTRL_CLK_SRC : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) static void aspeed_set_pwm_clock_values(struct regmap *regmap, u8 type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 					u8 div_high, u8 div_low, u8 unit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	u32 reg_value = ((div_high << type_params[type].h_value) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 			 (div_low << type_params[type].l_value) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 			 (unit << type_params[type].unit_value));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	regmap_update_bits(regmap, type_params[type].clk_ctrl_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 			   type_params[type].clk_ctrl_mask, reg_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static void aspeed_set_pwm_port_enable(struct regmap *regmap, u8 pwm_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 				       bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	regmap_update_bits(regmap, pwm_port_params[pwm_port].ctrl_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 			   pwm_port_params[pwm_port].pwm_en,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 			   enable ? pwm_port_params[pwm_port].pwm_en : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) static void aspeed_set_pwm_port_type(struct regmap *regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 				     u8 pwm_port, u8 type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	u32 reg_value = (type & 0x1) << pwm_port_params[pwm_port].type_part1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	reg_value |= (type & 0x2) << pwm_port_params[pwm_port].type_part2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	regmap_update_bits(regmap, pwm_port_params[pwm_port].ctrl_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 			   pwm_port_params[pwm_port].type_mask, reg_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) static void aspeed_set_pwm_port_duty_rising_falling(struct regmap *regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 						    u8 pwm_port, u8 rising,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 						    u8 falling)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	u32 reg_value = (rising <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 			 pwm_port_params[pwm_port].duty_ctrl_rise_point);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	reg_value |= (falling <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		      pwm_port_params[pwm_port].duty_ctrl_fall_point);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	regmap_update_bits(regmap, pwm_port_params[pwm_port].duty_ctrl_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 			   pwm_port_params[pwm_port].duty_ctrl_rise_fall_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 			   reg_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static void aspeed_set_tacho_type_enable(struct regmap *regmap, u8 type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 					 bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	regmap_update_bits(regmap, type_params[type].ctrl_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 			   TYPE_CTRL_FAN_TYPE_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 			   enable ? TYPE_CTRL_FAN_TYPE_EN : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) static void aspeed_set_tacho_type_values(struct regmap *regmap, u8 type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 					 u8 mode, u16 unit, u8 division)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	u32 reg_value = ((mode << TYPE_CTRL_FAN_MODE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 			 (unit << TYPE_CTRL_FAN_PERIOD) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 			 (division << TYPE_CTRL_FAN_DIVISION));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	regmap_update_bits(regmap, type_params[type].ctrl_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 			   TYPE_CTRL_FAN_MASK, reg_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	regmap_update_bits(regmap, type_params[type].ctrl_reg1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 			   TYPE_CTRL_FAN1_MASK, unit << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) static void aspeed_set_fan_tach_ch_enable(struct regmap *regmap, u8 fan_tach_ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 					  bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	regmap_update_bits(regmap, ASPEED_PTCR_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 			   ASPEED_PTCR_CTRL_FAN_NUM_EN(fan_tach_ch),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 			   enable ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 			   ASPEED_PTCR_CTRL_FAN_NUM_EN(fan_tach_ch) : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static void aspeed_set_fan_tach_ch_source(struct regmap *regmap, u8 fan_tach_ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 					  u8 fan_tach_ch_source)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	u32 reg_value1 = ((fan_tach_ch_source & 0x3) <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 			  TACH_PWM_SOURCE_BIT01(fan_tach_ch));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	u32 reg_value2 = (((fan_tach_ch_source & 0x4) >> 2) <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 			  TACH_PWM_SOURCE_BIT2(fan_tach_ch));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	regmap_update_bits(regmap, ASPEED_PTCR_TACH_SOURCE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 			   TACH_PWM_SOURCE_MASK_BIT01(fan_tach_ch),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 			   reg_value1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	regmap_update_bits(regmap, ASPEED_PTCR_TACH_SOURCE_EXT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 			   TACH_PWM_SOURCE_MASK_BIT2(fan_tach_ch),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 			   reg_value2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) static void aspeed_set_pwm_port_fan_ctrl(struct aspeed_pwm_tacho_data *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 					 u8 index, u8 fan_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	u16 period, dc_time_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	period = priv->type_pwm_clock_unit[priv->pwm_port_type[index]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	period += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	dc_time_on = (fan_ctrl * period) / PWM_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	if (dc_time_on == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 		aspeed_set_pwm_port_enable(priv->regmap, index, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 		if (dc_time_on == period)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 			dc_time_on = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		aspeed_set_pwm_port_duty_rising_falling(priv->regmap, index, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 							dc_time_on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 		aspeed_set_pwm_port_enable(priv->regmap, index, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) static u32 aspeed_get_fan_tach_ch_measure_period(struct aspeed_pwm_tacho_data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 						 *priv, u8 type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	u32 clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	u16 tacho_unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	u8 clk_unit, div_h, div_l, tacho_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	clk = priv->clk_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	clk_unit = priv->type_pwm_clock_unit[type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	div_h = priv->type_pwm_clock_division_h[type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	div_h = 0x1 << div_h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	div_l = priv->type_pwm_clock_division_l[type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	if (div_l == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 		div_l = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		div_l = div_l * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	tacho_unit = priv->type_fan_tach_unit[type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	tacho_div = priv->type_fan_tach_clock_division[type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	tacho_div = 0x4 << (tacho_div * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	return clk / (clk_unit * div_h * div_l * tacho_div * tacho_unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) static int aspeed_get_fan_tach_ch_rpm(struct aspeed_pwm_tacho_data *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 				      u8 fan_tach_ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	u32 raw_data, tach_div, clk_source, msec, usec, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	u8 fan_tach_ch_source, type, mode, both;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	regmap_write(priv->regmap, ASPEED_PTCR_TRIGGER, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	regmap_write(priv->regmap, ASPEED_PTCR_TRIGGER, 0x1 << fan_tach_ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	fan_tach_ch_source = priv->fan_tach_ch_source[fan_tach_ch];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	type = priv->pwm_port_type[fan_tach_ch_source];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	msec = (1000 / aspeed_get_fan_tach_ch_measure_period(priv, type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	usec = msec * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	ret = regmap_read_poll_timeout(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 		priv->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 		ASPEED_PTCR_RESULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 		val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		(val & RESULT_STATUS_MASK),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		ASPEED_RPM_STATUS_SLEEP_USEC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 		usec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	/* return -ETIMEDOUT if we didn't get an answer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	raw_data = val & RESULT_VALUE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	tach_div = priv->type_fan_tach_clock_division[type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	 * We need the mode to determine if the raw_data is double (from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	 * counting both edges).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	mode = priv->type_fan_tach_mode[type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	both = (mode & BOTH_EDGES) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	tach_div = (0x4 << both) << (tach_div * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	clk_source = priv->clk_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	if (raw_data == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	return (clk_source * 60) / (2 * raw_data * tach_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) static ssize_t pwm_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 			 const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	int index = sensor_attr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	struct aspeed_pwm_tacho_data *priv = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	long fan_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	ret = kstrtol(buf, 10, &fan_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	if (fan_ctrl < 0 || fan_ctrl > PWM_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	if (priv->pwm_port_fan_ctrl[index] == fan_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 		return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	priv->pwm_port_fan_ctrl[index] = fan_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	aspeed_set_pwm_port_fan_ctrl(priv, index, fan_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) static ssize_t pwm_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 			char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	int index = sensor_attr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	struct aspeed_pwm_tacho_data *priv = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	return sprintf(buf, "%u\n", priv->pwm_port_fan_ctrl[index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) static ssize_t rpm_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 			char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	int index = sensor_attr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	int rpm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	struct aspeed_pwm_tacho_data *priv = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	rpm = aspeed_get_fan_tach_ch_rpm(priv, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	if (rpm < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 		return rpm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	return sprintf(buf, "%d\n", rpm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) static umode_t pwm_is_visible(struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 			      struct attribute *a, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	struct device *dev = container_of(kobj, struct device, kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	struct aspeed_pwm_tacho_data *priv = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	if (!priv->pwm_present[index])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	return a->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) static umode_t fan_dev_is_visible(struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 				  struct attribute *a, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	struct device *dev = container_of(kobj, struct device, kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	struct aspeed_pwm_tacho_data *priv = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	if (!priv->fan_tach_present[index])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	return a->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) static SENSOR_DEVICE_ATTR_RW(pwm1, pwm, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) static SENSOR_DEVICE_ATTR_RW(pwm2, pwm, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) static SENSOR_DEVICE_ATTR_RW(pwm3, pwm, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) static SENSOR_DEVICE_ATTR_RW(pwm4, pwm, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) static SENSOR_DEVICE_ATTR_RW(pwm5, pwm, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) static SENSOR_DEVICE_ATTR_RW(pwm6, pwm, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) static SENSOR_DEVICE_ATTR_RW(pwm7, pwm, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) static SENSOR_DEVICE_ATTR_RW(pwm8, pwm, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) static struct attribute *pwm_dev_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	&sensor_dev_attr_pwm1.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	&sensor_dev_attr_pwm2.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	&sensor_dev_attr_pwm3.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 	&sensor_dev_attr_pwm4.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	&sensor_dev_attr_pwm5.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	&sensor_dev_attr_pwm6.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 	&sensor_dev_attr_pwm7.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	&sensor_dev_attr_pwm8.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) static const struct attribute_group pwm_dev_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	.attrs = pwm_dev_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 	.is_visible = pwm_is_visible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) static SENSOR_DEVICE_ATTR_RO(fan1_input, rpm, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) static SENSOR_DEVICE_ATTR_RO(fan2_input, rpm, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) static SENSOR_DEVICE_ATTR_RO(fan3_input, rpm, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) static SENSOR_DEVICE_ATTR_RO(fan4_input, rpm, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) static SENSOR_DEVICE_ATTR_RO(fan5_input, rpm, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) static SENSOR_DEVICE_ATTR_RO(fan6_input, rpm, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) static SENSOR_DEVICE_ATTR_RO(fan7_input, rpm, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) static SENSOR_DEVICE_ATTR_RO(fan8_input, rpm, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) static SENSOR_DEVICE_ATTR_RO(fan9_input, rpm, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) static SENSOR_DEVICE_ATTR_RO(fan10_input, rpm, 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) static SENSOR_DEVICE_ATTR_RO(fan11_input, rpm, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) static SENSOR_DEVICE_ATTR_RO(fan12_input, rpm, 11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) static SENSOR_DEVICE_ATTR_RO(fan13_input, rpm, 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) static SENSOR_DEVICE_ATTR_RO(fan14_input, rpm, 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) static SENSOR_DEVICE_ATTR_RO(fan15_input, rpm, 14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) static SENSOR_DEVICE_ATTR_RO(fan16_input, rpm, 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) static struct attribute *fan_dev_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	&sensor_dev_attr_fan1_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 	&sensor_dev_attr_fan2_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 	&sensor_dev_attr_fan3_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 	&sensor_dev_attr_fan4_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 	&sensor_dev_attr_fan5_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	&sensor_dev_attr_fan6_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	&sensor_dev_attr_fan7_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 	&sensor_dev_attr_fan8_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 	&sensor_dev_attr_fan9_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	&sensor_dev_attr_fan10_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 	&sensor_dev_attr_fan11_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	&sensor_dev_attr_fan12_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	&sensor_dev_attr_fan13_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	&sensor_dev_attr_fan14_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	&sensor_dev_attr_fan15_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 	&sensor_dev_attr_fan16_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) static const struct attribute_group fan_dev_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	.attrs = fan_dev_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	.is_visible = fan_dev_is_visible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)  * The clock type is type M :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)  * The PWM frequency = 24MHz / (type M clock division L bit *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)  * type M clock division H bit * (type M PWM period bit + 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) static void aspeed_create_type(struct aspeed_pwm_tacho_data *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 	priv->type_pwm_clock_division_h[TYPEM] = M_PWM_DIV_H;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 	priv->type_pwm_clock_division_l[TYPEM] = M_PWM_DIV_L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	priv->type_pwm_clock_unit[TYPEM] = M_PWM_PERIOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 	aspeed_set_pwm_clock_values(priv->regmap, TYPEM, M_PWM_DIV_H,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 				    M_PWM_DIV_L, M_PWM_PERIOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	aspeed_set_tacho_type_enable(priv->regmap, TYPEM, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	priv->type_fan_tach_clock_division[TYPEM] = M_TACH_CLK_DIV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 	priv->type_fan_tach_unit[TYPEM] = M_TACH_UNIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 	priv->type_fan_tach_mode[TYPEM] = M_TACH_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	aspeed_set_tacho_type_values(priv->regmap, TYPEM, M_TACH_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 				     M_TACH_UNIT, M_TACH_CLK_DIV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) static void aspeed_create_pwm_port(struct aspeed_pwm_tacho_data *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 				   u8 pwm_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	aspeed_set_pwm_port_enable(priv->regmap, pwm_port, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 	priv->pwm_present[pwm_port] = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	priv->pwm_port_type[pwm_port] = TYPEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	aspeed_set_pwm_port_type(priv->regmap, pwm_port, TYPEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	priv->pwm_port_fan_ctrl[pwm_port] = INIT_FAN_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 	aspeed_set_pwm_port_fan_ctrl(priv, pwm_port, INIT_FAN_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) static void aspeed_create_fan_tach_channel(struct aspeed_pwm_tacho_data *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 					   u8 *fan_tach_ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 					   int count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 					   u8 pwm_source)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 	u8 val, index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 	for (val = 0; val < count; val++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 		index = fan_tach_ch[val];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 		aspeed_set_fan_tach_ch_enable(priv->regmap, index, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 		priv->fan_tach_present[index] = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 		priv->fan_tach_ch_source[index] = pwm_source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 		aspeed_set_fan_tach_ch_source(priv->regmap, index, pwm_source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) aspeed_pwm_cz_get_max_state(struct thermal_cooling_device *tcdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 			    unsigned long *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 	struct aspeed_cooling_device *cdev = tcdev->devdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 	*state = cdev->max_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) aspeed_pwm_cz_get_cur_state(struct thermal_cooling_device *tcdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 			    unsigned long *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 	struct aspeed_cooling_device *cdev = tcdev->devdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 	*state = cdev->cur_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) aspeed_pwm_cz_set_cur_state(struct thermal_cooling_device *tcdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 			    unsigned long state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 	struct aspeed_cooling_device *cdev = tcdev->devdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 	if (state > cdev->max_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 	cdev->cur_state = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 	cdev->priv->pwm_port_fan_ctrl[cdev->pwm_port] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 					cdev->cooling_levels[cdev->cur_state];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 	aspeed_set_pwm_port_fan_ctrl(cdev->priv, cdev->pwm_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 				     cdev->cooling_levels[cdev->cur_state]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) static const struct thermal_cooling_device_ops aspeed_pwm_cool_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 	.get_max_state = aspeed_pwm_cz_get_max_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 	.get_cur_state = aspeed_pwm_cz_get_cur_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 	.set_cur_state = aspeed_pwm_cz_set_cur_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) static int aspeed_create_pwm_cooling(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 				     struct device_node *child,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 				     struct aspeed_pwm_tacho_data *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 				     u32 pwm_port, u8 num_levels)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 	struct aspeed_cooling_device *cdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 	cdev = devm_kzalloc(dev, sizeof(*cdev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 	if (!cdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 	cdev->cooling_levels = devm_kzalloc(dev, num_levels, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 	if (!cdev->cooling_levels)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 	cdev->max_state = num_levels - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 	ret = of_property_read_u8_array(child, "cooling-levels",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 					cdev->cooling_levels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 					num_levels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 		dev_err(dev, "Property 'cooling-levels' cannot be read.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 	snprintf(cdev->name, MAX_CDEV_NAME_LEN, "%pOFn%d", child, pwm_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 	cdev->tcdev = devm_thermal_of_cooling_device_register(dev, child,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 					cdev->name, cdev, &aspeed_pwm_cool_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 	if (IS_ERR(cdev->tcdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 		return PTR_ERR(cdev->tcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 	cdev->priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 	cdev->pwm_port = pwm_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 	priv->cdev[pwm_port] = cdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) static int aspeed_create_fan(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 			     struct device_node *child,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 			     struct aspeed_pwm_tacho_data *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 	u8 *fan_tach_ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 	u32 pwm_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 	int ret, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) 	ret = of_property_read_u32(child, "reg", &pwm_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) 	if (pwm_port >= ARRAY_SIZE(pwm_port_params))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) 	aspeed_create_pwm_port(priv, (u8)pwm_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 	ret = of_property_count_u8_elems(child, "cooling-levels");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 	if (ret > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 		ret = aspeed_create_pwm_cooling(dev, child, priv, pwm_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 						ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) 	count = of_property_count_u8_elems(child, "aspeed,fan-tach-ch");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) 	if (count < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) 	fan_tach_ch = devm_kcalloc(dev, count, sizeof(*fan_tach_ch),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) 				   GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) 	if (!fan_tach_ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) 	ret = of_property_read_u8_array(child, "aspeed,fan-tach-ch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) 					fan_tach_ch, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) 	aspeed_create_fan_tach_channel(priv, fan_tach_ch, count, pwm_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) static void aspeed_pwm_tacho_remove(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) 	struct aspeed_pwm_tacho_data *priv = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) 	reset_control_assert(priv->rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) static int aspeed_pwm_tacho_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) 	struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) 	struct device_node *np, *child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) 	struct aspeed_pwm_tacho_data *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) 	void __iomem *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) 	struct device *hwmon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) 	struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) 	np = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) 	regs = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) 	if (IS_ERR(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) 		return PTR_ERR(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) 	if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) 	priv->regmap = devm_regmap_init(dev, NULL, (__force void *)regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) 			&aspeed_pwm_tacho_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) 	if (IS_ERR(priv->regmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) 		return PTR_ERR(priv->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) 	priv->rst = devm_reset_control_get_exclusive(dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) 	if (IS_ERR(priv->rst)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) 		dev_err(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) 			"missing or invalid reset controller device tree entry");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) 		return PTR_ERR(priv->rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) 	reset_control_deassert(priv->rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) 	ret = devm_add_action_or_reset(dev, aspeed_pwm_tacho_remove, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) 	regmap_write(priv->regmap, ASPEED_PTCR_TACH_SOURCE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) 	regmap_write(priv->regmap, ASPEED_PTCR_TACH_SOURCE_EXT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) 	clk = devm_clk_get(dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) 	if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) 	priv->clk_freq = clk_get_rate(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) 	aspeed_set_clock_enable(priv->regmap, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) 	aspeed_set_clock_source(priv->regmap, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) 	aspeed_create_type(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) 	for_each_child_of_node(np, child) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) 		ret = aspeed_create_fan(dev, child, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) 			of_node_put(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) 	priv->groups[0] = &pwm_dev_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) 	priv->groups[1] = &fan_dev_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) 	priv->groups[2] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) 	hwmon = devm_hwmon_device_register_with_groups(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) 						       "aspeed_pwm_tacho",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) 						       priv, priv->groups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) 	return PTR_ERR_OR_ZERO(hwmon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) static const struct of_device_id of_pwm_tacho_match_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) 	{ .compatible = "aspeed,ast2400-pwm-tacho", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) 	{ .compatible = "aspeed,ast2500-pwm-tacho", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) 	{},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) MODULE_DEVICE_TABLE(of, of_pwm_tacho_match_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) static struct platform_driver aspeed_pwm_tacho_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) 	.probe		= aspeed_pwm_tacho_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) 	.driver		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) 		.name	= "aspeed_pwm_tacho",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) 		.of_match_table = of_pwm_tacho_match_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) module_platform_driver(aspeed_pwm_tacho_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) MODULE_AUTHOR("Jaghathiswari Rankappagounder Natarajan <jaghu@google.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) MODULE_DESCRIPTION("ASPEED PWM and Fan Tacho device driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) MODULE_LICENSE("GPL");