Lines Matching +full:attr +full:- +full:cnt +full:- +full:name

1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2014-2018 Nuvoton Technology corporation.
7 #include <linux/hwmon-sysfs.h>
147 * Get Fan Tach Timeout (base on clock 214843.75Hz, 1 cnt = 4.654us)
150 * 320RPM/pulse 2, ...-- 10.6Hz)
154 #define NPCM7XX_FAN_TCPA (NPCM7XX_FAN_TCNT - NPCM7XX_FAN_TIMEOUT)
155 #define NPCM7XX_FAN_TCPB (NPCM7XX_FAN_TCNT - NPCM7XX_FAN_TIMEOUT)
186 char name[THERMAL_NAME_LENGTH]; member
226 mutex_lock(&data->pwm_lock[module]); in npcm7xx_pwm_config_set()
229 iowrite32(val, NPCM7XX_PWM_REG_CMRx(data->pwm_base, module, pwm_ch)); in npcm7xx_pwm_config_set()
230 tmp_buf = ioread32(NPCM7XX_PWM_REG_CR(data->pwm_base, module)); in npcm7xx_pwm_config_set()
250 mutex_unlock(&data->pwm_lock[module]); in npcm7xx_pwm_config_set()
251 return -ENODEV; in npcm7xx_pwm_config_set()
264 iowrite32(tmp_buf, NPCM7XX_PWM_REG_CR(data->pwm_base, module)); in npcm7xx_pwm_config_set()
265 mutex_unlock(&data->pwm_lock[module]); in npcm7xx_pwm_config_set()
281 if (data->fan_dev[fan_id].fan_st_flg != FAN_DISABLE) { in npcm7xx_fan_start_capture()
283 spin_lock_irqsave(&data->fan_lock[fan], flags); in npcm7xx_fan_start_capture()
285 data->fan_dev[fan_id].fan_st_flg = FAN_INIT; in npcm7xx_fan_start_capture()
286 reg_int = ioread8(NPCM7XX_FAN_REG_TIEN(data->fan_base, fan)); in npcm7xx_fan_start_capture()
298 NPCM7XX_FAN_REG_TIEN(data->fan_base, fan)); in npcm7xx_fan_start_capture()
301 | ioread8(NPCM7XX_FAN_REG_TCKC(data->fan_base, in npcm7xx_fan_start_capture()
305 iowrite8(reg_mode, NPCM7XX_FAN_REG_TCKC(data->fan_base, in npcm7xx_fan_start_capture()
311 NPCM7XX_FAN_REG_TIEN(data->fan_base, fan)); in npcm7xx_fan_start_capture()
315 | ioread8(NPCM7XX_FAN_REG_TCKC(data->fan_base, in npcm7xx_fan_start_capture()
320 NPCM7XX_FAN_REG_TCKC(data->fan_base, fan)); in npcm7xx_fan_start_capture()
323 spin_unlock_irqrestore(&data->fan_lock[fan], flags); in npcm7xx_fan_start_capture()
342 for (i = data->fan_select; i < NPCM7XX_FAN_MAX_MODULE; in npcm7xx_fan_polling()
346 NPCM7XX_FAN_REG_TICLR(data->fan_base, i)); in npcm7xx_fan_polling()
348 if (data->fan_present[i * 2]) { in npcm7xx_fan_polling()
350 NPCM7XX_FAN_REG_TCNT1(data->fan_base, i)); in npcm7xx_fan_polling()
353 if (data->fan_present[(i * 2) + 1]) { in npcm7xx_fan_polling()
355 NPCM7XX_FAN_REG_TCNT2(data->fan_base, i)); in npcm7xx_fan_polling()
360 data->fan_select++; in npcm7xx_fan_polling()
361 data->fan_select &= 0x3; in npcm7xx_fan_polling()
364 data->fan_timer.expires = jiffies + in npcm7xx_fan_polling()
366 add_timer(&data->fan_timer); in npcm7xx_fan_polling()
378 fan_cap = ioread16(NPCM7XX_FAN_REG_TCRA(data->fan_base, fan)); in npcm7xx_fan_compute()
380 fan_cap = ioread16(NPCM7XX_FAN_REG_TCRB(data->fan_base, fan)); in npcm7xx_fan_compute()
383 iowrite8(flag_clear, NPCM7XX_FAN_REG_TICLR(data->fan_base, fan)); in npcm7xx_fan_compute()
385 if (data->fan_dev[fan_id].fan_st_flg == FAN_INIT) { in npcm7xx_fan_compute()
387 data->fan_dev[fan_id].fan_st_flg = in npcm7xx_fan_compute()
391 data->fan_dev[fan_id].fan_cnt_tmp = 0; in npcm7xx_fan_compute()
392 } else if (data->fan_dev[fan_id].fan_st_flg < FAN_ENOUGH_SAMPLE) { in npcm7xx_fan_compute()
397 data->fan_dev[fan_id].fan_cnt_tmp += in npcm7xx_fan_compute()
398 (NPCM7XX_FAN_TCNT - fan_cap); in npcm7xx_fan_compute()
400 data->fan_dev[fan_id].fan_st_flg++; in npcm7xx_fan_compute()
403 if (data->fan_dev[fan_id].fan_st_flg == FAN_ENOUGH_SAMPLE) { in npcm7xx_fan_compute()
404 data->fan_dev[fan_id].fan_cnt_tmp += in npcm7xx_fan_compute()
405 (NPCM7XX_FAN_TCNT - fan_cap); in npcm7xx_fan_compute()
407 /* compute finial average cnt per pulse */ in npcm7xx_fan_compute()
408 data->fan_dev[fan_id].fan_cnt = in npcm7xx_fan_compute()
409 data->fan_dev[fan_id].fan_cnt_tmp / in npcm7xx_fan_compute()
412 data->fan_dev[fan_id].fan_st_flg = FAN_INIT; in npcm7xx_fan_compute()
415 reg_int = ioread8(NPCM7XX_FAN_REG_TIEN(data->fan_base, fan)); in npcm7xx_fan_compute()
419 NPCM7XX_FAN_REG_TIEN(data->fan_base, fan)); in npcm7xx_fan_compute()
420 reg_mode = ioread8(NPCM7XX_FAN_REG_TCKC(data->fan_base, fan)); in npcm7xx_fan_compute()
424 NPCM7XX_FAN_REG_TCKC(data->fan_base, fan)); in npcm7xx_fan_compute()
457 reg_int = ioread8(NPCM7XX_FAN_REG_TIEN(data->fan_base, fan)); in npcm7xx_check_cmp()
461 NPCM7XX_FAN_REG_TIEN(data->fan_base, fan)); in npcm7xx_check_cmp()
465 NPCM7XX_FAN_REG_TICLR(data->fan_base, fan)); in npcm7xx_check_cmp()
467 reg_mode = ioread8(NPCM7XX_FAN_REG_TCKC(data->fan_base, fan)); in npcm7xx_check_cmp()
471 NPCM7XX_FAN_REG_TCKC(data->fan_base, fan)); in npcm7xx_check_cmp()
478 data->fan_dev[fan_id].fan_cnt = 0; in npcm7xx_check_cmp()
494 module = irq - data->fan_irq[0]; in npcm7xx_fan_isr()
495 spin_lock_irqsave(&data->fan_lock[module], flags); in npcm7xx_fan_isr()
497 flag = ioread8(NPCM7XX_FAN_REG_TICTRL(data->fan_base, module)); in npcm7xx_fan_isr()
501 spin_unlock_irqrestore(&data->fan_lock[module], flags); in npcm7xx_fan_isr()
505 spin_unlock_irqrestore(&data->fan_lock[module], flags); in npcm7xx_fan_isr()
510 static int npcm7xx_read_pwm(struct device *dev, u32 attr, int channel, in npcm7xx_read_pwm() argument
517 switch (attr) { in npcm7xx_read_pwm()
520 (NPCM7XX_PWM_REG_CMRx(data->pwm_base, module, pmw_ch)); in npcm7xx_read_pwm()
523 return -EOPNOTSUPP; in npcm7xx_read_pwm()
527 static int npcm7xx_write_pwm(struct device *dev, u32 attr, int channel, in npcm7xx_write_pwm() argument
533 switch (attr) { in npcm7xx_write_pwm()
536 return -EINVAL; in npcm7xx_write_pwm()
540 err = -EOPNOTSUPP; in npcm7xx_write_pwm()
547 static umode_t npcm7xx_pwm_is_visible(const void *_data, u32 attr, int channel) in npcm7xx_pwm_is_visible() argument
551 if (!data->pwm_present[channel] || channel >= data->info->pwm_max_channel) in npcm7xx_pwm_is_visible()
554 switch (attr) { in npcm7xx_pwm_is_visible()
562 static int npcm7xx_read_fan(struct device *dev, u32 attr, int channel, in npcm7xx_read_fan() argument
567 switch (attr) { in npcm7xx_read_fan()
570 if (data->fan_dev[channel].fan_cnt <= 0) in npcm7xx_read_fan()
571 return data->fan_dev[channel].fan_cnt; in npcm7xx_read_fan()
574 if (data->fan_dev[channel].fan_cnt > 0 && in npcm7xx_read_fan()
575 data->fan_dev[channel].fan_pls_per_rev > 0) in npcm7xx_read_fan()
576 *val = ((data->input_clk_freq * 60) / in npcm7xx_read_fan()
577 (data->fan_dev[channel].fan_cnt * in npcm7xx_read_fan()
578 data->fan_dev[channel].fan_pls_per_rev)); in npcm7xx_read_fan()
581 return -EOPNOTSUPP; in npcm7xx_read_fan()
585 static umode_t npcm7xx_fan_is_visible(const void *_data, u32 attr, int channel) in npcm7xx_fan_is_visible() argument
589 if (!data->fan_present[channel]) in npcm7xx_fan_is_visible()
592 switch (attr) { in npcm7xx_fan_is_visible()
601 u32 attr, int channel, long *val) in npcm7xx_read() argument
605 return npcm7xx_read_pwm(dev, attr, channel, val); in npcm7xx_read()
607 return npcm7xx_read_fan(dev, attr, channel, val); in npcm7xx_read()
609 return -EOPNOTSUPP; in npcm7xx_read()
614 u32 attr, int channel, long val) in npcm7xx_write() argument
618 return npcm7xx_write_pwm(dev, attr, channel, val); in npcm7xx_write()
620 return -EOPNOTSUPP; in npcm7xx_write()
626 u32 attr, int channel) in npcm7xx_is_visible() argument
630 return npcm7xx_pwm_is_visible(data, attr, channel); in npcm7xx_is_visible()
632 return npcm7xx_fan_is_visible(data, attr, channel); in npcm7xx_is_visible()
696 data->pwm_clk_freq = clk_get_rate(data->pwm_clk); in npcm7xx_pwm_init()
699 output_freq = data->pwm_clk_freq / PWN_CNT_DEFAULT; in npcm7xx_pwm_init()
709 prescale_val--; in npcm7xx_pwm_init()
714 for (m = 0; m < data->pwm_modules; m++) { in npcm7xx_pwm_init()
715 iowrite32(prescale_val, NPCM7XX_PWM_REG_PR(data->pwm_base, m)); in npcm7xx_pwm_init()
717 NPCM7XX_PWM_REG_CSR(data->pwm_base, m)); in npcm7xx_pwm_init()
719 NPCM7XX_PWM_REG_CR(data->pwm_base, m)); in npcm7xx_pwm_init()
723 NPCM7XX_PWM_REG_CNRx(data->pwm_base, m, ch)); in npcm7xx_pwm_init()
740 NPCM7XX_FAN_REG_TCKC(data->fan_base, md)); in npcm7xx_fan_init()
743 iowrite8(0x00, NPCM7XX_FAN_REG_TIEN(data->fan_base, md)); in npcm7xx_fan_init()
747 NPCM7XX_FAN_REG_TICLR(data->fan_base, md)); in npcm7xx_fan_init()
751 NPCM7XX_FAN_REG_TPRSC(data->fan_base, md)); in npcm7xx_fan_init()
753 /* set FAN0~7 mode (high-to-low transition) */ in npcm7xx_fan_init()
756 NPCM7XX_FAN_REG_TMCTRL(data->fan_base, md)); in npcm7xx_fan_init()
760 NPCM7XX_FAN_REG_TCNT1(data->fan_base, md)); in npcm7xx_fan_init()
762 NPCM7XX_FAN_REG_TCNT2(data->fan_base, md)); in npcm7xx_fan_init()
766 NPCM7XX_FAN_REG_TCPCFG(data->fan_base, md)); in npcm7xx_fan_init()
770 NPCM7XX_FAN_REG_TCPA(data->fan_base, md)); in npcm7xx_fan_init()
772 NPCM7XX_FAN_REG_TCPB(data->fan_base, md)); in npcm7xx_fan_init()
776 NPCM7XX_FAN_REG_TINASEL(data->fan_base, md)); in npcm7xx_fan_init()
778 NPCM7XX_FAN_REG_TINBSEL(data->fan_base, md)); in npcm7xx_fan_init()
782 data->fan_dev[ch].fan_st_flg = FAN_DISABLE; in npcm7xx_fan_init()
783 data->fan_dev[ch].fan_pls_per_rev = in npcm7xx_fan_init()
785 data->fan_dev[ch].fan_cnt = 0; in npcm7xx_fan_init()
789 apb_clk_freq = clk_get_rate(data->fan_clk); in npcm7xx_fan_init()
792 data->input_clk_freq = apb_clk_freq / (NPCM7XX_FAN_CLK_PRESCALE + 1); in npcm7xx_fan_init()
799 struct npcm7xx_cooling_device *cdev = tcdev->devdata; in npcm7xx_pwm_cz_get_max_state()
801 *state = cdev->max_state; in npcm7xx_pwm_cz_get_max_state()
810 struct npcm7xx_cooling_device *cdev = tcdev->devdata; in npcm7xx_pwm_cz_get_cur_state()
812 *state = cdev->cur_state; in npcm7xx_pwm_cz_get_cur_state()
821 struct npcm7xx_cooling_device *cdev = tcdev->devdata; in npcm7xx_pwm_cz_set_cur_state()
824 if (state > cdev->max_state) in npcm7xx_pwm_cz_set_cur_state()
825 return -EINVAL; in npcm7xx_pwm_cz_set_cur_state()
827 cdev->cur_state = state; in npcm7xx_pwm_cz_set_cur_state()
828 ret = npcm7xx_pwm_config_set(cdev->data, cdev->pwm_port, in npcm7xx_pwm_cz_set_cur_state()
829 cdev->cooling_levels[cdev->cur_state]); in npcm7xx_pwm_cz_set_cur_state()
850 return -ENOMEM; in npcm7xx_create_pwm_cooling()
852 cdev->cooling_levels = devm_kzalloc(dev, num_levels, GFP_KERNEL); in npcm7xx_create_pwm_cooling()
853 if (!cdev->cooling_levels) in npcm7xx_create_pwm_cooling()
854 return -ENOMEM; in npcm7xx_create_pwm_cooling()
856 cdev->max_state = num_levels - 1; in npcm7xx_create_pwm_cooling()
857 ret = of_property_read_u8_array(child, "cooling-levels", in npcm7xx_create_pwm_cooling()
858 cdev->cooling_levels, in npcm7xx_create_pwm_cooling()
861 dev_err(dev, "Property 'cooling-levels' cannot be read.\n"); in npcm7xx_create_pwm_cooling()
864 snprintf(cdev->name, THERMAL_NAME_LENGTH, "%pOFn%d", child, in npcm7xx_create_pwm_cooling()
867 cdev->tcdev = devm_thermal_of_cooling_device_register(dev, child, in npcm7xx_create_pwm_cooling()
868 cdev->name, cdev, &npcm7xx_pwm_cool_ops); in npcm7xx_create_pwm_cooling()
869 if (IS_ERR(cdev->tcdev)) in npcm7xx_create_pwm_cooling()
870 return PTR_ERR(cdev->tcdev); in npcm7xx_create_pwm_cooling()
872 cdev->data = data; in npcm7xx_create_pwm_cooling()
873 cdev->pwm_port = pwm_port; in npcm7xx_create_pwm_cooling()
875 data->cdev[pwm_port] = cdev; in npcm7xx_create_pwm_cooling()
893 data->pwm_present[pwm_port] = true; in npcm7xx_en_pwm_fan()
899 ret = of_property_count_u8_elems(child, "cooling-levels"); in npcm7xx_en_pwm_fan()
907 fan_cnt = of_property_count_u8_elems(child, "fan-tach-ch"); in npcm7xx_en_pwm_fan()
909 return -EINVAL; in npcm7xx_en_pwm_fan()
913 return -ENOMEM; in npcm7xx_en_pwm_fan()
915 ret = of_property_read_u8_array(child, "fan-tach-ch", fan_ch, fan_cnt); in npcm7xx_en_pwm_fan()
921 data->fan_present[index] = true; in npcm7xx_en_pwm_fan()
922 data->fan_dev[index].fan_st_flg = FAN_INIT; in npcm7xx_en_pwm_fan()
930 struct device *dev = &pdev->dev; in npcm7xx_pwm_fan_probe()
935 char name[20]; in npcm7xx_pwm_fan_probe() local
936 int ret, cnt; in npcm7xx_pwm_fan_probe() local
940 np = dev->of_node; in npcm7xx_pwm_fan_probe()
944 return -ENOMEM; in npcm7xx_pwm_fan_probe()
946 data->info = device_get_match_data(dev); in npcm7xx_pwm_fan_probe()
947 if (!data->info) in npcm7xx_pwm_fan_probe()
948 return -EINVAL; in npcm7xx_pwm_fan_probe()
950 data->pwm_modules = data->info->pwm_max_channel / NPCM7XX_PWM_MAX_CHN_NUM_IN_A_MODULE; in npcm7xx_pwm_fan_probe()
955 return -ENODEV; in npcm7xx_pwm_fan_probe()
958 data->pwm_base = devm_ioremap_resource(dev, res); in npcm7xx_pwm_fan_probe()
960 if (IS_ERR(data->pwm_base)) in npcm7xx_pwm_fan_probe()
961 return PTR_ERR(data->pwm_base); in npcm7xx_pwm_fan_probe()
963 data->pwm_clk = devm_clk_get(dev, "pwm"); in npcm7xx_pwm_fan_probe()
964 if (IS_ERR(data->pwm_clk)) { in npcm7xx_pwm_fan_probe()
966 return PTR_ERR(data->pwm_clk); in npcm7xx_pwm_fan_probe()
972 return -ENODEV; in npcm7xx_pwm_fan_probe()
975 data->fan_base = devm_ioremap_resource(dev, res); in npcm7xx_pwm_fan_probe()
977 if (IS_ERR(data->fan_base)) in npcm7xx_pwm_fan_probe()
978 return PTR_ERR(data->fan_base); in npcm7xx_pwm_fan_probe()
980 data->fan_clk = devm_clk_get(dev, "fan"); in npcm7xx_pwm_fan_probe()
981 if (IS_ERR(data->fan_clk)) { in npcm7xx_pwm_fan_probe()
983 return PTR_ERR(data->fan_clk); in npcm7xx_pwm_fan_probe()
989 for (cnt = 0; cnt < data->pwm_modules; cnt++) in npcm7xx_pwm_fan_probe()
990 mutex_init(&data->pwm_lock[cnt]); in npcm7xx_pwm_fan_probe()
993 spin_lock_init(&data->fan_lock[i]); in npcm7xx_pwm_fan_probe()
995 data->fan_irq[i] = platform_get_irq(pdev, i); in npcm7xx_pwm_fan_probe()
996 if (data->fan_irq[i] < 0) in npcm7xx_pwm_fan_probe()
997 return data->fan_irq[i]; in npcm7xx_pwm_fan_probe()
999 sprintf(name, "NPCM7XX-FAN-MD%d", i); in npcm7xx_pwm_fan_probe()
1000 ret = devm_request_irq(dev, data->fan_irq[i], npcm7xx_fan_isr, in npcm7xx_pwm_fan_probe()
1001 0, name, (void *)data); in npcm7xx_pwm_fan_probe()
1026 if (data->fan_present[i]) { in npcm7xx_pwm_fan_probe()
1028 data->fan_timer.expires = jiffies + in npcm7xx_pwm_fan_probe()
1030 timer_setup(&data->fan_timer, in npcm7xx_pwm_fan_probe()
1032 add_timer(&data->fan_timer); in npcm7xx_pwm_fan_probe()
1037 pr_info("NPCM7XX PWM-FAN Driver probed, output Freq %dHz[PWM], input Freq %dHz[FAN]\n", in npcm7xx_pwm_fan_probe()
1038 output_freq, data->input_clk_freq); in npcm7xx_pwm_fan_probe()
1044 { .compatible = "nuvoton,npcm750-pwm-fan", .data = &npxm7xx_hwmon_info},
1045 { .compatible = "nuvoton,npcm845-pwm-fan", .data = &npxm8xx_hwmon_info},
1053 .name = "npcm7xx_pwm_fan",