summaryrefslogtreecommitdiff
path: root/drivers/hwmon/ast_pwm_fan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/ast_pwm_fan.c')
-rw-r--r--drivers/hwmon/ast_pwm_fan.c159
1 files changed, 127 insertions, 32 deletions
diff --git a/drivers/hwmon/ast_pwm_fan.c b/drivers/hwmon/ast_pwm_fan.c
index 02784c5b9e1e..5864f5cc6827 100644
--- a/drivers/hwmon/ast_pwm_fan.c
+++ b/drivers/hwmon/ast_pwm_fan.c
@@ -65,6 +65,8 @@
#include <mach/ast_pwm_techo.h>
#endif
+#include <plat/ast-scu.h>
+
//#define MCLK 1
struct ast_pwm_tacho_data {
@@ -119,6 +121,8 @@ ast_pwm_tacho_read(struct ast_pwm_tacho_data *ast_pwm_tacho, u32 reg)
static void ast_pwm_taco_init(void)
{
+ uint32_t val;
+
//Enable PWM TACH CLK **************************************************
// Set M/N/O out is 25Khz
//The PWM frequency = 24Mhz / (16 * 6 * (9 + 1)) = 25Khz
@@ -153,15 +157,20 @@ static void ast_pwm_taco_init(void)
ast_pwm_tacho_write(ast_pwm_tacho, 0x0, AST_PTCR_TACH_SOURCE);
ast_pwm_tacho_write(ast_pwm_tacho, 0x0, AST_PTCR_TACH_SOURCE_EXT);
- //PWM A~D -> Disable , type M,
+ //PWM A~H -> Disable , type M,
//Tacho 0~15 Disable
//CLK source 24Mhz
+ val = AST_PTCR_CTRL_PWMA_EN | AST_PTCR_CTRL_PWMB_EN
+ | AST_PTCR_CTRL_PWMC_EN | AST_PTCR_CTRL_PWMD_EN
+ | AST_PTCR_CTRL_CLK_EN;
#ifdef MCLK
- ast_pwm_tacho_write(ast_pwm_tacho, AST_PTCR_CTRL_CLK_MCLK | AST_PTCR_CTRL_CLK_EN, AST_PTCR_CTRL);
+ ast_pwm_tacho_write(ast_pwm_tacho, val|AST_PTCR_CTRL_CLK_MCLK, AST_PTCR_CTRL);
#else
- ast_pwm_tacho_write(ast_pwm_tacho, AST_PTCR_CTRL_CLK_EN, AST_PTCR_CTRL);
+ ast_pwm_tacho_write(ast_pwm_tacho, val, AST_PTCR_CTRL);
#endif
-
+ val = AST_PTCR_CTRL_PWME_EN | AST_PTCR_CTRL_PWMF_EN
+ | AST_PTCR_CTRL_PWMG_EN | AST_PTCR_CTRL_PWMH_EN;
+ ast_pwm_tacho_write(ast_pwm_tacho, val, AST_PTCR_CTRL_EXT);
}
/*index 0 : clk_en , 1: clk_source*/
@@ -724,7 +733,7 @@ ast_get_tacho_rpm(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 tacho_ch)
else
clk_source = 24*1000*1000;
- printk("raw_data %d, clk_source %d, tacho_clk_div %d \n",raw_data, clk_source, tacho_clk_div);
+ // printk("raw_data %d, clk_source %d, tacho_clk_div %d \n",raw_data, clk_source, tacho_clk_div);
rpm = (clk_source * 60) / (2 * raw_data * tacho_clk_div);
return rpm;
@@ -923,28 +932,28 @@ ast_get_pwm_en(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_ch)
switch (pwm_ch) {
case PWMA:
- tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & AST_PTCR_CTRL_PMWA_EN) >> AST_PTCR_CTRL_PMWA;
+ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & AST_PTCR_CTRL_PWMA_EN) >> AST_PTCR_CTRL_PWMA;
break;
case PWMB:
- tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & AST_PTCR_CTRL_PMWB_EN) >> AST_PTCR_CTRL_PMWB;
+ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & AST_PTCR_CTRL_PWMB_EN) >> AST_PTCR_CTRL_PWMB;
break;
case PWMC:
- tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & AST_PTCR_CTRL_PMWC_EN) >> AST_PTCR_CTRL_PMWC;
+ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & AST_PTCR_CTRL_PWMC_EN) >> AST_PTCR_CTRL_PWMC;
break;
case PWMD:
- tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & AST_PTCR_CTRL_PMWD_EN) >> AST_PTCR_CTRL_PMWD;
+ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & AST_PTCR_CTRL_PWMD_EN) >> AST_PTCR_CTRL_PWMD;
break;
case PWME:
- tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & AST_PTCR_CTRL_PMWE_EN) >> AST_PTCR_CTRL_PMWE;
+ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & AST_PTCR_CTRL_PWME_EN) >> AST_PTCR_CTRL_PWME;
break;
case PWMF:
- tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & AST_PTCR_CTRL_PMWF_EN) >> AST_PTCR_CTRL_PMWF;
+ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & AST_PTCR_CTRL_PWMF_EN) >> AST_PTCR_CTRL_PWMF;
break;
case PWMG:
- tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & AST_PTCR_CTRL_PMWG_EN) >> AST_PTCR_CTRL_PMWG;
+ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & AST_PTCR_CTRL_PWMG_EN) >> AST_PTCR_CTRL_PWMG;
break;
case PWMH:
- tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & AST_PTCR_CTRL_PMWH_EN) >> AST_PTCR_CTRL_PMWH;
+ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & AST_PTCR_CTRL_PWMH_EN) >> AST_PTCR_CTRL_PWMH;
break;
default:
printk("error channel ast_get_pwm_type %d \n",pwm_ch);
@@ -962,87 +971,87 @@ ast_set_pwm_en(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_ch, u8 enable)
case PWMA:
if(enable)
ast_pwm_tacho_write(ast_pwm_tacho,
- ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_PMWA_EN,
+ ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_PWMA_EN,
AST_PTCR_CTRL);
else
ast_pwm_tacho_write(ast_pwm_tacho,
- ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_PMWA_EN,
+ ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_PWMA_EN,
AST_PTCR_CTRL);
break;
case PWMB:
if(enable)
ast_pwm_tacho_write(ast_pwm_tacho,
- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_PMWB_EN),
+ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_PWMB_EN),
AST_PTCR_CTRL);
else
ast_pwm_tacho_write(ast_pwm_tacho,
- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_PMWB_EN),
+ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_PWMB_EN),
AST_PTCR_CTRL);
break;
case PWMC:
if(enable)
ast_pwm_tacho_write(ast_pwm_tacho,
- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_PMWC_EN),
+ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_PWMC_EN),
AST_PTCR_CTRL);
else
ast_pwm_tacho_write(ast_pwm_tacho,
- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_PMWC_EN),
+ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_PWMC_EN),
AST_PTCR_CTRL);
break;
case PWMD:
if(enable)
ast_pwm_tacho_write(ast_pwm_tacho,
- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_PMWD_EN),
+ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_PWMD_EN),
AST_PTCR_CTRL);
else
ast_pwm_tacho_write(ast_pwm_tacho,
- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_PMWD_EN),
+ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_PWMD_EN),
AST_PTCR_CTRL);
break;
case PWME:
if(enable)
ast_pwm_tacho_write(ast_pwm_tacho,
- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) | AST_PTCR_CTRL_PMWE_EN),
+ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) | AST_PTCR_CTRL_PWME_EN),
AST_PTCR_CTRL_EXT);
else
ast_pwm_tacho_write(ast_pwm_tacho,
- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & ~AST_PTCR_CTRL_PMWE_EN),
+ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & ~AST_PTCR_CTRL_PWME_EN),
AST_PTCR_CTRL_EXT);
break;
case PWMF:
if(enable)
ast_pwm_tacho_write(ast_pwm_tacho,
- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) | AST_PTCR_CTRL_PMWF_EN),
+ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) | AST_PTCR_CTRL_PWMF_EN),
AST_PTCR_CTRL_EXT);
else
ast_pwm_tacho_write(ast_pwm_tacho,
- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & ~AST_PTCR_CTRL_PMWF_EN),
+ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & ~AST_PTCR_CTRL_PWMF_EN),
AST_PTCR_CTRL_EXT);
break;
case PWMG:
if(enable)
ast_pwm_tacho_write(ast_pwm_tacho,
- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) | AST_PTCR_CTRL_PMWG_EN),
+ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) | AST_PTCR_CTRL_PWMG_EN),
AST_PTCR_CTRL_EXT);
else
ast_pwm_tacho_write(ast_pwm_tacho,
- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & ~AST_PTCR_CTRL_PMWG_EN),
+ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & ~AST_PTCR_CTRL_PWMG_EN),
AST_PTCR_CTRL_EXT);
break;
case PWMH:
if(enable)
ast_pwm_tacho_write(ast_pwm_tacho,
- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) | AST_PTCR_CTRL_PMWH_EN),
+ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) | AST_PTCR_CTRL_PWMH_EN),
AST_PTCR_CTRL_EXT);
else
ast_pwm_tacho_write(ast_pwm_tacho,
- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & ~AST_PTCR_CTRL_PMWH_EN),
+ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & ~AST_PTCR_CTRL_PWMH_EN),
AST_PTCR_CTRL_EXT);
break;
@@ -1383,6 +1392,22 @@ ast_set_pwm_duty_falling(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_ch, u8
}
+/* NAME sysfs */
+static ssize_t
+show_name(struct device *dev, struct device_attribute *devattr,
+ char *buf)
+{
+ return sprintf(buf, "ast_pwm\n");
+}
+static SENSOR_DEVICE_ATTR_2(name, S_IRUGO, show_name, NULL, 0, 0);
+static struct attribute *name_attributes[] = {
+ &sensor_dev_attr_name.dev_attr.attr,
+ NULL
+};
+static const struct attribute_group name_attribute_groups = {
+ .attrs = name_attributes,
+};
+
/*PWM M/N/O Type sysfs*/
/*
* Macro defining SENSOR_DEVICE_ATTR for a pwm sysfs entries.
@@ -1937,6 +1962,51 @@ static const struct attribute_group tacho_attribute_groups[] = {
{ .attrs = tacho15_attributes },
};
+/* Create fan sysfs for lm-sensors, index starts from 1 */
+#define sysfs_fan_speeds_num(index) \
+static SENSOR_DEVICE_ATTR_2(fan##index##_input, S_IRUGO, \
+ ast_show_tacho_speed, NULL, 2, index - 1); \
+static struct attribute *fan##index##_attributes[] = { \
+ &sensor_dev_attr_fan##index##_input.dev_attr.attr, \
+ NULL \
+};
+
+sysfs_fan_speeds_num(1);
+sysfs_fan_speeds_num(2);
+sysfs_fan_speeds_num(3);
+sysfs_fan_speeds_num(4);
+sysfs_fan_speeds_num(5);
+sysfs_fan_speeds_num(6);
+sysfs_fan_speeds_num(7);
+sysfs_fan_speeds_num(8);
+sysfs_fan_speeds_num(9);
+sysfs_fan_speeds_num(10);
+sysfs_fan_speeds_num(11);
+sysfs_fan_speeds_num(12);
+sysfs_fan_speeds_num(13);
+sysfs_fan_speeds_num(14);
+sysfs_fan_speeds_num(15);
+sysfs_fan_speeds_num(16);
+
+static const struct attribute_group fan_attribute_groups[] = {
+ { .attrs = fan1_attributes },
+ { .attrs = fan2_attributes },
+ { .attrs = fan3_attributes },
+ { .attrs = fan4_attributes },
+ { .attrs = fan5_attributes },
+ { .attrs = fan6_attributes },
+ { .attrs = fan7_attributes },
+ { .attrs = fan8_attributes },
+ { .attrs = fan9_attributes },
+ { .attrs = fan10_attributes },
+ { .attrs = fan11_attributes },
+ { .attrs = fan12_attributes },
+ { .attrs = fan13_attributes },
+ { .attrs = fan14_attributes },
+ { .attrs = fan15_attributes },
+ { .attrs = fan16_attributes },
+};
+
static int
ast_pwm_tacho_probe(struct platform_device *pdev)
{
@@ -1947,6 +2017,12 @@ ast_pwm_tacho_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "ast_pwm_fan_probe \n");
+ //SCU Pin-MUX //PWM & TACHO
+ ast_scu_multi_func_pwm_tacho();
+
+ //SCU PWM CTRL Reset
+ ast_scu_init_pwm_tacho();
+
ast_pwm_tacho = kzalloc(sizeof(struct ast_pwm_tacho_data), GFP_KERNEL);
if (!ast_pwm_tacho) {
ret = -ENOMEM;
@@ -1982,10 +2058,14 @@ ast_pwm_tacho_probe(struct platform_device *pdev)
}
/* Register sysfs hooks */
- err = sysfs_create_group(&pdev->dev.kobj, &clk_attribute_groups);
+ err = sysfs_create_group(&pdev->dev.kobj, &name_attribute_groups);
if (err)
goto out_region;
+ err = sysfs_create_group(&pdev->dev.kobj, &clk_attribute_groups);
+ if (err)
+ goto out_sysfs00;
+
ast_pwm_tacho->hwmon_dev = hwmon_device_register(&pdev->dev);
if (IS_ERR(ast_pwm_tacho->hwmon_dev)) {
ret = PTR_ERR(ast_pwm_tacho->hwmon_dev);
@@ -2017,12 +2097,22 @@ ast_pwm_tacho_probe(struct platform_device *pdev)
goto out_sysfs3;
}
+ for(i=0; i< TACHO_NUM; i++) {
+ err = sysfs_create_group(&pdev->dev.kobj, &fan_attribute_groups[i]);
+ if (err)
+ goto out_sysfs4;
+ }
+
ast_pwm_taco_init();
printk(KERN_INFO "ast_pwm_tacho: driver successfully loaded.\n");
return 0;
+out_sysfs4:
+ for(i=0; i< PWM_TYPE_NUM; i++)
+ sysfs_remove_group(&pdev->dev.kobj, &tacho_type_attribute_groups[i]);
+
out_sysfs3:
for(i=0; i< TACHO_NUM; i++)
sysfs_remove_group(&pdev->dev.kobj, &tacho_attribute_groups[i]);
@@ -2036,6 +2126,8 @@ out_sysfs1:
sysfs_remove_group(&pdev->dev.kobj, &pwm_attribute_groups[i]);
out_sysfs0:
sysfs_remove_group(&pdev->dev.kobj, &clk_attribute_groups);
+out_sysfs00:
+ sysfs_remove_group(&pdev->dev.kobj, &name_attribute_groups);
//out_irq:
// free_irq(ast_pwm_tacho->irq, NULL);
@@ -2058,9 +2150,10 @@ ast_pwm_tacho_remove(struct platform_device *pdev)
hwmon_device_unregister(ast_pwm_tacho->hwmon_dev);
- for(i=0; i<16; i++)
+ for(i=0; i<16; i++) {
sysfs_remove_group(&pdev->dev.kobj, &tacho_attribute_groups[i]);
-
+ sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[i]);
+ }
for(i=0; i<3; i++)
sysfs_remove_group(&pdev->dev.kobj, &pwm_type_attribute_groups[i]);
@@ -2069,6 +2162,8 @@ ast_pwm_tacho_remove(struct platform_device *pdev)
sysfs_remove_group(&pdev->dev.kobj, &clk_attribute_groups);
+ sysfs_remove_group(&pdev->dev.kobj, &name_attribute_groups);
+
platform_set_drvdata(pdev, NULL);
// free_irq(ast_pwm_tacho->irq, ast_pwm_tacho);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);