diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/arm/npcm7xx.c | 26 | ||||
-rw-r--r-- | hw/misc/meson.build | 1 | ||||
-rw-r--r-- | hw/misc/npcm7xx_pwm.c | 550 | ||||
-rw-r--r-- | hw/misc/trace-events | 6 |
4 files changed, 581 insertions, 2 deletions
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c index b22a8c966d..72040d4079 100644 --- a/hw/arm/npcm7xx.c +++ b/hw/arm/npcm7xx.c @@ -102,6 +102,8 @@ enum NPCM7xxInterrupt { NPCM7XX_WDG2_IRQ, /* Timer Module 2 Watchdog */ NPCM7XX_EHCI_IRQ = 61, NPCM7XX_OHCI_IRQ = 62, + NPCM7XX_PWM0_IRQ = 93, /* PWM module 0 */ + NPCM7XX_PWM1_IRQ, /* PWM module 1 */ NPCM7XX_GPIO0_IRQ = 116, NPCM7XX_GPIO1_IRQ, NPCM7XX_GPIO2_IRQ, @@ -144,6 +146,12 @@ static const hwaddr npcm7xx_fiu3_flash_addr[] = { 0xb8000000, /* CS3 */ }; +/* Register base address for each PWM Module */ +static const hwaddr npcm7xx_pwm_addr[] = { + 0xf0103000, + 0xf0104000, +}; + static const struct { hwaddr regs_addr; uint32_t unconnected_pins; @@ -353,6 +361,10 @@ static void npcm7xx_init(Object *obj) object_initialize_child(obj, npcm7xx_fiu[i].name, &s->fiu[i], TYPE_NPCM7XX_FIU); } + + for (i = 0; i < ARRAY_SIZE(s->pwm); i++) { + object_initialize_child(obj, "pwm[*]", &s->pwm[i], TYPE_NPCM7XX_PWM); + } } static void npcm7xx_realize(DeviceState *dev, Error **errp) @@ -513,6 +525,18 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp) sysbus_connect_irq(SYS_BUS_DEVICE(&s->ohci), 0, npcm7xx_irq(s, NPCM7XX_OHCI_IRQ)); + /* PWM Modules. Cannot fail. */ + QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_pwm_addr) != ARRAY_SIZE(s->pwm)); + for (i = 0; i < ARRAY_SIZE(s->pwm); i++) { + SysBusDevice *sbd = SYS_BUS_DEVICE(&s->pwm[i]); + + qdev_connect_clock_in(DEVICE(&s->pwm[i]), "clock", qdev_get_clock_out( + DEVICE(&s->clk), "apb3-clock")); + sysbus_realize(sbd, &error_abort); + sysbus_mmio_map(sbd, 0, npcm7xx_pwm_addr[i]); + sysbus_connect_irq(sbd, i, npcm7xx_irq(s, NPCM7XX_PWM0_IRQ + i)); + } + /* * Flash Interface Unit (FIU). Can fail if incorrect number of chip selects * specified, but this is a programming error. @@ -580,8 +604,6 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp) create_unimplemented_device("npcm7xx.peci", 0xf0100000, 4 * KiB); create_unimplemented_device("npcm7xx.siox[1]", 0xf0101000, 4 * KiB); create_unimplemented_device("npcm7xx.siox[2]", 0xf0102000, 4 * KiB); - create_unimplemented_device("npcm7xx.pwm[0]", 0xf0103000, 4 * KiB); - create_unimplemented_device("npcm7xx.pwm[1]", 0xf0104000, 4 * KiB); create_unimplemented_device("npcm7xx.mft[0]", 0xf0180000, 4 * KiB); create_unimplemented_device("npcm7xx.mft[1]", 0xf0181000, 4 * KiB); create_unimplemented_device("npcm7xx.mft[2]", 0xf0182000, 4 * KiB); diff --git a/hw/misc/meson.build b/hw/misc/meson.build index ce15ffceb9..607cd38a21 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -64,6 +64,7 @@ softmmu_ss.add(when: 'CONFIG_MAINSTONE', if_true: files('mst_fpga.c')) softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files( 'npcm7xx_clk.c', 'npcm7xx_gcr.c', + 'npcm7xx_pwm.c', 'npcm7xx_rng.c', )) softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files( diff --git a/hw/misc/npcm7xx_pwm.c b/hw/misc/npcm7xx_pwm.c new file mode 100644 index 0000000000..e99e3cc7ef --- /dev/null +++ b/hw/misc/npcm7xx_pwm.c @@ -0,0 +1,550 @@ +/* + * Nuvoton NPCM7xx PWM Module + * + * Copyright 2020 Google LLC + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "qemu/osdep.h" +#include "hw/irq.h" +#include "hw/qdev-clock.h" +#include "hw/qdev-properties.h" +#include "hw/misc/npcm7xx_pwm.h" +#include "hw/registerfields.h" +#include "migration/vmstate.h" +#include "qemu/bitops.h" +#include "qemu/error-report.h" +#include "qemu/log.h" +#include "qemu/module.h" +#include "qemu/units.h" +#include "trace.h" + +REG32(NPCM7XX_PWM_PPR, 0x00); +REG32(NPCM7XX_PWM_CSR, 0x04); +REG32(NPCM7XX_PWM_PCR, 0x08); +REG32(NPCM7XX_PWM_CNR0, 0x0c); +REG32(NPCM7XX_PWM_CMR0, 0x10); +REG32(NPCM7XX_PWM_PDR0, 0x14); +REG32(NPCM7XX_PWM_CNR1, 0x18); +REG32(NPCM7XX_PWM_CMR1, 0x1c); +REG32(NPCM7XX_PWM_PDR1, 0x20); +REG32(NPCM7XX_PWM_CNR2, 0x24); +REG32(NPCM7XX_PWM_CMR2, 0x28); +REG32(NPCM7XX_PWM_PDR2, 0x2c); +REG32(NPCM7XX_PWM_CNR3, 0x30); +REG32(NPCM7XX_PWM_CMR3, 0x34); +REG32(NPCM7XX_PWM_PDR3, 0x38); +REG32(NPCM7XX_PWM_PIER, 0x3c); +REG32(NPCM7XX_PWM_PIIR, 0x40); +REG32(NPCM7XX_PWM_PWDR0, 0x44); +REG32(NPCM7XX_PWM_PWDR1, 0x48); +REG32(NPCM7XX_PWM_PWDR2, 0x4c); +REG32(NPCM7XX_PWM_PWDR3, 0x50); + +/* Register field definitions. */ +#define NPCM7XX_PPR(rv, index) extract32((rv), npcm7xx_ppr_base[index], 8) +#define NPCM7XX_CSR(rv, index) extract32((rv), npcm7xx_csr_base[index], 3) +#define NPCM7XX_CH(rv, index) extract32((rv), npcm7xx_ch_base[index], 4) +#define NPCM7XX_CH_EN BIT(0) +#define NPCM7XX_CH_INV BIT(2) +#define NPCM7XX_CH_MOD BIT(3) + +/* Offset of each PWM channel's prescaler in the PPR register. */ +static const int npcm7xx_ppr_base[] = { 0, 0, 8, 8 }; +/* Offset of each PWM channel's clock selector in the CSR register. */ +static const int npcm7xx_csr_base[] = { 0, 4, 8, 12 }; +/* Offset of each PWM channel's control variable in the PCR register. */ +static const int npcm7xx_ch_base[] = { 0, 8, 12, 16 }; + +static uint32_t npcm7xx_pwm_calculate_freq(NPCM7xxPWM *p) +{ + uint32_t ppr; + uint32_t csr; + uint32_t freq; + + if (!p->running) { + return 0; + } + + csr = NPCM7XX_CSR(p->module->csr, p->index); + ppr = NPCM7XX_PPR(p->module->ppr, p->index); + freq = clock_get_hz(p->module->clock); + freq /= ppr + 1; + /* csr can only be 0~4 */ + if (csr > 4) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid csr value %u\n", + __func__, csr); + csr = 4; + } + /* freq won't be changed if csr == 4. */ + if (csr < 4) { + freq >>= csr + 1; + } + + return freq / (p->cnr + 1); +} + +static uint32_t npcm7xx_pwm_calculate_duty(NPCM7xxPWM *p) +{ + uint64_t duty; + + if (p->running) { + if (p->cnr == 0) { + duty = 0; + } else if (p->cmr >= p->cnr) { + duty = NPCM7XX_PWM_MAX_DUTY; + } else { + duty = NPCM7XX_PWM_MAX_DUTY * (p->cmr + 1) / (p->cnr + 1); + } + } else { + duty = 0; + } + + if (p->inverted) { + duty = NPCM7XX_PWM_MAX_DUTY - duty; + } + + return duty; +} + +static void npcm7xx_pwm_update_freq(NPCM7xxPWM *p) +{ + uint32_t freq = npcm7xx_pwm_calculate_freq(p); + + if (freq != p->freq) { + trace_npcm7xx_pwm_update_freq(DEVICE(p->module)->canonical_path, + p->index, p->freq, freq); + p->freq = freq; + } +} + +static void npcm7xx_pwm_update_duty(NPCM7xxPWM *p) +{ + uint32_t duty = npcm7xx_pwm_calculate_duty(p); + + if (duty != p->duty) { + trace_npcm7xx_pwm_update_duty(DEVICE(p->module)->canonical_path, + p->index, p->duty, duty); + p->duty = duty; + } +} + +static void npcm7xx_pwm_update_output(NPCM7xxPWM *p) +{ + npcm7xx_pwm_update_freq(p); + npcm7xx_pwm_update_duty(p); +} + +static void npcm7xx_pwm_write_ppr(NPCM7xxPWMState *s, uint32_t new_ppr) +{ + int i; + uint32_t old_ppr = s->ppr; + + QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_ppr_base) != NPCM7XX_PWM_PER_MODULE); + s->ppr = new_ppr; + for (i = 0; i < NPCM7XX_PWM_PER_MODULE; ++i) { + if (NPCM7XX_PPR(old_ppr, i) != NPCM7XX_PPR(new_ppr, i)) { + npcm7xx_pwm_update_freq(&s->pwm[i]); + } + } +} + +static void npcm7xx_pwm_write_csr(NPCM7xxPWMState *s, uint32_t new_csr) +{ + int i; + uint32_t old_csr = s->csr; + + QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_csr_base) != NPCM7XX_PWM_PER_MODULE); + s->csr = new_csr; + for (i = 0; i < NPCM7XX_PWM_PER_MODULE; ++i) { + if (NPCM7XX_CSR(old_csr, i) != NPCM7XX_CSR(new_csr, i)) { + npcm7xx_pwm_update_freq(&s->pwm[i]); + } + } +} + +static void npcm7xx_pwm_write_pcr(NPCM7xxPWMState *s, uint32_t new_pcr) +{ + int i; + bool inverted; + uint32_t pcr; + NPCM7xxPWM *p; + + s->pcr = new_pcr; + QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_ch_base) != NPCM7XX_PWM_PER_MODULE); + for (i = 0; i < NPCM7XX_PWM_PER_MODULE; ++i) { + p = &s->pwm[i]; + pcr = NPCM7XX_CH(new_pcr, i); + inverted = pcr & NPCM7XX_CH_INV; + + /* + * We only run a PWM channel with toggle mode. Single-shot mode does not + * generate frequency and duty-cycle values. + */ + if ((pcr & NPCM7XX_CH_EN) && (pcr & NPCM7XX_CH_MOD)) { + if (p->running) { + /* Re-run this PWM channel if inverted changed. */ + if (p->inverted ^ inverted) { + p->inverted = inverted; + npcm7xx_pwm_update_duty(p); + } + } else { + /* Run this PWM channel. */ + p->running = true; + p->inverted = inverted; + npcm7xx_pwm_update_output(p); + } + } else { + /* Clear this PWM channel. */ + p->running = false; + p->inverted = inverted; + npcm7xx_pwm_update_output(p); + } + } + +} + +static hwaddr npcm7xx_cnr_index(hwaddr offset) +{ + switch (offset) { + case A_NPCM7XX_PWM_CNR0: + return 0; + case A_NPCM7XX_PWM_CNR1: + return 1; + case A_NPCM7XX_PWM_CNR2: + return 2; + case A_NPCM7XX_PWM_CNR3: + return 3; + default: + g_assert_not_reached(); + } +} + +static hwaddr npcm7xx_cmr_index(hwaddr offset) +{ + switch (offset) { + case A_NPCM7XX_PWM_CMR0: + return 0; + case A_NPCM7XX_PWM_CMR1: + return 1; + case A_NPCM7XX_PWM_CMR2: + return 2; + case A_NPCM7XX_PWM_CMR3: + return 3; + default: + g_assert_not_reached(); + } +} + +static hwaddr npcm7xx_pdr_index(hwaddr offset) +{ + switch (offset) { + case A_NPCM7XX_PWM_PDR0: + return 0; + case A_NPCM7XX_PWM_PDR1: + return 1; + case A_NPCM7XX_PWM_PDR2: + return 2; + case A_NPCM7XX_PWM_PDR3: + return 3; + default: + g_assert_not_reached(); + } +} + +static hwaddr npcm7xx_pwdr_index(hwaddr offset) +{ + switch (offset) { + case A_NPCM7XX_PWM_PWDR0: + return 0; + case A_NPCM7XX_PWM_PWDR1: + return 1; + case A_NPCM7XX_PWM_PWDR2: + return 2; + case A_NPCM7XX_PWM_PWDR3: + return 3; + default: + g_assert_not_reached(); + } +} + +static uint64_t npcm7xx_pwm_read(void *opaque, hwaddr offset, unsigned size) +{ + NPCM7xxPWMState *s = opaque; + uint64_t value = 0; + + switch (offset) { + case A_NPCM7XX_PWM_CNR0: + case A_NPCM7XX_PWM_CNR1: + case A_NPCM7XX_PWM_CNR2: + case A_NPCM7XX_PWM_CNR3: + value = s->pwm[npcm7xx_cnr_index(offset)].cnr; + break; + + case A_NPCM7XX_PWM_CMR0: + case A_NPCM7XX_PWM_CMR1: + case A_NPCM7XX_PWM_CMR2: + case A_NPCM7XX_PWM_CMR3: + value = s->pwm[npcm7xx_cmr_index(offset)].cmr; + break; + + case A_NPCM7XX_PWM_PDR0: + case A_NPCM7XX_PWM_PDR1: + case A_NPCM7XX_PWM_PDR2: + case A_NPCM7XX_PWM_PDR3: + value = s->pwm[npcm7xx_pdr_index(offset)].pdr; + break; + + case A_NPCM7XX_PWM_PWDR0: + case A_NPCM7XX_PWM_PWDR1: + case A_NPCM7XX_PWM_PWDR2: + case A_NPCM7XX_PWM_PWDR3: + value = s->pwm[npcm7xx_pwdr_index(offset)].pwdr; + break; + + case A_NPCM7XX_PWM_PPR: + value = s->ppr; + break; + + case A_NPCM7XX_PWM_CSR: + value = s->csr; + break; + + case A_NPCM7XX_PWM_PCR: + value = s->pcr; + break; + + case A_NPCM7XX_PWM_PIER: + value = s->pier; + break; + + case A_NPCM7XX_PWM_PIIR: + value = s->piir; + break; + + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid offset 0x%04" HWADDR_PRIx "\n", + __func__, offset); + break; + } + + trace_npcm7xx_pwm_read(DEVICE(s)->canonical_path, offset, value); + return value; +} + +static void npcm7xx_pwm_write(void *opaque, hwaddr offset, + uint64_t v, unsigned size) +{ + NPCM7xxPWMState *s = opaque; + NPCM7xxPWM *p; + uint32_t value = v; + + trace_npcm7xx_pwm_write(DEVICE(s)->canonical_path, offset, value); + switch (offset) { + case A_NPCM7XX_PWM_CNR0: + case A_NPCM7XX_PWM_CNR1: + case A_NPCM7XX_PWM_CNR2: + case A_NPCM7XX_PWM_CNR3: + p = &s->pwm[npcm7xx_cnr_index(offset)]; + p->cnr = value; + npcm7xx_pwm_update_output(p); + break; + + case A_NPCM7XX_PWM_CMR0: + case A_NPCM7XX_PWM_CMR1: + case A_NPCM7XX_PWM_CMR2: + case A_NPCM7XX_PWM_CMR3: + p = &s->pwm[npcm7xx_cmr_index(offset)]; + p->cmr = value; + npcm7xx_pwm_update_output(p); + break; + + case A_NPCM7XX_PWM_PDR0: + case A_NPCM7XX_PWM_PDR1: + case A_NPCM7XX_PWM_PDR2: + case A_NPCM7XX_PWM_PDR3: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: register @ 0x%04" HWADDR_PRIx " is read-only\n", + __func__, offset); + break; + + case A_NPCM7XX_PWM_PWDR0: + case A_NPCM7XX_PWM_PWDR1: + case A_NPCM7XX_PWM_PWDR2: + case A_NPCM7XX_PWM_PWDR3: + qemu_log_mask(LOG_UNIMP, + "%s: register @ 0x%04" HWADDR_PRIx " is not implemented\n", + __func__, offset); + break; + + case A_NPCM7XX_PWM_PPR: + npcm7xx_pwm_write_ppr(s, value); + break; + + case A_NPCM7XX_PWM_CSR: + npcm7xx_pwm_write_csr(s, value); + break; + + case A_NPCM7XX_PWM_PCR: + npcm7xx_pwm_write_pcr(s, value); + break; + + case A_NPCM7XX_PWM_PIER: + qemu_log_mask(LOG_UNIMP, + "%s: register @ 0x%04" HWADDR_PRIx " is not implemented\n", + __func__, offset); + break; + + case A_NPCM7XX_PWM_PIIR: + qemu_log_mask(LOG_UNIMP, + "%s: register @ 0x%04" HWADDR_PRIx " is not implemented\n", + __func__, offset); + break; + + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid offset 0x%04" HWADDR_PRIx "\n", + __func__, offset); + break; + } +} + +static const struct MemoryRegionOps npcm7xx_pwm_ops = { + .read = npcm7xx_pwm_read, + .write = npcm7xx_pwm_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + .unaligned = false, + }, +}; + +static void npcm7xx_pwm_enter_reset(Object *obj, ResetType type) +{ + NPCM7xxPWMState *s = NPCM7XX_PWM(obj); + int i; + + for (i = 0; i < NPCM7XX_PWM_PER_MODULE; i++) { + NPCM7xxPWM *p = &s->pwm[i]; + + p->cnr = 0x00000000; + p->cmr = 0x00000000; + p->pdr = 0x00000000; + p->pwdr = 0x00000000; + } + + s->ppr = 0x00000000; + s->csr = 0x00000000; + s->pcr = 0x00000000; + s->pier = 0x00000000; + s->piir = 0x00000000; +} + +static void npcm7xx_pwm_hold_reset(Object *obj) +{ + NPCM7xxPWMState *s = NPCM7XX_PWM(obj); + int i; + + for (i = 0; i < NPCM7XX_PWM_PER_MODULE; i++) { + qemu_irq_lower(s->pwm[i].irq); + } +} + +static void npcm7xx_pwm_init(Object *obj) +{ + NPCM7xxPWMState *s = NPCM7XX_PWM(obj); + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + int i; + + for (i = 0; i < NPCM7XX_PWM_PER_MODULE; i++) { + NPCM7xxPWM *p = &s->pwm[i]; + p->module = s; + p->index = i; + sysbus_init_irq(sbd, &p->irq); + } + + memory_region_init_io(&s->iomem, obj, &npcm7xx_pwm_ops, s, + TYPE_NPCM7XX_PWM, 4 * KiB); + sysbus_init_mmio(sbd, &s->iomem); + s->clock = qdev_init_clock_in(DEVICE(s), "clock", NULL, NULL); + + for (i = 0; i < NPCM7XX_PWM_PER_MODULE; ++i) { + object_property_add_uint32_ptr(obj, "freq[*]", + &s->pwm[i].freq, OBJ_PROP_FLAG_READ); + object_property_add_uint32_ptr(obj, "duty[*]", + &s->pwm[i].duty, OBJ_PROP_FLAG_READ); + } +} + +static const VMStateDescription vmstate_npcm7xx_pwm = { + .name = "npcm7xx-pwm", + .version_id = 0, + .minimum_version_id = 0, + .fields = (VMStateField[]) { + VMSTATE_BOOL(running, NPCM7xxPWM), + VMSTATE_BOOL(inverted, NPCM7xxPWM), + VMSTATE_UINT8(index, NPCM7xxPWM), + VMSTATE_UINT32(cnr, NPCM7xxPWM), + VMSTATE_UINT32(cmr, NPCM7xxPWM), + VMSTATE_UINT32(pdr, NPCM7xxPWM), + VMSTATE_UINT32(pwdr, NPCM7xxPWM), + VMSTATE_UINT32(freq, NPCM7xxPWM), + VMSTATE_UINT32(duty, NPCM7xxPWM), + VMSTATE_END_OF_LIST(), + }, +}; + +static const VMStateDescription vmstate_npcm7xx_pwm_module = { + .name = "npcm7xx-pwm-module", + .version_id = 0, + .minimum_version_id = 0, + .fields = (VMStateField[]) { + VMSTATE_CLOCK(clock, NPCM7xxPWMState), + VMSTATE_STRUCT_ARRAY(pwm, NPCM7xxPWMState, + NPCM7XX_PWM_PER_MODULE, 0, vmstate_npcm7xx_pwm, + NPCM7xxPWM), + VMSTATE_UINT32(ppr, NPCM7xxPWMState), + VMSTATE_UINT32(csr, NPCM7xxPWMState), + VMSTATE_UINT32(pcr, NPCM7xxPWMState), + VMSTATE_UINT32(pier, NPCM7xxPWMState), + VMSTATE_UINT32(piir, NPCM7xxPWMState), + VMSTATE_END_OF_LIST(), + }, +}; + +static void npcm7xx_pwm_class_init(ObjectClass *klass, void *data) +{ + ResettableClass *rc = RESETTABLE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->desc = "NPCM7xx PWM Controller"; + dc->vmsd = &vmstate_npcm7xx_pwm_module; + rc->phases.enter = npcm7xx_pwm_enter_reset; + rc->phases.hold = npcm7xx_pwm_hold_reset; +} + +static const TypeInfo npcm7xx_pwm_info = { + .name = TYPE_NPCM7XX_PWM, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(NPCM7xxPWMState), + .class_init = npcm7xx_pwm_class_init, + .instance_init = npcm7xx_pwm_init, +}; + +static void npcm7xx_pwm_register_type(void) +{ + type_register_static(&npcm7xx_pwm_info); +} +type_init(npcm7xx_pwm_register_type); diff --git a/hw/misc/trace-events b/hw/misc/trace-events index b5118acd3f..d626b9d7a7 100644 --- a/hw/misc/trace-events +++ b/hw/misc/trace-events @@ -120,6 +120,12 @@ npcm7xx_gcr_write(uint64_t offset, uint32_t value) "offset: 0x%04" PRIx64 " valu npcm7xx_rng_read(uint64_t offset, uint64_t value, unsigned size) "offset: 0x%04" PRIx64 " value: 0x%02" PRIx64 " size: %u" npcm7xx_rng_write(uint64_t offset, uint64_t value, unsigned size) "offset: 0x%04" PRIx64 " value: 0x%02" PRIx64 " size: %u" +# npcm7xx_pwm.c +npcm7xx_pwm_read(const char *id, uint64_t offset, uint32_t value) "%s offset: 0x%04" PRIx64 " value: 0x%08" PRIx32 +npcm7xx_pwm_write(const char *id, uint64_t offset, uint32_t value) "%s offset: 0x%04" PRIx64 " value: 0x%08" PRIx32 +npcm7xx_pwm_update_freq(const char *id, uint8_t index, uint32_t old_value, uint32_t new_value) "%s pwm[%u] Update Freq: old_freq: %u, new_freq: %u" +npcm7xx_pwm_update_duty(const char *id, uint8_t index, uint32_t old_value, uint32_t new_value) "%s pwm[%u] Update Duty: old_duty: %u, new_duty: %u" + # stm32f4xx_syscfg.c stm32f4xx_syscfg_set_irq(int gpio, int line, int level) "Interupt: GPIO: %d, Line: %d; Level: %d" stm32f4xx_pulse_exti(int irq) "Pulse EXTI: %d" |