Lines Matching full:ams

3  * Xilinx AMS driver
30 /* AMS registers definitions */
267 * struct ams - This structure contains necessary state for xilinx-ams to operate
281 struct ams { struct
295 static inline void ams_ps_update_reg(struct ams *ams, unsigned int offset, in ams_ps_update_reg() argument
300 val = readl(ams->ps_base + offset); in ams_ps_update_reg()
302 writel(regval, ams->ps_base + offset); in ams_ps_update_reg()
305 static inline void ams_pl_update_reg(struct ams *ams, unsigned int offset, in ams_pl_update_reg() argument
310 val = readl(ams->pl_base + offset); in ams_pl_update_reg()
312 writel(regval, ams->pl_base + offset); in ams_pl_update_reg()
315 static void ams_update_intrmask(struct ams *ams, u64 mask, u64 val) in ams_update_intrmask() argument
319 ams->intr_mask = (ams->intr_mask & ~mask) | (val & mask); in ams_update_intrmask()
321 regval = ~(ams->intr_mask | ams->current_masked_alarm); in ams_update_intrmask()
322 writel(regval, ams->base + AMS_IER_0); in ams_update_intrmask()
324 regval = ~(FIELD_GET(AMS_ISR1_INTR_MASK, ams->intr_mask)); in ams_update_intrmask()
325 writel(regval, ams->base + AMS_IER_1); in ams_update_intrmask()
327 regval = ams->intr_mask | ams->current_masked_alarm; in ams_update_intrmask()
328 writel(regval, ams->base + AMS_IDR_0); in ams_update_intrmask()
330 regval = FIELD_GET(AMS_ISR1_INTR_MASK, ams->intr_mask); in ams_update_intrmask()
331 writel(regval, ams->base + AMS_IDR_1); in ams_update_intrmask()
334 static void ams_disable_all_alarms(struct ams *ams) in ams_disable_all_alarms() argument
337 if (ams->ps_base) { in ams_disable_all_alarms()
338 ams_ps_update_reg(ams, AMS_REG_CONFIG1, AMS_REGCFG1_ALARM_MASK, in ams_disable_all_alarms()
340 ams_ps_update_reg(ams, AMS_REG_CONFIG3, AMS_REGCFG3_ALARM_MASK, in ams_disable_all_alarms()
345 if (ams->pl_base) { in ams_disable_all_alarms()
346 ams_pl_update_reg(ams, AMS_REG_CONFIG1, AMS_REGCFG1_ALARM_MASK, in ams_disable_all_alarms()
348 ams_pl_update_reg(ams, AMS_REG_CONFIG3, AMS_REGCFG3_ALARM_MASK, in ams_disable_all_alarms()
353 static void ams_update_ps_alarm(struct ams *ams, unsigned long alarm_mask) in ams_update_ps_alarm() argument
364 ams_ps_update_reg(ams, AMS_REG_CONFIG1, AMS_REGCFG1_ALARM_MASK, cfg); in ams_update_ps_alarm()
368 ams_ps_update_reg(ams, AMS_REG_CONFIG3, AMS_REGCFG3_ALARM_MASK, cfg); in ams_update_ps_alarm()
371 static void ams_update_pl_alarm(struct ams *ams, unsigned long alarm_mask) in ams_update_pl_alarm() argument
385 ams_pl_update_reg(ams, AMS_REG_CONFIG1, AMS_REGCFG1_ALARM_MASK, cfg); in ams_update_pl_alarm()
389 ams_pl_update_reg(ams, AMS_REG_CONFIG3, AMS_REGCFG3_ALARM_MASK, cfg); in ams_update_pl_alarm()
392 static void ams_update_alarm(struct ams *ams, unsigned long alarm_mask) in ams_update_alarm() argument
396 if (ams->ps_base) in ams_update_alarm()
397 ams_update_ps_alarm(ams, alarm_mask); in ams_update_alarm()
399 if (ams->pl_base) in ams_update_alarm()
400 ams_update_pl_alarm(ams, alarm_mask); in ams_update_alarm()
402 spin_lock_irqsave(&ams->intr_lock, flags); in ams_update_alarm()
403 ams_update_intrmask(ams, AMS_ISR0_ALARM_MASK, ~alarm_mask); in ams_update_alarm()
404 spin_unlock_irqrestore(&ams->intr_lock, flags); in ams_update_alarm()
409 struct ams *ams = iio_priv(indio_dev); in ams_enable_channel_sequence() local
428 if (ams->ps_base) { in ams_enable_channel_sequence()
430 ams_ps_update_reg(ams, AMS_REG_CONFIG1, AMS_CONF1_SEQ_MASK, in ams_enable_channel_sequence()
435 writel(regval, ams->ps_base + AMS_REG_SEQ_CH0); in ams_enable_channel_sequence()
438 writel(regval, ams->ps_base + AMS_REG_SEQ_CH2); in ams_enable_channel_sequence()
441 ams_ps_update_reg(ams, AMS_REG_CONFIG1, AMS_CONF1_SEQ_MASK, in ams_enable_channel_sequence()
445 if (ams->pl_base) { in ams_enable_channel_sequence()
447 ams_pl_update_reg(ams, AMS_REG_CONFIG1, AMS_CONF1_SEQ_MASK, in ams_enable_channel_sequence()
454 writel(regval, ams->pl_base + AMS_REG_SEQ_CH0); in ams_enable_channel_sequence()
457 writel(regval, ams->pl_base + AMS_REG_SEQ_CH1); in ams_enable_channel_sequence()
460 writel(regval, ams->pl_base + AMS_REG_SEQ_CH2); in ams_enable_channel_sequence()
463 ams_pl_update_reg(ams, AMS_REG_CONFIG1, AMS_CONF1_SEQ_MASK, in ams_enable_channel_sequence()
468 static int ams_init_device(struct ams *ams) in ams_init_device() argument
474 /* reset AMS */ in ams_init_device()
475 if (ams->ps_base) { in ams_init_device()
476 writel(AMS_PS_RESET_VALUE, ams->ps_base + AMS_VP_VN); in ams_init_device()
478 ret = readl_poll_timeout(ams->base + AMS_PS_CSTS, reg, (reg & expect), in ams_init_device()
484 ams_ps_update_reg(ams, AMS_REG_CONFIG1, AMS_CONF1_SEQ_MASK, in ams_init_device()
488 if (ams->pl_base) { in ams_init_device()
489 value = readl(ams->base + AMS_PL_CSTS); in ams_init_device()
493 writel(AMS_PL_RESET_VALUE, ams->pl_base + AMS_VP_VN); in ams_init_device()
496 ams_pl_update_reg(ams, AMS_REG_CONFIG1, AMS_CONF1_SEQ_MASK, in ams_init_device()
500 ams_disable_all_alarms(ams); in ams_init_device()
503 ams_update_intrmask(ams, AMS_ALARM_MASK, AMS_ALARM_MASK); in ams_init_device()
506 writel(AMS_ISR0_ALARM_MASK, ams->base + AMS_ISR_0); in ams_init_device()
507 writel(AMS_ISR1_ALARM_MASK, ams->base + AMS_ISR_1); in ams_init_device()
518 static int ams_enable_single_channel(struct ams *ams, unsigned int offset) in ams_enable_single_channel() argument
549 ams_ps_update_reg(ams, AMS_REG_CONFIG1, AMS_CONF1_SEQ_MASK, in ams_enable_single_channel()
553 ams_ps_update_reg(ams, AMS_REG_CONFIG0, AMS_CONF0_CHANNEL_NUM_MASK, in ams_enable_single_channel()
557 ams_ps_update_reg(ams, AMS_REG_CONFIG1, AMS_CONF1_SEQ_MASK, in ams_enable_single_channel()
563 static int ams_read_vcc_reg(struct ams *ams, unsigned int offset, u32 *data) in ams_read_vcc_reg() argument
569 ret = ams_enable_single_channel(ams, offset); in ams_read_vcc_reg()
574 writel(expect, ams->base + AMS_ISR_1); in ams_read_vcc_reg()
575 ret = readl_poll_timeout(ams->base + AMS_ISR_1, reg, (reg & expect), in ams_read_vcc_reg()
580 *data = readl(ams->base + offset); in ams_read_vcc_reg()
613 static int ams_get_pl_scale(struct ams *ams, int address) in ams_get_pl_scale() argument
630 regval = readl(ams->pl_base + AMS_REG_CONFIG4); in ams_get_pl_scale()
637 regval = readl(ams->pl_base + AMS_REG_CONFIG4); in ams_get_pl_scale()
644 regval = readl(ams->pl_base + AMS_REG_CONFIG4); in ams_get_pl_scale()
651 regval = readl(ams->pl_base + AMS_REG_CONFIG4); in ams_get_pl_scale()
695 struct ams *ams = iio_priv(indio_dev); in ams_read_raw() local
700 mutex_lock(&ams->lock); in ams_read_raw()
702 ret = ams_read_vcc_reg(ams, chan->address, val); in ams_read_raw()
707 *val = readl(ams->pl_base + chan->address); in ams_read_raw()
709 *val = readl(ams->ps_base + chan->address); in ams_read_raw()
713 mutex_unlock(&ams->lock); in ams_read_raw()
722 *val = ams_get_pl_scale(ams, chan->address); in ams_read_raw()
899 struct ams *ams = iio_priv(indio_dev); in ams_read_event_config() local
901 return !!(ams->alarm_mask & ams_get_alarm_mask(chan->scan_index)); in ams_read_event_config()
910 struct ams *ams = iio_priv(indio_dev); in ams_write_event_config() local
915 mutex_lock(&ams->lock); in ams_write_event_config()
918 ams->alarm_mask |= alarm; in ams_write_event_config()
920 ams->alarm_mask &= ~alarm; in ams_write_event_config()
922 ams_update_alarm(ams, ams->alarm_mask); in ams_write_event_config()
924 mutex_unlock(&ams->lock); in ams_write_event_config()
935 struct ams *ams = iio_priv(indio_dev); in ams_read_event_value() local
938 mutex_lock(&ams->lock); in ams_read_event_value()
941 *val = readl(ams->pl_base + offset); in ams_read_event_value()
943 *val = readl(ams->ps_base + offset); in ams_read_event_value()
945 mutex_unlock(&ams->lock); in ams_read_event_value()
956 struct ams *ams = iio_priv(indio_dev); in ams_write_event_value() local
959 mutex_lock(&ams->lock); in ams_write_event_value()
966 ams_pl_update_reg(ams, offset, in ams_write_event_value()
970 ams_ps_update_reg(ams, offset, in ams_write_event_value()
977 writel(val, ams->pl_base + offset); in ams_write_event_value()
979 writel(val, ams->ps_base + offset); in ams_write_event_value()
981 mutex_unlock(&ams->lock); in ams_write_event_value()
1025 * ams_unmask_worker - ams alarm interrupt unmask worker
1037 struct ams *ams = container_of(work, struct ams, ams_unmask_work.work); in ams_unmask_worker() local
1040 spin_lock_irq(&ams->intr_lock); in ams_unmask_worker()
1042 status = readl(ams->base + AMS_ISR_0); in ams_unmask_worker()
1045 unmask = (ams->current_masked_alarm ^ status) & ams->current_masked_alarm; in ams_unmask_worker()
1048 unmask |= ams->intr_mask; in ams_unmask_worker()
1050 ams->current_masked_alarm &= status; in ams_unmask_worker()
1053 ams->current_masked_alarm &= ~ams->intr_mask; in ams_unmask_worker()
1056 writel(unmask, ams->base + AMS_ISR_0); in ams_unmask_worker()
1058 ams_update_intrmask(ams, ~AMS_ALARM_MASK, ~AMS_ALARM_MASK); in ams_unmask_worker()
1060 spin_unlock_irq(&ams->intr_lock); in ams_unmask_worker()
1063 if (ams->current_masked_alarm) in ams_unmask_worker()
1064 schedule_delayed_work(&ams->ams_unmask_work, in ams_unmask_worker()
1071 struct ams *ams = iio_priv(indio_dev); in ams_irq() local
1074 spin_lock(&ams->intr_lock); in ams_irq()
1076 isr0 = readl(ams->base + AMS_ISR_0); in ams_irq()
1079 isr0 &= ~((ams->intr_mask & AMS_ISR0_ALARM_MASK) | ams->current_masked_alarm); in ams_irq()
1081 spin_unlock(&ams->intr_lock); in ams_irq()
1086 writel(isr0, ams->base + AMS_ISR_0); in ams_irq()
1089 ams->current_masked_alarm |= isr0; in ams_irq()
1090 ams_update_intrmask(ams, ~AMS_ALARM_MASK, ~AMS_ALARM_MASK); in ams_irq()
1094 schedule_delayed_work(&ams->ams_unmask_work, in ams_irq()
1097 spin_unlock(&ams->intr_lock); in ams_irq()
1216 struct ams *ams = data; in ams_iounmap_ps() local
1218 iounmap(ams->ps_base); in ams_iounmap_ps()
1223 struct ams *ams = data; in ams_iounmap_pl() local
1225 iounmap(ams->pl_base); in ams_iounmap_pl()
1233 struct ams *ams = iio_priv(indio_dev); in ams_init_module() local
1237 if (fwnode_device_is_compatible(fwnode, "xlnx,zynqmp-ams-ps")) { in ams_init_module()
1238 ams->ps_base = fwnode_iomap(fwnode, 0); in ams_init_module()
1239 if (!ams->ps_base) in ams_init_module()
1241 ret = devm_add_action_or_reset(dev, ams_iounmap_ps, ams); in ams_init_module()
1248 } else if (fwnode_device_is_compatible(fwnode, "xlnx,zynqmp-ams-pl")) { in ams_init_module()
1249 ams->pl_base = fwnode_iomap(fwnode, 0); in ams_init_module()
1250 if (!ams->pl_base) in ams_init_module()
1253 ret = devm_add_action_or_reset(dev, ams_iounmap_pl, ams); in ams_init_module()
1262 } else if (fwnode_device_is_compatible(fwnode, "xlnx,zynqmp-ams")) { in ams_init_module()
1263 /* add AMS channels to iio device channels */ in ams_init_module()
1275 struct ams *ams = iio_priv(indio_dev); in ams_parse_firmware() local
1320 ams->pl_base + falling_off); in ams_parse_firmware()
1322 ams->pl_base + rising_off); in ams_parse_firmware()
1325 ams->ps_base + falling_off); in ams_parse_firmware()
1327 ams->ps_base + rising_off); in ams_parse_firmware()
1353 { .compatible = "xlnx,zynqmp-ams" },
1361 struct ams *ams; in ams_probe() local
1365 indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*ams)); in ams_probe()
1369 ams = iio_priv(indio_dev); in ams_probe()
1370 mutex_init(&ams->lock); in ams_probe()
1371 spin_lock_init(&ams->intr_lock); in ams_probe()
1373 indio_dev->name = "xilinx-ams"; in ams_probe()
1378 ams->base = devm_platform_ioremap_resource(pdev, 0); in ams_probe()
1379 if (IS_ERR(ams->base)) in ams_probe()
1380 return PTR_ERR(ams->base); in ams_probe()
1382 ams->clk = devm_clk_get_enabled(&pdev->dev, NULL); in ams_probe()
1383 if (IS_ERR(ams->clk)) in ams_probe()
1384 return PTR_ERR(ams->clk); in ams_probe()
1386 ret = devm_delayed_work_autocancel(&pdev->dev, &ams->ams_unmask_work, in ams_probe()
1395 ret = ams_init_device(ams); in ams_probe()
1397 return dev_err_probe(&pdev->dev, ret, "failed to initialize AMS\n"); in ams_probe()
1405 ret = devm_request_irq(&pdev->dev, irq, &ams_irq, 0, "ams-irq", in ams_probe()
1417 struct ams *ams = iio_priv(dev_get_drvdata(dev)); in ams_suspend() local
1419 clk_disable_unprepare(ams->clk); in ams_suspend()
1426 struct ams *ams = iio_priv(dev_get_drvdata(dev)); in ams_resume() local
1428 return clk_prepare_enable(ams->clk); in ams_resume()
1436 .name = "xilinx-ams",
1443 MODULE_DESCRIPTION("Xilinx AMS driver");