Commit a1867f85 authored by Min Li's avatar Min Li Committed by Lee Jones

mfd: Add Renesas Synchronization Management Unit (SMU) support

Add support for ClockMatrix(TM) and 82P33xxx families of timing
and synchronization devices. The access interface can be either
SPI or I2C. Currently, it will create 2 types of MFD devices,
which are to be used by the corresponding rsmu character device
driver and the PTP hardware clock driver, respectively.
Signed-off-by: default avatarMin Li <min.li.xe@renesas.com>
Signed-off-by: default avatarLee Jones <lee.jones@linaro.org>
parent e73f0f0e
...@@ -2183,5 +2183,33 @@ config MFD_INTEL_M10_BMC ...@@ -2183,5 +2183,33 @@ config MFD_INTEL_M10_BMC
additional drivers must be enabled in order to use the functionality additional drivers must be enabled in order to use the functionality
of the device. of the device.
config MFD_RSMU_I2C
tristate "Renesas Synchronization Management Unit with I2C"
depends on I2C && OF
select MFD_CORE
select REGMAP_I2C
help
Support for the Renesas Synchronization Management Unit, such as
Clockmatrix and 82P33XXX series. This option supports I2C as
the control interface.
This driver provides common support for accessing the device.
Additional drivers must be enabled in order to use the functionality
of the device.
config MFD_RSMU_SPI
tristate "Renesas Synchronization Management Unit with SPI"
depends on SPI && OF
select MFD_CORE
select REGMAP_SPI
help
Support for the Renesas Synchronization Management Unit, such as
Clockmatrix and 82P33XXX series. This option supports SPI as
the control interface.
This driver provides common support for accessing the device.
Additional drivers must be enabled in order to use the functionality
of the device.
endmenu endmenu
endif endif
...@@ -272,3 +272,8 @@ obj-$(CONFIG_MFD_INTEL_M10_BMC) += intel-m10-bmc.o ...@@ -272,3 +272,8 @@ obj-$(CONFIG_MFD_INTEL_M10_BMC) += intel-m10-bmc.o
obj-$(CONFIG_MFD_ATC260X) += atc260x-core.o obj-$(CONFIG_MFD_ATC260X) += atc260x-core.o
obj-$(CONFIG_MFD_ATC260X_I2C) += atc260x-i2c.o obj-$(CONFIG_MFD_ATC260X_I2C) += atc260x-i2c.o
rsmu-i2c-objs := rsmu_core.o rsmu_i2c.o
rsmu-spi-objs := rsmu_core.o rsmu_spi.o
obj-$(CONFIG_MFD_RSMU_I2C) += rsmu-i2c.o
obj-$(CONFIG_MFD_RSMU_SPI) += rsmu-spi.o
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Renesas Synchronization Management Unit (SMU) devices.
*
* Copyright (C) 2021 Integrated Device Technology, Inc., a Renesas Company.
*/
#ifndef __RSMU_MFD_H
#define __RSMU_MFD_H
#include <linux/mfd/rsmu.h>
int rsmu_core_init(struct rsmu_ddata *rsmu);
void rsmu_core_exit(struct rsmu_ddata *rsmu);
#endif /* __RSMU_MFD_H */
// SPDX-License-Identifier: GPL-2.0+
/*
* Core driver for Renesas Synchronization Management Unit (SMU) devices.
*
* Copyright (C) 2021 Integrated Device Technology, Inc., a Renesas Company.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/mfd/core.h>
#include <linux/mfd/rsmu.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include "rsmu.h"
enum {
RSMU_PHC = 0,
RSMU_CDEV = 1,
RSMU_N_DEVS = 2,
};
static struct mfd_cell rsmu_cm_devs[] = {
[RSMU_PHC] = {
.name = "8a3400x-phc",
},
[RSMU_CDEV] = {
.name = "8a3400x-cdev",
},
};
static struct mfd_cell rsmu_sabre_devs[] = {
[RSMU_PHC] = {
.name = "82p33x1x-phc",
},
[RSMU_CDEV] = {
.name = "82p33x1x-cdev",
},
};
static struct mfd_cell rsmu_sl_devs[] = {
[RSMU_PHC] = {
.name = "8v19n85x-phc",
},
[RSMU_CDEV] = {
.name = "8v19n85x-cdev",
},
};
int rsmu_core_init(struct rsmu_ddata *rsmu)
{
struct mfd_cell *cells;
int ret;
switch (rsmu->type) {
case RSMU_CM:
cells = rsmu_cm_devs;
break;
case RSMU_SABRE:
cells = rsmu_sabre_devs;
break;
case RSMU_SL:
cells = rsmu_sl_devs;
break;
default:
dev_err(rsmu->dev, "Unsupported RSMU device type: %d\n", rsmu->type);
return -ENODEV;
}
mutex_init(&rsmu->lock);
ret = devm_mfd_add_devices(rsmu->dev, PLATFORM_DEVID_AUTO, cells,
RSMU_N_DEVS, NULL, 0, NULL);
if (ret < 0)
dev_err(rsmu->dev, "Failed to register sub-devices: %d\n", ret);
return ret;
}
void rsmu_core_exit(struct rsmu_ddata *rsmu)
{
mutex_destroy(&rsmu->lock);
}
MODULE_DESCRIPTION("Renesas SMU core driver");
MODULE_LICENSE("GPL");
// SPDX-License-Identifier: GPL-2.0+
/*
* I2C driver for Renesas Synchronization Management Unit (SMU) devices.
*
* Copyright (C) 2021 Integrated Device Technology, Inc., a Renesas Company.
*/
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/mfd/core.h>
#include <linux/mfd/rsmu.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include "rsmu.h"
/*
* 16-bit register address: the lower 8 bits of the register address come
* from the offset addr byte and the upper 8 bits come from the page register.
*/
#define RSMU_CM_PAGE_ADDR 0xFD
#define RSMU_CM_PAGE_WINDOW 256
/*
* 15-bit register address: the lower 7 bits of the register address come
* from the offset addr byte and the upper 8 bits come from the page register.
*/
#define RSMU_SABRE_PAGE_ADDR 0x7F
#define RSMU_SABRE_PAGE_WINDOW 128
static const struct regmap_range_cfg rsmu_cm_range_cfg[] = {
{
.range_min = 0,
.range_max = 0xD000,
.selector_reg = RSMU_CM_PAGE_ADDR,
.selector_mask = 0xFF,
.selector_shift = 0,
.window_start = 0,
.window_len = RSMU_CM_PAGE_WINDOW,
}
};
static const struct regmap_range_cfg rsmu_sabre_range_cfg[] = {
{
.range_min = 0,
.range_max = 0x400,
.selector_reg = RSMU_SABRE_PAGE_ADDR,
.selector_mask = 0xFF,
.selector_shift = 0,
.window_start = 0,
.window_len = RSMU_SABRE_PAGE_WINDOW,
}
};
static bool rsmu_cm_volatile_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case RSMU_CM_PAGE_ADDR:
return false;
default:
return true;
}
}
static bool rsmu_sabre_volatile_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case RSMU_SABRE_PAGE_ADDR:
return false;
default:
return true;
}
}
static const struct regmap_config rsmu_cm_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xD000,
.ranges = rsmu_cm_range_cfg,
.num_ranges = ARRAY_SIZE(rsmu_cm_range_cfg),
.volatile_reg = rsmu_cm_volatile_reg,
.cache_type = REGCACHE_RBTREE,
.can_multi_write = true,
};
static const struct regmap_config rsmu_sabre_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = 0x400,
.ranges = rsmu_sabre_range_cfg,
.num_ranges = ARRAY_SIZE(rsmu_sabre_range_cfg),
.volatile_reg = rsmu_sabre_volatile_reg,
.cache_type = REGCACHE_RBTREE,
.can_multi_write = true,
};
static const struct regmap_config rsmu_sl_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
.reg_format_endian = REGMAP_ENDIAN_BIG,
.max_register = 0x339,
.cache_type = REGCACHE_NONE,
.can_multi_write = true,
};
static int rsmu_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
const struct regmap_config *cfg;
struct rsmu_ddata *rsmu;
int ret;
rsmu = devm_kzalloc(&client->dev, sizeof(*rsmu), GFP_KERNEL);
if (!rsmu)
return -ENOMEM;
i2c_set_clientdata(client, rsmu);
rsmu->dev = &client->dev;
rsmu->type = (enum rsmu_type)id->driver_data;
switch (rsmu->type) {
case RSMU_CM:
cfg = &rsmu_cm_regmap_config;
break;
case RSMU_SABRE:
cfg = &rsmu_sabre_regmap_config;
break;
case RSMU_SL:
cfg = &rsmu_sl_regmap_config;
break;
default:
dev_err(rsmu->dev, "Unsupported RSMU device type: %d\n", rsmu->type);
return -ENODEV;
}
rsmu->regmap = devm_regmap_init_i2c(client, cfg);
if (IS_ERR(rsmu->regmap)) {
ret = PTR_ERR(rsmu->regmap);
dev_err(rsmu->dev, "Failed to allocate register map: %d\n", ret);
return ret;
}
return rsmu_core_init(rsmu);
}
static int rsmu_i2c_remove(struct i2c_client *client)
{
struct rsmu_ddata *rsmu = i2c_get_clientdata(client);
rsmu_core_exit(rsmu);
return 0;
}
static const struct i2c_device_id rsmu_i2c_id[] = {
{ "8a34000", RSMU_CM },
{ "8a34001", RSMU_CM },
{ "82p33810", RSMU_SABRE },
{ "82p33811", RSMU_SABRE },
{ "8v19n850", RSMU_SL },
{ "8v19n851", RSMU_SL },
{}
};
MODULE_DEVICE_TABLE(i2c, rsmu_i2c_id);
static const struct of_device_id rsmu_i2c_of_match[] = {
{ .compatible = "idt,8a34000", .data = (void *)RSMU_CM },
{ .compatible = "idt,8a34001", .data = (void *)RSMU_CM },
{ .compatible = "idt,82p33810", .data = (void *)RSMU_SABRE },
{ .compatible = "idt,82p33811", .data = (void *)RSMU_SABRE },
{ .compatible = "idt,8v19n850", .data = (void *)RSMU_SL },
{ .compatible = "idt,8v19n851", .data = (void *)RSMU_SL },
{}
};
MODULE_DEVICE_TABLE(of, rsmu_i2c_of_match);
static struct i2c_driver rsmu_i2c_driver = {
.driver = {
.name = "rsmu-i2c",
.of_match_table = of_match_ptr(rsmu_i2c_of_match),
},
.probe = rsmu_i2c_probe,
.remove = rsmu_i2c_remove,
.id_table = rsmu_i2c_id,
};
static int __init rsmu_i2c_init(void)
{
return i2c_add_driver(&rsmu_i2c_driver);
}
subsys_initcall(rsmu_i2c_init);
static void __exit rsmu_i2c_exit(void)
{
i2c_del_driver(&rsmu_i2c_driver);
}
module_exit(rsmu_i2c_exit);
MODULE_DESCRIPTION("Renesas SMU I2C driver");
MODULE_LICENSE("GPL");
// SPDX-License-Identifier: GPL-2.0+
/*
* SPI driver for Renesas Synchronization Management Unit (SMU) devices.
*
* Copyright (C) 2021 Integrated Device Technology, Inc., a Renesas Company.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/mfd/core.h>
#include <linux/mfd/rsmu.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/spi/spi.h>
#include "rsmu.h"
#define RSMU_CM_PAGE_ADDR 0x7C
#define RSMU_SABRE_PAGE_ADDR 0x7F
#define RSMU_HIGHER_ADDR_MASK 0xFF80
#define RSMU_HIGHER_ADDR_SHIFT 7
#define RSMU_LOWER_ADDR_MASK 0x7F
static int rsmu_read_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u16 bytes)
{
struct spi_device *client = to_spi_device(rsmu->dev);
struct spi_transfer xfer = {0};
struct spi_message msg;
u8 cmd[256] = {0};
u8 rsp[256] = {0};
int ret;
cmd[0] = reg | 0x80;
xfer.rx_buf = rsp;
xfer.len = bytes + 1;
xfer.tx_buf = cmd;
xfer.bits_per_word = client->bits_per_word;
xfer.speed_hz = client->max_speed_hz;
spi_message_init(&msg);
spi_message_add_tail(&xfer, &msg);
/*
* 4-wire SPI is a shift register, so for every byte you send,
* you get one back at the same time. Example read from 0xC024,
* which has value of 0x2D
*
* MOSI:
* 7C 00 C0 #Set page register
* A4 00 #MSB is set, so this is read command
* MISO:
* XX 2D #XX is a dummy byte from sending A4 and we
* need to throw it away
*/
ret = spi_sync(client, &msg);
if (ret >= 0)
memcpy(buf, &rsp[1], xfer.len-1);
return ret;
}
static int rsmu_write_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u16 bytes)
{
struct spi_device *client = to_spi_device(rsmu->dev);
struct spi_transfer xfer = {0};
struct spi_message msg;
u8 cmd[256] = {0};
cmd[0] = reg;
memcpy(&cmd[1], buf, bytes);
xfer.len = bytes + 1;
xfer.tx_buf = cmd;
xfer.bits_per_word = client->bits_per_word;
xfer.speed_hz = client->max_speed_hz;
spi_message_init(&msg);
spi_message_add_tail(&xfer, &msg);
return spi_sync(client, &msg);
}
/*
* 1-byte (1B) offset addressing:
* 16-bit register address: the lower 7 bits of the register address come
* from the offset addr byte and the upper 9 bits come from the page register.
*/
static int rsmu_write_page_register(struct rsmu_ddata *rsmu, u16 reg)
{
u8 page_reg;
u8 buf[2];
u16 bytes;
u16 page;
int err;
switch (rsmu->type) {
case RSMU_CM:
page_reg = RSMU_CM_PAGE_ADDR;
page = reg & RSMU_HIGHER_ADDR_MASK;
buf[0] = (u8)(page & 0xff);
buf[1] = (u8)((page >> 8) & 0xff);
bytes = 2;
break;
case RSMU_SABRE:
page_reg = RSMU_SABRE_PAGE_ADDR;
page = reg >> RSMU_HIGHER_ADDR_SHIFT;
buf[0] = (u8)(page & 0xff);
bytes = 1;
break;
default:
dev_err(rsmu->dev, "Unsupported RSMU device type: %d\n", rsmu->type);
return -ENODEV;
}
/* Simply return if we are on the same page */
if (rsmu->page == page)
return 0;
err = rsmu_write_device(rsmu, page_reg, buf, bytes);
if (err)
dev_err(rsmu->dev, "Failed to set page offset 0x%x\n", page);
else
/* Remember the last page */
rsmu->page = page;
return err;
}
static int rsmu_reg_read(void *context, unsigned int reg, unsigned int *val)
{
struct rsmu_ddata *rsmu = spi_get_drvdata((struct spi_device *)context);
u8 addr = (u8)(reg & RSMU_LOWER_ADDR_MASK);
int err;
err = rsmu_write_page_register(rsmu, reg);
if (err)
return err;
err = rsmu_read_device(rsmu, addr, (u8 *)val, 1);
if (err)
dev_err(rsmu->dev, "Failed to read offset address 0x%x\n", addr);
return err;
}
static int rsmu_reg_write(void *context, unsigned int reg, unsigned int val)
{
struct rsmu_ddata *rsmu = spi_get_drvdata((struct spi_device *)context);
u8 addr = (u8)(reg & RSMU_LOWER_ADDR_MASK);
u8 data = (u8)val;
int err;
err = rsmu_write_page_register(rsmu, reg);
if (err)
return err;
err = rsmu_write_device(rsmu, addr, &data, 1);
if (err)
dev_err(rsmu->dev,
"Failed to write offset address 0x%x\n", addr);
return err;
}
static const struct regmap_config rsmu_cm_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
.max_register = 0xD000,
.reg_read = rsmu_reg_read,
.reg_write = rsmu_reg_write,
.cache_type = REGCACHE_NONE,
};
static const struct regmap_config rsmu_sabre_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
.max_register = 0x400,
.reg_read = rsmu_reg_read,
.reg_write = rsmu_reg_write,
.cache_type = REGCACHE_NONE,
};
static int rsmu_spi_probe(struct spi_device *client)
{
const struct spi_device_id *id = spi_get_device_id(client);
const struct regmap_config *cfg;
struct rsmu_ddata *rsmu;
int ret;
rsmu = devm_kzalloc(&client->dev, sizeof(*rsmu), GFP_KERNEL);
if (!rsmu)
return -ENOMEM;
spi_set_drvdata(client, rsmu);
rsmu->dev = &client->dev;
rsmu->type = (enum rsmu_type)id->driver_data;
/* Initialize regmap */
switch (rsmu->type) {
case RSMU_CM:
cfg = &rsmu_cm_regmap_config;
break;
case RSMU_SABRE:
cfg = &rsmu_sabre_regmap_config;
break;
default:
dev_err(rsmu->dev, "Unsupported RSMU device type: %d\n", rsmu->type);
return -ENODEV;
}
rsmu->regmap = devm_regmap_init(&client->dev, NULL, client, cfg);
if (IS_ERR(rsmu->regmap)) {
ret = PTR_ERR(rsmu->regmap);
dev_err(rsmu->dev, "Failed to allocate register map: %d\n", ret);
return ret;
}
return rsmu_core_init(rsmu);
}
static int rsmu_spi_remove(struct spi_device *client)
{
struct rsmu_ddata *rsmu = spi_get_drvdata(client);
rsmu_core_exit(rsmu);
return 0;
}
static const struct spi_device_id rsmu_spi_id[] = {
{ "8a34000", RSMU_CM },
{ "8a34001", RSMU_CM },
{ "82p33810", RSMU_SABRE },
{ "82p33811", RSMU_SABRE },
{}
};
MODULE_DEVICE_TABLE(spi, rsmu_spi_id);
static const struct of_device_id rsmu_spi_of_match[] = {
{ .compatible = "idt,8a34000", .data = (void *)RSMU_CM },
{ .compatible = "idt,8a34001", .data = (void *)RSMU_CM },
{ .compatible = "idt,82p33810", .data = (void *)RSMU_SABRE },
{ .compatible = "idt,82p33811", .data = (void *)RSMU_SABRE },
{}
};
MODULE_DEVICE_TABLE(of, rsmu_spi_of_match);
static struct spi_driver rsmu_spi_driver = {
.driver = {
.name = "rsmu-spi",
.of_match_table = of_match_ptr(rsmu_spi_of_match),
},
.probe = rsmu_spi_probe,
.remove = rsmu_spi_remove,
.id_table = rsmu_spi_id,
};
static int __init rsmu_spi_init(void)
{
return spi_register_driver(&rsmu_spi_driver);
}
subsys_initcall(rsmu_spi_init);
static void __exit rsmu_spi_exit(void)
{
spi_unregister_driver(&rsmu_spi_driver);
}
module_exit(rsmu_spi_exit);
MODULE_DESCRIPTION("Renesas SMU SPI driver");
MODULE_LICENSE("GPL");
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Register Map - Based on AN888_SMUforIEEE_SynchEther_82P33xxx_RevH.pdf
*
* Copyright (C) 2021 Integrated Device Technology, Inc., a Renesas Company.
*/
#ifndef HAVE_IDT82P33_REG
#define HAVE_IDT82P33_REG
/* Register address */
#define DPLL1_TOD_CNFG 0x134
#define DPLL2_TOD_CNFG 0x1B4
#define DPLL1_TOD_STS 0x10B
#define DPLL2_TOD_STS 0x18B
#define DPLL1_TOD_TRIGGER 0x115
#define DPLL2_TOD_TRIGGER 0x195
#define DPLL1_OPERATING_MODE_CNFG 0x120
#define DPLL2_OPERATING_MODE_CNFG 0x1A0
#define DPLL1_HOLDOVER_FREQ_CNFG 0x12C
#define DPLL2_HOLDOVER_FREQ_CNFG 0x1AC
#define DPLL1_PHASE_OFFSET_CNFG 0x143
#define DPLL2_PHASE_OFFSET_CNFG 0x1C3
#define DPLL1_SYNC_EDGE_CNFG 0x140
#define DPLL2_SYNC_EDGE_CNFG 0x1C0
#define DPLL1_INPUT_MODE_CNFG 0x116
#define DPLL2_INPUT_MODE_CNFG 0x196
#define DPLL1_OPERATING_STS 0x102
#define DPLL2_OPERATING_STS 0x182
#define DPLL1_CURRENT_FREQ_STS 0x103
#define DPLL2_CURRENT_FREQ_STS 0x183
#define REG_SOFT_RESET 0X381
#define OUT_MUX_CNFG(outn) REG_ADDR(0x6, (0xC * (outn)))
/* Register bit definitions */
#define SYNC_TOD BIT(1)
#define PH_OFFSET_EN BIT(7)
#define SQUELCH_ENABLE BIT(5)
/* Bit definitions for the DPLL_MODE register */
#define PLL_MODE_SHIFT (0)
#define PLL_MODE_MASK (0x1F)
#define COMBO_MODE_EN BIT(5)
#define COMBO_MODE_SHIFT (6)
#define COMBO_MODE_MASK (0x3)
/* Bit definitions for DPLL_OPERATING_STS register */
#define OPERATING_STS_MASK (0x7)
#define OPERATING_STS_SHIFT (0x0)
/* Bit definitions for DPLL_TOD_TRIGGER register */
#define READ_TRIGGER_MASK (0xF)
#define READ_TRIGGER_SHIFT (0x0)
#define WRITE_TRIGGER_MASK (0xF0)
#define WRITE_TRIGGER_SHIFT (0x4)
/* Bit definitions for REG_SOFT_RESET register */
#define SOFT_RESET_EN BIT(7)
enum pll_mode {
PLL_MODE_MIN = 0,
PLL_MODE_AUTOMATIC = PLL_MODE_MIN,
PLL_MODE_FORCE_FREERUN = 1,
PLL_MODE_FORCE_HOLDOVER = 2,
PLL_MODE_FORCE_LOCKED = 4,
PLL_MODE_FORCE_PRE_LOCKED2 = 5,
PLL_MODE_FORCE_PRE_LOCKED = 6,
PLL_MODE_FORCE_LOST_PHASE = 7,
PLL_MODE_DCO = 10,
PLL_MODE_WPH = 18,
PLL_MODE_MAX = PLL_MODE_WPH,
};
enum hw_tod_trig_sel {
HW_TOD_TRIG_SEL_MIN = 0,
HW_TOD_TRIG_SEL_NO_WRITE = HW_TOD_TRIG_SEL_MIN,
HW_TOD_TRIG_SEL_NO_READ = HW_TOD_TRIG_SEL_MIN,
HW_TOD_TRIG_SEL_SYNC_SEL = 1,
HW_TOD_TRIG_SEL_IN12 = 2,
HW_TOD_TRIG_SEL_IN13 = 3,
HW_TOD_TRIG_SEL_IN14 = 4,
HW_TOD_TRIG_SEL_TOD_PPS = 5,
HW_TOD_TRIG_SEL_TIMER_INTERVAL = 6,
HW_TOD_TRIG_SEL_MSB_PHASE_OFFSET_CNFG = 7,
HW_TOD_TRIG_SEL_MSB_HOLDOVER_FREQ_CNFG = 8,
HW_TOD_WR_TRIG_SEL_MSB_TOD_CNFG = 9,
HW_TOD_RD_TRIG_SEL_LSB_TOD_STS = HW_TOD_WR_TRIG_SEL_MSB_TOD_CNFG,
WR_TRIG_SEL_MAX = HW_TOD_WR_TRIG_SEL_MSB_TOD_CNFG,
};
/** @brief Enumerated type listing DPLL operational modes */
enum dpll_state {
DPLL_STATE_FREERUN = 1,
DPLL_STATE_HOLDOVER = 2,
DPLL_STATE_LOCKED = 4,
DPLL_STATE_PRELOCKED2 = 5,
DPLL_STATE_PRELOCKED = 6,
DPLL_STATE_LOSTPHASE = 7,
DPLL_STATE_MAX
};
#endif
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Core interface for Renesas Synchronization Management Unit (SMU) devices.
*
* Copyright (C) 2021 Integrated Device Technology, Inc., a Renesas Company.
*/
#ifndef __LINUX_MFD_RSMU_H
#define __LINUX_MFD_RSMU_H
/* The supported devices are ClockMatrix, Sabre and SnowLotus */
enum rsmu_type {
RSMU_CM = 0x34000,
RSMU_SABRE = 0x33810,
RSMU_SL = 0x19850,
};
/**
*
* struct rsmu_ddata - device data structure for sub devices.
*
* @dev: i2c/spi device.
* @regmap: i2c/spi bus access.
* @lock: mutex used by sub devices to make sure a series of
* bus access requests are not interrupted.
* @type: RSMU device type.
* @page: i2c/spi bus driver internal use only.
*/
struct rsmu_ddata {
struct device *dev;
struct regmap *regmap;
struct mutex lock;
enum rsmu_type type;
u16 page;
};
#endif /* __LINUX_MFD_RSMU_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment