ITE drivers/pwm: add PWM for it8xxx2

Add pulse width modulator (PWM) for it8xxx2.

Signed-off-by: Ruibin Chang <ruibin.chang@ite.com.tw>
This commit is contained in:
Ruibin Chang 2021-06-07 15:21:22 +08:00 committed by Anas Nashif
commit d0ce9bb877
13 changed files with 601 additions and 45 deletions

View file

@ -275,6 +275,7 @@
/drivers/pwm/pwm_capture.c @henrikbrixandersen
/drivers/pwm/pwm_shell.c @henrikbrixandersen
/drivers/pwm/*gecko* @sun681
/drivers/pwm/*it8xxx2* @RuibinChang
/drivers/sensor/ @MaureenHelm
/drivers/sensor/ams_iAQcore/ @alexanderwachter
/drivers/sensor/ens210/ @alexanderwachter
@ -471,6 +472,7 @@
/include/dt-bindings/dma/stm32_dma.h @cybertale
/include/dt-bindings/ethernet/xlnx_gem.h @ibirnbaum
/include/dt-bindings/pcie/ @dcpleung
/include/dt-bindings/pwm/*it8xxx2* @RuibinChang
/include/dt-bindings/usb/usb.h @galak
/include/drivers/emul.h @sjg20
/include/fs/ @nashif @nvlsianpu @de-nordic

View file

@ -11,6 +11,12 @@
/ {
model = "IT8XXX2 EV-Board";
compatible = "riscv,it8xxx2-evb";
aliases {
pwm-led0 = &led0;
pwm-led1 = &led1;
};
chosen {
zephyr,console = &uart1;
zephyr,shell-uart = &uart1;
@ -20,6 +26,19 @@
zephyr,flash-controller = &flashctrl;
zephyr,code-partition = &slot0_partition;
};
pwmleds {
compatible = "pwm-leds";
/* NOTE: &pwm number needs same with channel number */
led0: led_0 {
pwms = <&pwm7 PWM_CHANNEL_7 PWM_POLARITY_INVERTED>;
label = "LED0_GREEN";
};
led1: led_1 {
pwms = <&pwm0 PWM_CHANNEL_0 PWM_POLARITY_NORMAL>;
label = "LED1_BLUE";
};
};
};
&adc0 {
status = "okay";
@ -58,6 +77,20 @@
current-speed = <460800>;
clock-frequency = <1804800>;
};
&pwm0 {
status = "okay";
prescaler-cx = <PWM_PRESCALER_C6>;
/*
* If we need pwm output in ITE chip power saving mode,
* then we should set frequency <=324Hz.
*/
pwm-output-frequency = <324>;
};
&pwm7 {
status = "okay";
prescaler-cx = <PWM_PRESCALER_C4>;
pwm-output-frequency = <30000>;
};
&flash0 {
partitions {
compatible = "fixed-partitions";

View file

@ -32,3 +32,5 @@ CONFIG_I2C=y
CONFIG_I2C_ITE_IT8XXX2=y
CONFIG_ADC_ITE_IT8XXX2=y
CONFIG_SOC_FLASH_ITE_IT8XXX2=y
CONFIG_PWM=y
CONFIG_PWM_ITE_IT8XXX2=y

View file

@ -8,6 +8,7 @@ zephyr_library_sources_ifdef(CONFIG_PWM_NRF5_SW pwm_nrf5_sw.c)
zephyr_library_sources_ifdef(CONFIG_PWM_NRFX pwm_nrfx.c)
zephyr_library_sources_ifdef(CONFIG_PWM_MCUX_FTM pwm_mcux_ftm.c)
zephyr_library_sources_ifdef(CONFIG_PWM_IMX pwm_imx.c)
zephyr_library_sources_ifdef(CONFIG_PWM_ITE_IT8XXX2 pwm_ite_it8xxx2.c)
zephyr_library_sources_ifdef(CONFIG_PWM_LED_ESP32 pwm_led_esp32.c)
zephyr_library_sources_ifdef(CONFIG_PWM_SAM pwm_sam.c)
zephyr_library_sources_ifdef(CONFIG_PWM_MCUX pwm_mcux.c)

View file

@ -39,6 +39,8 @@ source "drivers/pwm/Kconfig.mcux_ftm"
source "drivers/pwm/Kconfig.imx"
source "drivers/pwm/Kconfig.it8xxx2"
source "drivers/pwm/Kconfig.esp32"
source "drivers/pwm/Kconfig.sam"

View file

@ -0,0 +1,12 @@
# IT8XXX2 PWM configuration options
# Copyright (c) 2021 ITE Corporation. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
config PWM_ITE_IT8XXX2
bool "ITE IT8XXX2 embedded controller (EC) PWM driver"
depends on SOC_IT8XXX2
help
Enable PWM driver for it8xxx2_evb.
Supports three 16-bit prescalers each with 8-bit cycle timer, and
eight PWM channels each with 8-bit duty cycle.

View file

@ -0,0 +1,265 @@
/*
* Copyright (c) 2021 ITE Corporation. All Rights Reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT ite_it8xxx2_pwm
#include <device.h>
#include <drivers/pwm.h>
#include <drivers/pinmux.h>
#include <dt-bindings/pwm/it8xxx2_pwm.h>
#include <errno.h>
#include <kernel.h>
#include <soc.h>
#include <stdlib.h>
#include <logging/log.h>
LOG_MODULE_REGISTER(pwm_ite_it8xxx2, CONFIG_PWM_LOG_LEVEL);
#define PWM_CTRX_MIN 100
#define PWM_EC_FREQ MHZ(8)
#define PCSSG_MASK 0x3
/* Device config */
struct pwm_it8xxx2_cfg {
/* PWM channel duty cycle register */
uintptr_t reg_dcr;
/* PWM channel clock source selection register */
uintptr_t reg_pcssg;
/* PWM channel clock source gating register */
uintptr_t reg_pcsgr;
/* PWM channel output polarity register */
uintptr_t reg_pwmpol;
/* PWM channel */
int channel;
/* PWM prescaler control register base */
uintptr_t base;
/* Select PWM prescaler that output to PWM channel */
int prs_sel;
/* Pinmux control device structure */
const struct device *pinctrls;
/* GPIO pin */
uint8_t pin;
/* Alternate function */
uint8_t alt_fun;
};
/* Driver convenience defines */
#define DRV_CONFIG(dev) ((const struct pwm_it8xxx2_cfg * const)(dev)->config)
#define DRV_REG(dev) (struct pwm_it8xxx2_regs *)(DRV_CONFIG(dev)->base)
#define DEV_PINMUX(inst) \
DEVICE_DT_GET(DT_PHANDLE_BY_IDX(DT_NODELABEL(pinctrl_pwm##inst), pinctrls, 0))
#define DEV_PIN(inst) \
DT_PHA(DT_PHANDLE_BY_IDX(DT_DRV_INST(inst), pinctrl_0, 0), pinctrls, pin)
#define DEV_ALT_FUN(inst) \
DT_PHA(DT_PHANDLE_BY_IDX(DT_DRV_INST(inst), pinctrl_0, 0), pinctrls, alt_func)
static void pwm_enable(const struct device *dev, int enabled)
{
const struct pwm_it8xxx2_cfg *config = DRV_CONFIG(dev);
volatile uint8_t *reg_pcsgr = (uint8_t *)config->reg_pcsgr;
int ch = config->channel;
if (enabled)
/* PWM channel clock source not gating */
*reg_pcsgr &= ~BIT(ch);
else
/* PWM channel clock source gating */
*reg_pcsgr |= BIT(ch);
}
static int pwm_it8xxx2_get_cycles_per_sec(const struct device *dev,
uint32_t pwm, uint64_t *cycles)
{
const struct pwm_it8xxx2_cfg *config = DRV_CONFIG(dev);
struct pwm_it8xxx2_regs *const inst = DRV_REG(dev);
int prs_sel = config->prs_sel;
ARG_UNUSED(pwm);
/* Get clock source cycles per second that output to prescaler */
if ((inst->PCFSR) & BIT(prs_sel))
*cycles = (uint64_t) PWM_EC_FREQ;
else
*cycles = (uint64_t) 32768;
return 0;
}
static int pwm_it8xxx2_pin_set(const struct device *dev,
uint32_t pwm, uint32_t period_cycles,
uint32_t pulse_cycles, pwm_flags_t flags)
{
const struct pwm_it8xxx2_cfg *config = DRV_CONFIG(dev);
struct pwm_it8xxx2_regs *const inst = DRV_REG(dev);
volatile uint8_t *reg_dcr = (uint8_t *)config->reg_dcr;
volatile uint8_t *reg_pwmpol = (uint8_t *)config->reg_pwmpol;
int ch = config->channel;
int prs_sel = config->prs_sel;
uint32_t actual_freq = 0xffffffff, target_freq, deviation, cxcprs, ctr;
uint64_t pwm_clk_src;
ARG_UNUSED(pwm);
if (pulse_cycles > period_cycles)
return -EINVAL;
/* PWM channel clock source gating before configuring */
pwm_enable(dev, 0);
/* Select PWM inverted polarity (ex. active-low pulse) */
if (flags & PWM_POLARITY_INVERTED)
*reg_pwmpol |= BIT(ch);
else
*reg_pwmpol &= ~BIT(ch);
/* If pulse cycles is 0, set duty cycle 0 and enable pwm channel */
if (pulse_cycles == 0) {
*reg_dcr = 0;
pwm_enable(dev, 1);
return 0;
}
pwm_it8xxx2_get_cycles_per_sec(dev, pwm, &pwm_clk_src);
target_freq = ((uint32_t) pwm_clk_src) / period_cycles;
deviation = (target_freq / 100) + 1;
/*
* Default clock source setting is 8MHz, when ITE chip is in power
* saving mode, clock source 8MHz will be gated (32.768KHz won't).
* So if we still need pwm output in mode, then we should set frequency
* <=324Hz in board dts. Now change prescaler clock source from 8MHz to
* 32.768KHz to support pwm output in mode.
* NOTE: PWM output signal maximum supported frequency 324Hz comes from
* 32768 / (PWM_CTRX_MIN + 1).
*/
if ((target_freq <= 324) && (inst->PCFSR & BIT(prs_sel))) {
inst->PCFSR &= ~BIT(prs_sel);
pwm_clk_src = (uint64_t) 32768;
}
/*
* PWM output signal frequency is
* pwm_clk_src / ((CxCPRS[15:0] + 1) * (CTRx[7:0] + 1))
* NOTE: 1) define CTR minimum is 100 for more precisely when
* calculate DCR
* 2) CxCPRS[15:0] value 0001h results in a divisor 2
* CxCPRS[15:0] value FFFFh results in a divisor 65536
* CTRx[7:0] value 00h results in a divisor 1
* CTRx[7:0] value FFh results in a divisor 256
*/
for (ctr = 0xFF; ctr >= PWM_CTRX_MIN; ctr--) {
cxcprs = (((uint32_t) pwm_clk_src) / (ctr + 1) / target_freq) - 1;
if (cxcprs >= 0) {
actual_freq = ((uint32_t) pwm_clk_src) / (ctr + 1) / (cxcprs + 1);
if (abs(actual_freq - target_freq) < deviation)
break;
}
}
if (cxcprs > UINT16_MAX) {
LOG_ERR("PWM prescaler CxCPRS only support 2 bytes !");
return -EINVAL;
}
/* Set PWM prescaler clock divide and cycle time register */
if (prs_sel == PWM_PRESCALER_C4) {
inst->C4CPRS = cxcprs & 0xFF;
inst->C4MCPRS = (cxcprs >> 8) & 0xFF;
inst->CTR1 = ctr;
} else if (prs_sel == PWM_PRESCALER_C6) {
inst->C6CPRS = cxcprs & 0xFF;
inst->C6MCPRS = (cxcprs >> 8) & 0xFF;
inst->CTR2 = ctr;
} else if (prs_sel == PWM_PRESCALER_C7) {
inst->C7CPRS = cxcprs & 0xFF;
inst->C7MCPRS = (cxcprs >> 8) & 0xFF;
inst->CTR3 = ctr;
}
/* Set PWM channel duty cycle register */
*reg_dcr = (ctr * pulse_cycles) / period_cycles;
/* PWM channel clock source not gating */
pwm_enable(dev, 1);
LOG_DBG("clock source freq %d, target freq %d",
(uint32_t) pwm_clk_src, target_freq);
return 0;
}
static int pwm_it8xxx2_init(const struct device *dev)
{
const struct pwm_it8xxx2_cfg *config = DRV_CONFIG(dev);
struct pwm_it8xxx2_regs *const inst = DRV_REG(dev);
volatile uint8_t *reg_pcssg = (uint8_t *)config->reg_pcssg;
int ch = config->channel;
int prs_sel = config->prs_sel;
int pcssg_shift;
int pcssg_mask;
/* PWM channel clock source gating before configuring */
pwm_enable(dev, 0);
/* Select clock source 8MHz for prescaler */
inst->PCFSR |= BIT(prs_sel);
/* Bit shift and mask of prescaler clock source select group register */
pcssg_shift = (ch % 4) * 2;
pcssg_mask = (prs_sel & PCSSG_MASK) << pcssg_shift;
/* Select which prescaler output to PWM channel */
*reg_pcssg &= ~(PCSSG_MASK << pcssg_shift);
*reg_pcssg |= pcssg_mask;
/*
* The cycle timer1 of it8320 later series was enhanced from
* 8bits to 10bits resolution, and others are still 8bit resolution.
* Because the cycle timer1 high byte default value is not zero,
* we clear cycle timer1 high byte at init and use it as 8-bit
* resolution like others.
*/
inst->CTR1M = 0;
/* Enable PWMs clock counter */
inst->ZTIER |= IT8XXX2_PWM_PCCE;
/* Set alternate mode of PWM pin */
pinmux_pin_set(config->pinctrls, config->pin, config->alt_fun);
return 0;
}
static const struct pwm_driver_api pwm_it8xxx2_api = {
.pin_set = pwm_it8xxx2_pin_set,
.get_cycles_per_sec = pwm_it8xxx2_get_cycles_per_sec,
};
/* Device Instance */
#define PWM_IT8XXX2_INIT(inst) \
static const struct pwm_it8xxx2_cfg pwm_it8xxx2_cfg_##inst = { \
.reg_dcr = DT_INST_REG_ADDR_BY_IDX(inst, 0), \
.reg_pcssg = DT_INST_REG_ADDR_BY_IDX(inst, 1), \
.reg_pcsgr = DT_INST_REG_ADDR_BY_IDX(inst, 2), \
.reg_pwmpol = DT_INST_REG_ADDR_BY_IDX(inst, 3), \
.channel = DT_PROP(DT_INST(inst, ite_it8xxx2_pwm), channel), \
.base = DT_REG_ADDR(DT_NODELABEL(prs)), \
.prs_sel = DT_PROP(DT_INST(inst, ite_it8xxx2_pwm), prescaler_cx), \
.pinctrls = DEV_PINMUX(inst), \
.pin = DEV_PIN(inst), \
.alt_fun = DEV_ALT_FUN(inst), \
}; \
\
DEVICE_DT_INST_DEFINE(inst, \
&pwm_it8xxx2_init, \
NULL, \
NULL, \
&pwm_it8xxx2_cfg_##inst, \
PRE_KERNEL_1, \
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \
&pwm_it8xxx2_api);
DT_INST_FOREACH_STATUS_OKAY(PWM_IT8XXX2_INIT)

View file

@ -0,0 +1,58 @@
# Copyright (c) 2021 ITE Corporation. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
description: ITE, it8xxx2 Pulse Width Modulator (PWM) node
compatible: "ite,it8xxx2-pwm"
include: [pwm-controller.yaml, base.yaml]
properties:
reg:
required: true
label:
required: true
interrupts:
required: false
channel:
type: int
required: true
enum:
- 0 #PWM_CHANNEL_0
- 1 #PWM_CHANNEL_1
- 2 #PWM_CHANNEL_2
- 3 #PWM_CHANNEL_3
- 4 #PWM_CHANNEL_4
- 5 #PWM_CHANNEL_5
- 6 #PWM_CHANNEL_6
- 7 #PWM_CHANNEL_7
pwmctrl:
type: phandle
required: true
description: PWM prescaler controller
pinctrl-0:
type: phandle
required: true
description: configuration of PWM pinmux controller
prescaler-cx:
type: int
required: true
enum:
- 1 #PWM_PRESCALER_C4
- 2 #PWM_PRESCALER_C6
- 3 #PWM_PRESCALER_C7
pwm-output-frequency:
type: int
required: false
description: PWM output frequency for operation
pwm-cells:
- channel
- flags

View file

@ -0,0 +1,18 @@
# Copyright (c) 2021 ITE Corporation. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
description: ITE, it8xxx2 PWM prescaler node
compatible: "ite,it8xxx2-pwmprs"
include: base.yaml
properties:
reg:
required: true
label:
required: true
interrupts:
required: false

View file

@ -36,5 +36,30 @@
pinctrls = <&pinmuxi 7 IT8XXX2_PINMUX_FUNC_1>;
};
/* PWM alternate function */
pinctrl_pwm0: pwm0 {
pinctrls = <&pinmuxa 0 IT8XXX2_PINMUX_FUNC_1>;
};
pinctrl_pwm1: pwm1 {
pinctrls = <&pinmuxa 1 IT8XXX2_PINMUX_FUNC_1>;
};
pinctrl_pwm2: pwm2 {
pinctrls = <&pinmuxa 2 IT8XXX2_PINMUX_FUNC_1>;
};
pinctrl_pwm3: pwm3 {
pinctrls = <&pinmuxa 3 IT8XXX2_PINMUX_FUNC_1>;
};
pinctrl_pwm4: pwm4 {
pinctrls = <&pinmuxa 4 IT8XXX2_PINMUX_FUNC_1>;
};
pinctrl_pwm5: pwm5 {
pinctrls = <&pinmuxa 5 IT8XXX2_PINMUX_FUNC_1>;
};
pinctrl_pwm6: pwm6 {
pinctrls = <&pinmuxa 6 IT8XXX2_PINMUX_FUNC_1>;
};
pinctrl_pwm7: pwm7 {
pinctrls = <&pinmuxa 7 IT8XXX2_PINMUX_FUNC_1>;
};
};
};

View file

@ -9,6 +9,8 @@
#include <dt-bindings/interrupt-controller/ite-intc.h>
#include <dt-bindings/i2c/i2c.h>
#include <dt-bindings/pinctrl/it8xxx2-pinctrl.h>
#include <dt-bindings/pwm/pwm.h>
#include <dt-bindings/pwm/it8xxx2_pwm.h>
#include "it8xxx2-alts-map.dtsi"
/ {
@ -664,5 +666,114 @@
reg-names = "ecpm";
label = "EC_PM";
};
prs: pwmprs@f01800 {
compatible = "ite,it8xxx2-pwmprs";
reg = <0x00f01800 1>;
label = "prescaler";
};
pwm0: pwm@f01802 {
compatible = "ite,it8xxx2-pwm";
reg = <0x00f01802 1 /* DCR */
0x00f0180c 1 /* PCSSG */
0x00f0180f 1 /* PCSG */
0x00f0180a 1>; /* PWMPOL */
channel = <PWM_CHANNEL_0>;
label = "pwm_0";
status = "disabled";
pwmctrl = <&prs>;
pinctrl-0 = <&pinctrl_pwm0>; /* GPA0 */
#pwm-cells = <2>;
};
pwm1: pwm@f01803 {
compatible = "ite,it8xxx2-pwm";
reg = <0x00f01803 1 /* DCR */
0x00f0180c 1 /* PCSSG */
0x00f0180f 1 /* PCSG */
0x00f0180a 1>; /* PWMPOL */
channel = <PWM_CHANNEL_1>;
label = "pwm_1";
status = "disabled";
pwmctrl = <&prs>;
pinctrl-0 = <&pinctrl_pwm1>; /* GPA1 */
#pwm-cells = <2>;
};
pwm2: pwm@f01804 {
compatible = "ite,it8xxx2-pwm";
reg = <0x00f01804 1 /* DCR */
0x00f0180c 1 /* PCSSG */
0x00f0180f 1 /* PCSG */
0x00f0180a 1>; /* PWMPOL */
channel = <PWM_CHANNEL_2>;
label = "pwm_2";
status = "disabled";
pwmctrl = <&prs>;
pinctrl-0 = <&pinctrl_pwm2>; /* GPA2 */
#pwm-cells = <2>;
};
pwm3: pwm@f01805 {
compatible = "ite,it8xxx2-pwm";
reg = <0x00f01805 1 /* DCR */
0x00f0180c 1 /* PCSSG */
0x00f0180f 1 /* PCSG */
0x00f0180a 1>; /* PWMPOL */
channel = <PWM_CHANNEL_3>;
label = "pwm_3";
status = "disabled";
pwmctrl = <&prs>;
pinctrl-0 = <&pinctrl_pwm3>; /* GPA3 */
#pwm-cells = <2>;
};
pwm4: pwm@f01806 {
compatible = "ite,it8xxx2-pwm";
reg = <0x00f01806 1 /* DCR */
0x00f0180d 1 /* PCSSG */
0x00f0180f 1 /* PCSG */
0x00f0180a 1>; /* PWMPOL */
channel = <PWM_CHANNEL_4>;
label = "pwm_4";
status = "disabled";
pwmctrl = <&prs>;
pinctrl-0 = <&pinctrl_pwm4>; /* GPA4 */
#pwm-cells = <2>;
};
pwm5: pwm@f01807 {
compatible = "ite,it8xxx2-pwm";
reg = <0x00f01807 1 /* DCR */
0x00f0180d 1 /* PCSSG */
0x00f0180f 1 /* PCSG */
0x00f0180a 1>; /* PWMPOL */
channel = <PWM_CHANNEL_5>;
label = "pwm_5";
status = "disabled";
pwmctrl = <&prs>;
pinctrl-0 = <&pinctrl_pwm5>; /* GPA5 */
#pwm-cells = <2>;
};
pwm6: pwm@f01808 {
compatible = "ite,it8xxx2-pwm";
reg = <0x00f01808 1 /* DCR */
0x00f0180d 1 /* PCSSG */
0x00f0180f 1 /* PCSG */
0x00f0180a 1>; /* PWMPOL */
channel = <PWM_CHANNEL_6>;
label = "pwm_6";
status = "disabled";
pwmctrl = <&prs>;
pinctrl-0 = <&pinctrl_pwm6>; /* GPA6 */
#pwm-cells = <2>;
};
pwm7: pwm@f01809 {
compatible = "ite,it8xxx2-pwm";
reg = <0x00f01809 1 /* DCR */
0x00f0180d 1 /* PCSSG */
0x00f0180f 1 /* PCSG */
0x00f0180a 1>; /* PWMPOL */
channel = <PWM_CHANNEL_7>;
label = "pwm_7";
status = "disabled";
pwmctrl = <&prs>;
pinctrl-0 = <&pinctrl_pwm7>; /* GPA7 */
#pwm-cells = <2>;
};
};
};

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 2021 ITE Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PWM_IT8XXX2_H_
#define ZEPHYR_INCLUDE_DT_BINDINGS_PWM_IT8XXX2_H_
/* PWM prescaler references */
#define PWM_PRESCALER_C4 1
#define PWM_PRESCALER_C6 2
#define PWM_PRESCALER_C7 3
/* PWM channel references */
#define PWM_CHANNEL_0 0
#define PWM_CHANNEL_1 1
#define PWM_CHANNEL_2 2
#define PWM_CHANNEL_3 3
#define PWM_CHANNEL_4 4
#define PWM_CHANNEL_5 5
#define PWM_CHANNEL_6 6
#define PWM_CHANNEL_7 7
#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PWM_IT8XXX2_H_ */

View file

@ -739,51 +739,54 @@
* (18xxh) PWM & SmartAuto Fan Control (PWM)
*
*/
#define C0CPRS ECREG(EC_REG_BASE_ADDR + 0x1800)
#define CTR ECREG(EC_REG_BASE_ADDR + 0x1801)
#define DCR0 ECREG(EC_REG_BASE_ADDR + 0x1802)
#define DCR1 ECREG(EC_REG_BASE_ADDR + 0x1803)
#define DCR2 ECREG(EC_REG_BASE_ADDR + 0x1804)
#define DCR3 ECREG(EC_REG_BASE_ADDR + 0x1805)
#define DCR4 ECREG(EC_REG_BASE_ADDR + 0x1806)
#define DCR5 ECREG(EC_REG_BASE_ADDR + 0x1807)
#define DCR6 ECREG(EC_REG_BASE_ADDR + 0x1808)
#define DCR7 ECREG(EC_REG_BASE_ADDR + 0x1809)
#define PWMPOL ECREG(EC_REG_BASE_ADDR + 0x180A)
#define PCFSR ECREG(EC_REG_BASE_ADDR + 0x180B)
#define PCSSGL ECREG(EC_REG_BASE_ADDR + 0x180C)
#define PCSSGH ECREG(EC_REG_BASE_ADDR + 0x180D)
#define CR256PCSSG ECREG(EC_REG_BASE_ADDR + 0x180E)
#define PCSGR ECREG(EC_REG_BASE_ADDR + 0x180F)
#define F1TLRR ECREG(EC_REG_BASE_ADDR + 0x181E)
#define F1TMRR ECREG(EC_REG_BASE_ADDR + 0x181F)
#define F2TLRR ECREG(EC_REG_BASE_ADDR + 0x1820)
#define F2TMRR ECREG(EC_REG_BASE_ADDR + 0x1821)
#define ZINTSCR ECREG(EC_REG_BASE_ADDR + 0x1822)
#define ZTIER ECREG(EC_REG_BASE_ADDR + 0x1823)
#define TSWCTLR ECREG(EC_REG_BASE_ADDR + 0x1824)
#define C4CPRS ECREG(EC_REG_BASE_ADDR + 0x1827)
#define C4MCPRS ECREG(EC_REG_BASE_ADDR + 0x1828)
#define C6CPRS ECREG(EC_REG_BASE_ADDR + 0x182B)
#define C6MCPRS ECREG(EC_REG_BASE_ADDR + 0x182C)
#define C7CPRS ECREG(EC_REG_BASE_ADDR + 0x182D)
#define C7MCPRS ECREG(EC_REG_BASE_ADDR + 0x182E)
#define CLK6MSEL ECREG(EC_REG_BASE_ADDR + 0x1840)
#define CTR1 ECREG(EC_REG_BASE_ADDR + 0x1841)
#define CTR2 ECREG(EC_REG_BASE_ADDR + 0x1842)
#define CTR3 ECREG(EC_REG_BASE_ADDR + 0x1843)
#define PWM5TOCTRL ECREG(EC_REG_BASE_ADDR + 0x1844)
#define CFLRR ECREG(EC_REG_BASE_ADDR + 0x1845)
#define CFMRR ECREG(EC_REG_BASE_ADDR + 0x1846)
#define CFINTCTRL ECREG(EC_REG_BASE_ADDR + 0x1847)
#define TSWCTRL ECREG(EC_REG_BASE_ADDR + 0x1848)
#define PWMODENR ECREG(EC_REG_BASE_ADDR + 0x1849)
#define PWM0LHE ECREG(EC_REG_BASE_ADDR + 0x1850)
#define PWM0LCR1 ECREG(EC_REG_BASE_ADDR + 0x1851)
#define PWM0LCR2 ECREG(EC_REG_BASE_ADDR + 0x1852)
#define PWM1LHE ECREG(EC_REG_BASE_ADDR + 0x1853)
#define PWM1LCR1 ECREG(EC_REG_BASE_ADDR + 0x1854)
#define PWM1LCR2 ECREG(EC_REG_BASE_ADDR + 0x1855)
#ifndef __ASSEMBLER__
struct pwm_it8xxx2_regs {
/* 0x000: Channel0 Clock Prescaler */
volatile uint8_t C0CPRS;
/* 0x001: Cycle Time0 */
volatile uint8_t CTR;
/* 0x002~0x00A: Reserved1 */
volatile uint8_t Reserved1[9];
/* 0x00B: Prescaler Clock Frequency Select */
volatile uint8_t PCFSR;
/* 0x00C~0x00F: Reserved2 */
volatile uint8_t Reserved2[4];
/* 0x010: Cycle Time1 MSB */
volatile uint8_t CTR1M;
/* 0x011~0x022: Reserved3 */
volatile uint8_t Reserved3[18];
/* 0x023: PWM Clock Control */
volatile uint8_t ZTIER;
/* 0x024~0x026: Reserved4 */
volatile uint8_t Reserved4[3];
/* 0x027: Channel4 Clock Prescaler */
volatile uint8_t C4CPRS;
/* 0x028: Channel4 Clock Prescaler MSB */
volatile uint8_t C4MCPRS;
/* 0x029~0x02A: Reserved5 */
volatile uint8_t Reserved5[2];
/* 0x02B: Channel6 Clock Prescaler */
volatile uint8_t C6CPRS;
/* 0x02C: Channel6 Clock Prescaler MSB */
volatile uint8_t C6MCPRS;
/* 0x02D: Channel7 Clock Prescaler */
volatile uint8_t C7CPRS;
/* 0x02E: Channel7 Clock Prescaler MSB */
volatile uint8_t C7MCPRS;
/* 0x02F~0x040: Reserved6 */
volatile uint8_t reserved6[18];
/* 0x041: Cycle Time1 */
volatile uint8_t CTR1;
/* 0x042: Cycle Time2 */
volatile uint8_t CTR2;
/* 0x043: Cycle Time3 */
volatile uint8_t CTR3;
};
#endif /* !__ASSEMBLER__ */
/* PWM register fields */
/* 0x023: PWM Clock Control */
#define IT8XXX2_PWM_PCCE BIT(1)
/**
*