1 /* 2 * Nuvoton NPCM7xx PWM Module 3 * 4 * Copyright 2020 Google LLC 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the 8 * Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * for more details. 15 */ 16 #ifndef NPCM7XX_PWM_H 17 #define NPCM7XX_PWM_H 18 19 #include "hw/clock.h" 20 #include "hw/sysbus.h" 21 #include "hw/irq.h" 22 23 /* Each PWM module holds 4 PWM channels. */ 24 #define NPCM7XX_PWM_PER_MODULE 4 25 26 /* 27 * Number of registers in one pwm module. Don't change this without increasing 28 * the version_id in vmstate. 29 */ 30 #define NPCM7XX_PWM_NR_REGS (0x54 / sizeof(uint32_t)) 31 32 /* 33 * The maximum duty values. Each duty unit represents 1/NPCM7XX_PWM_MAX_DUTY 34 * cycles. For example, if NPCM7XX_PWM_MAX_DUTY=1,000,000 and a PWM has a duty 35 * value of 100,000 the duty cycle for that PWM is 10%. 36 */ 37 #define NPCM7XX_PWM_MAX_DUTY 1000000 38 39 typedef struct NPCM7xxPWMState NPCM7xxPWMState; 40 41 /** 42 * struct NPCM7xxPWM - The state of a single PWM channel. 43 * @module: The PWM module that contains this channel. 44 * @irq: GIC interrupt line to fire on expiration if enabled. 45 * @running: Whether this PWM channel is generating output. 46 * @inverted: Whether this PWM channel is inverted. 47 * @index: The index of this PWM channel. 48 * @cnr: The counter register. 49 * @cmr: The comparator register. 50 * @pdr: The data register. 51 * @pwdr: The watchdog register. 52 * @freq: The frequency of this PWM channel. 53 * @duty: The duty cycle of this PWM channel. One unit represents 54 * 1/NPCM7XX_MAX_DUTY cycles. 55 */ 56 typedef struct NPCM7xxPWM { 57 NPCM7xxPWMState *module; 58 59 qemu_irq irq; 60 61 bool running; 62 bool inverted; 63 64 uint8_t index; 65 uint32_t cnr; 66 uint32_t cmr; 67 uint32_t pdr; 68 uint32_t pwdr; 69 70 uint32_t freq; 71 uint32_t duty; 72 } NPCM7xxPWM; 73 74 /** 75 * struct NPCM7xxPWMState - Pulse Width Modulation device state. 76 * @parent: System bus device. 77 * @iomem: Memory region through which registers are accessed. 78 * @clock: The PWM clock. 79 * @pwm: The PWM channels owned by this module. 80 * @ppr: The prescaler register. 81 * @csr: The clock selector register. 82 * @pcr: The control register. 83 * @pier: The interrupt enable register. 84 * @piir: The interrupt indication register. 85 */ 86 struct NPCM7xxPWMState { 87 SysBusDevice parent; 88 89 MemoryRegion iomem; 90 91 Clock *clock; 92 NPCM7xxPWM pwm[NPCM7XX_PWM_PER_MODULE]; 93 94 uint32_t ppr; 95 uint32_t csr; 96 uint32_t pcr; 97 uint32_t pier; 98 uint32_t piir; 99 }; 100 101 #define TYPE_NPCM7XX_PWM "npcm7xx-pwm" 102 #define NPCM7XX_PWM(obj) \ 103 OBJECT_CHECK(NPCM7xxPWMState, (obj), TYPE_NPCM7XX_PWM) 104 105 #endif /* NPCM7XX_PWM_H */ 106