Lines Matching full:pvt
34 #include "bt1-pvt.h"
51 * to PVT data and vice-versa are following:
128 * Baikal-T1 PVT mode can be updated only when the controller is disabled.
134 static inline void pvt_set_mode(struct pvt_hwmon *pvt, u32 mode) in pvt_set_mode() argument
140 old = pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, 0); in pvt_set_mode()
141 pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_MODE_MASK | PVT_CTRL_EN, in pvt_set_mode()
152 static inline void pvt_set_trim(struct pvt_hwmon *pvt, u32 trim) in pvt_set_trim() argument
158 old = pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, 0); in pvt_set_trim()
159 pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_TRIM_MASK | PVT_CTRL_EN, in pvt_set_trim()
163 static inline void pvt_set_tout(struct pvt_hwmon *pvt, u32 tout) in pvt_set_tout() argument
167 old = pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, 0); in pvt_set_tout()
168 writel(tout, pvt->regs + PVT_TTIMEOUT); in pvt_set_tout()
169 pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, old); in pvt_set_tout()
173 * This driver can optionally provide the hwmon alarms for each sensor the PVT
177 * your system design it's recommended to have them disabled to prevent the PVT
181 * Baikal-T1 PVT embedded controller is based on the Analog Bits PVT sensor,
182 * but is equipped with a dedicated control wrapper. It exposes the PVT
207 struct pvt_hwmon *pvt = data; in pvt_soft_isr() local
216 thres_sts = readl(pvt->regs + PVT_RAW_INTR_STAT); in pvt_soft_isr()
219 * Then lets recharge the PVT interface with the next sampling mode. in pvt_soft_isr()
223 cache = &pvt->cache[pvt->sensor]; in pvt_soft_isr()
224 info = &pvt_info[pvt->sensor]; in pvt_soft_isr()
225 pvt->sensor = (pvt->sensor == PVT_SENSOR_LAST) ? in pvt_soft_isr()
226 PVT_SENSOR_FIRST : (pvt->sensor + 1); in pvt_soft_isr()
237 mutex_lock(&pvt->iface_mtx); in pvt_soft_isr()
239 old = pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_DVALID, in pvt_soft_isr()
242 val = readl(pvt->regs + PVT_DATA); in pvt_soft_isr()
244 pvt_set_mode(pvt, pvt_info[pvt->sensor].mode); in pvt_soft_isr()
246 pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_DVALID, old); in pvt_soft_isr()
248 mutex_unlock(&pvt->iface_mtx); in pvt_soft_isr()
262 * While PVT core is doing the next mode data conversion, we'll check in pvt_soft_isr()
269 hwmon_notify_event(pvt->hwmon, info->type, info->attr_min_alarm, in pvt_soft_isr()
273 hwmon_notify_event(pvt->hwmon, info->type, info->attr_max_alarm, in pvt_soft_isr()
290 static int pvt_read_data(struct pvt_hwmon *pvt, enum pvt_sensor_type type, in pvt_read_data() argument
293 struct pvt_cache *cache = &pvt->cache[type]; in pvt_read_data()
310 static int pvt_read_limit(struct pvt_hwmon *pvt, enum pvt_sensor_type type, in pvt_read_limit() argument
316 data = readl(pvt->regs + pvt_info[type].thres_base); in pvt_read_limit()
331 static int pvt_write_limit(struct pvt_hwmon *pvt, enum pvt_sensor_type type, in pvt_write_limit() argument
346 ret = mutex_lock_interruptible(&pvt->iface_mtx); in pvt_write_limit()
351 limit = readl(pvt->regs + pvt_info[type].thres_base); in pvt_write_limit()
364 pvt_update(pvt->regs + pvt_info[type].thres_base, mask, data); in pvt_write_limit()
366 mutex_unlock(&pvt->iface_mtx); in pvt_write_limit()
371 static int pvt_read_alarm(struct pvt_hwmon *pvt, enum pvt_sensor_type type, in pvt_read_alarm() argument
375 *val = !!READ_ONCE(pvt->cache[type].thres_sts_lo); in pvt_read_alarm()
377 *val = !!READ_ONCE(pvt->cache[type].thres_sts_hi); in pvt_read_alarm()
410 struct pvt_hwmon *pvt = data; in pvt_hard_isr() local
418 pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_DVALID, in pvt_hard_isr()
425 val = readl(pvt->regs + PVT_DATA); in pvt_hard_isr()
427 dev_err(pvt->dev, "Got IRQ when data isn't valid\n"); in pvt_hard_isr()
431 cache = &pvt->cache[pvt->sensor]; in pvt_hard_isr()
452 static int pvt_read_data(struct pvt_hwmon *pvt, enum pvt_sensor_type type, in pvt_read_data() argument
455 struct pvt_cache *cache = &pvt->cache[type]; in pvt_read_data()
461 * Lock PVT conversion interface until data cache is updated. The in pvt_read_data()
462 * data read procedure is following: set the requested PVT sensor in pvt_read_data()
466 ret = mutex_lock_interruptible(&pvt->iface_mtx); in pvt_read_data()
470 pvt->sensor = type; in pvt_read_data()
471 pvt_set_mode(pvt, pvt_info[type].mode); in pvt_read_data()
477 pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_DVALID, 0); in pvt_read_data()
478 pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, PVT_CTRL_EN); in pvt_read_data()
486 timeout = 2 * usecs_to_jiffies(ktime_to_us(pvt->timeout)); in pvt_read_data()
489 pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, 0); in pvt_read_data()
490 pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_DVALID, in pvt_read_data()
495 mutex_unlock(&pvt->iface_mtx); in pvt_read_data()
508 static int pvt_read_limit(struct pvt_hwmon *pvt, enum pvt_sensor_type type, in pvt_read_limit() argument
514 static int pvt_write_limit(struct pvt_hwmon *pvt, enum pvt_sensor_type type, in pvt_write_limit() argument
520 static int pvt_read_alarm(struct pvt_hwmon *pvt, enum pvt_sensor_type type, in pvt_read_alarm() argument
612 static int pvt_read_trim(struct pvt_hwmon *pvt, long *val) in pvt_read_trim() argument
616 data = readl(pvt->regs + PVT_CTRL); in pvt_read_trim()
622 static int pvt_write_trim(struct pvt_hwmon *pvt, long val) in pvt_write_trim() argument
631 ret = mutex_lock_interruptible(&pvt->iface_mtx); in pvt_write_trim()
636 pvt_set_trim(pvt, trim); in pvt_write_trim()
638 mutex_unlock(&pvt->iface_mtx); in pvt_write_trim()
643 static int pvt_read_timeout(struct pvt_hwmon *pvt, long *val) in pvt_read_timeout() argument
647 ret = mutex_lock_interruptible(&pvt->iface_mtx); in pvt_read_timeout()
652 *val = ktime_to_ms(pvt->timeout); in pvt_read_timeout()
654 mutex_unlock(&pvt->iface_mtx); in pvt_read_timeout()
659 static int pvt_write_timeout(struct pvt_hwmon *pvt, long val) in pvt_write_timeout() argument
666 rate = clk_get_rate(pvt->clks[PVT_CLOCK_REF].clk); in pvt_write_timeout()
682 * PVT sampling rate. Make sure the timeout is not negative. in pvt_write_timeout()
696 * we have to disable PVT in order to have the new delay actually in pvt_write_timeout()
699 ret = mutex_lock_interruptible(&pvt->iface_mtx); in pvt_write_timeout()
703 pvt_set_tout(pvt, data); in pvt_write_timeout()
704 pvt->timeout = cache; in pvt_write_timeout()
706 mutex_unlock(&pvt->iface_mtx); in pvt_write_timeout()
714 struct pvt_hwmon *pvt = dev_get_drvdata(dev); in pvt_hwmon_read() local
723 return pvt_read_timeout(pvt, val); in pvt_hwmon_read()
729 return pvt_read_data(pvt, ch, val); in pvt_hwmon_read()
734 return pvt_read_limit(pvt, ch, true, val); in pvt_hwmon_read()
736 return pvt_read_limit(pvt, ch, false, val); in pvt_hwmon_read()
738 return pvt_read_alarm(pvt, ch, true, val); in pvt_hwmon_read()
740 return pvt_read_alarm(pvt, ch, false, val); in pvt_hwmon_read()
742 return pvt_read_trim(pvt, val); in pvt_hwmon_read()
748 return pvt_read_data(pvt, PVT_VOLT + ch, val); in pvt_hwmon_read()
750 return pvt_read_limit(pvt, PVT_VOLT + ch, true, val); in pvt_hwmon_read()
752 return pvt_read_limit(pvt, PVT_VOLT + ch, false, val); in pvt_hwmon_read()
754 return pvt_read_alarm(pvt, PVT_VOLT + ch, true, val); in pvt_hwmon_read()
756 return pvt_read_alarm(pvt, PVT_VOLT + ch, false, val); in pvt_hwmon_read()
798 struct pvt_hwmon *pvt = dev_get_drvdata(dev); in pvt_hwmon_write() local
807 return pvt_write_timeout(pvt, val); in pvt_hwmon_write()
813 return pvt_write_limit(pvt, ch, true, val); in pvt_hwmon_write()
815 return pvt_write_limit(pvt, ch, false, val); in pvt_hwmon_write()
817 return pvt_write_trim(pvt, val); in pvt_hwmon_write()
823 return pvt_write_limit(pvt, PVT_VOLT + ch, true, val); in pvt_hwmon_write()
825 return pvt_write_limit(pvt, PVT_VOLT + ch, false, val); in pvt_hwmon_write()
849 struct pvt_hwmon *pvt = data; in pvt_clear_data() local
854 complete_all(&pvt->cache[idx].conversion); in pvt_clear_data()
857 mutex_destroy(&pvt->iface_mtx); in pvt_clear_data()
863 struct pvt_hwmon *pvt; in pvt_create_data() local
866 pvt = devm_kzalloc(dev, sizeof(*pvt), GFP_KERNEL); in pvt_create_data()
867 if (!pvt) in pvt_create_data()
870 ret = devm_add_action(dev, pvt_clear_data, pvt); in pvt_create_data()
872 dev_err(dev, "Can't add PVT data clear action\n"); in pvt_create_data()
876 pvt->dev = dev; in pvt_create_data()
877 pvt->sensor = PVT_SENSOR_FIRST; in pvt_create_data()
878 mutex_init(&pvt->iface_mtx); in pvt_create_data()
882 seqlock_init(&pvt->cache[idx].data_seqlock); in pvt_create_data()
885 init_completion(&pvt->cache[idx].conversion); in pvt_create_data()
888 return pvt; in pvt_create_data()
891 static int pvt_request_regs(struct pvt_hwmon *pvt) in pvt_request_regs() argument
893 struct platform_device *pdev = to_platform_device(pvt->dev); in pvt_request_regs()
895 pvt->regs = devm_platform_ioremap_resource(pdev, 0); in pvt_request_regs()
896 if (IS_ERR(pvt->regs)) in pvt_request_regs()
897 return PTR_ERR(pvt->regs); in pvt_request_regs()
904 struct pvt_hwmon *pvt = data; in pvt_disable_clks() local
906 clk_bulk_disable_unprepare(PVT_CLOCK_NUM, pvt->clks); in pvt_disable_clks()
909 static int pvt_request_clks(struct pvt_hwmon *pvt) in pvt_request_clks() argument
913 pvt->clks[PVT_CLOCK_APB].id = "pclk"; in pvt_request_clks()
914 pvt->clks[PVT_CLOCK_REF].id = "ref"; in pvt_request_clks()
916 ret = devm_clk_bulk_get(pvt->dev, PVT_CLOCK_NUM, pvt->clks); in pvt_request_clks()
918 dev_err(pvt->dev, "Couldn't get PVT clocks descriptors\n"); in pvt_request_clks()
922 ret = clk_bulk_prepare_enable(PVT_CLOCK_NUM, pvt->clks); in pvt_request_clks()
924 dev_err(pvt->dev, "Couldn't enable the PVT clocks\n"); in pvt_request_clks()
928 ret = devm_add_action_or_reset(pvt->dev, pvt_disable_clks, pvt); in pvt_request_clks()
930 dev_err(pvt->dev, "Can't add PVT clocks disable action\n"); in pvt_request_clks()
937 static int pvt_check_pwr(struct pvt_hwmon *pvt) in pvt_check_pwr() argument
953 pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_ALL, PVT_INTR_ALL); in pvt_check_pwr()
954 pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, PVT_CTRL_EN); in pvt_check_pwr()
955 pvt_set_tout(pvt, 0); in pvt_check_pwr()
956 readl(pvt->regs + PVT_DATA); in pvt_check_pwr()
961 data = readl(pvt->regs + PVT_DATA); in pvt_check_pwr()
964 dev_err(pvt->dev, "Sensor is powered down\n"); in pvt_check_pwr()
967 pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, 0); in pvt_check_pwr()
972 static int pvt_init_iface(struct pvt_hwmon *pvt) in pvt_init_iface() argument
977 rate = clk_get_rate(pvt->clks[PVT_CLOCK_REF].clk); in pvt_init_iface()
979 dev_err(pvt->dev, "Invalid reference clock rate\n"); in pvt_init_iface()
988 pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_ALL, PVT_INTR_ALL); in pvt_init_iface()
989 pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, 0); in pvt_init_iface()
990 readl(pvt->regs + PVT_CLR_INTR); in pvt_init_iface()
991 readl(pvt->regs + PVT_DATA); in pvt_init_iface()
994 pvt_set_mode(pvt, pvt_info[pvt->sensor].mode); in pvt_init_iface()
995 pvt_set_tout(pvt, PVT_TOUT_DEF); in pvt_init_iface()
1011 pvt->timeout = ktime_set(PVT_SENSORS_NUM * PVT_TOUT_DEF, 0); in pvt_init_iface()
1012 pvt->timeout = ktime_divns(pvt->timeout, rate); in pvt_init_iface()
1013 pvt->timeout = ktime_add_ns(pvt->timeout, PVT_SENSORS_NUM * PVT_TOUT_MIN); in pvt_init_iface()
1015 pvt->timeout = ktime_set(PVT_TOUT_DEF, 0); in pvt_init_iface()
1016 pvt->timeout = ktime_divns(pvt->timeout, rate); in pvt_init_iface()
1017 pvt->timeout = ktime_add_ns(pvt->timeout, PVT_TOUT_MIN); in pvt_init_iface()
1021 if (!of_property_read_u32(pvt->dev->of_node, in pvt_init_iface()
1022 "baikal,pvt-temp-offset-millicelsius", &temp)) in pvt_init_iface()
1025 pvt_set_trim(pvt, trim); in pvt_init_iface()
1030 static int pvt_request_irq(struct pvt_hwmon *pvt) in pvt_request_irq() argument
1032 struct platform_device *pdev = to_platform_device(pvt->dev); in pvt_request_irq()
1035 pvt->irq = platform_get_irq(pdev, 0); in pvt_request_irq()
1036 if (pvt->irq < 0) in pvt_request_irq()
1037 return pvt->irq; in pvt_request_irq()
1039 ret = devm_request_threaded_irq(pvt->dev, pvt->irq, in pvt_request_irq()
1047 "pvt", pvt); in pvt_request_irq()
1049 dev_err(pvt->dev, "Couldn't request PVT IRQ\n"); in pvt_request_irq()
1056 static int pvt_create_hwmon(struct pvt_hwmon *pvt) in pvt_create_hwmon() argument
1058 pvt->hwmon = devm_hwmon_device_register_with_info(pvt->dev, "pvt", pvt, in pvt_create_hwmon()
1060 if (IS_ERR(pvt->hwmon)) { in pvt_create_hwmon()
1061 dev_err(pvt->dev, "Couldn't create hwmon device\n"); in pvt_create_hwmon()
1062 return PTR_ERR(pvt->hwmon); in pvt_create_hwmon()
1072 struct pvt_hwmon *pvt = data; in pvt_disable_iface() local
1074 mutex_lock(&pvt->iface_mtx); in pvt_disable_iface()
1075 pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, 0); in pvt_disable_iface()
1076 pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_DVALID, in pvt_disable_iface()
1078 mutex_unlock(&pvt->iface_mtx); in pvt_disable_iface()
1081 static int pvt_enable_iface(struct pvt_hwmon *pvt) in pvt_enable_iface() argument
1085 ret = devm_add_action(pvt->dev, pvt_disable_iface, pvt); in pvt_enable_iface()
1087 dev_err(pvt->dev, "Can't add PVT disable interface action\n"); in pvt_enable_iface()
1097 mutex_lock(&pvt->iface_mtx); in pvt_enable_iface()
1098 pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_DVALID, 0); in pvt_enable_iface()
1099 pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, PVT_CTRL_EN); in pvt_enable_iface()
1100 mutex_unlock(&pvt->iface_mtx); in pvt_enable_iface()
1107 static int pvt_enable_iface(struct pvt_hwmon *pvt) in pvt_enable_iface() argument
1116 struct pvt_hwmon *pvt; in pvt_probe() local
1119 pvt = pvt_create_data(pdev); in pvt_probe()
1120 if (IS_ERR(pvt)) in pvt_probe()
1121 return PTR_ERR(pvt); in pvt_probe()
1123 ret = pvt_request_regs(pvt); in pvt_probe()
1127 ret = pvt_request_clks(pvt); in pvt_probe()
1131 ret = pvt_check_pwr(pvt); in pvt_probe()
1135 ret = pvt_init_iface(pvt); in pvt_probe()
1139 ret = pvt_request_irq(pvt); in pvt_probe()
1143 ret = pvt_create_hwmon(pvt); in pvt_probe()
1147 ret = pvt_enable_iface(pvt); in pvt_probe()
1155 { .compatible = "baikal,bt1-pvt" },
1163 .name = "bt1-pvt",
1170 MODULE_DESCRIPTION("Baikal-T1 PVT driver");