diff options
Diffstat (limited to 'drivers/hwmon/ast_pwm_fan.c')
-rw-r--r-- | drivers/hwmon/ast_pwm_fan.c | 159 |
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); |