Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 29 additions & 28 deletions drivers/mfd/Kconfig

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this change may be minimized by moving config sections down

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know, and not only here, but I preferred to keep the changes exactly as they are in https://github.com/renesas/linux-ptp-driver-package . Anyway this PR is now superseded by work done for https://ceragon.atlassian.net/issues/DEV-7459, keeping it in Draft just in case.

Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,35 @@ config MFD_CORE
select IRQ_DOMAIN
default n

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.


config MFD_CS5535
tristate "AMD CS5535 and CS5536 southbridge core functions"
select MFD_CORE
Expand Down Expand Up @@ -2168,33 +2197,5 @@ config MFD_INTEL_M10_BMC
additional drivers must be enabled in order to use the functionality
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
endif
9 changes: 5 additions & 4 deletions drivers/mfd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ obj-$(CONFIG_MFD_MC13XXX_I2C) += mc13xxx-i2c.o

obj-$(CONFIG_MFD_CORE) += mfd-core.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

obj-$(CONFIG_EZX_PCAP) += ezx-pcap.o
obj-$(CONFIG_MFD_CPCAP) += motorola-cpcap.o

Expand Down Expand Up @@ -271,7 +276,3 @@ obj-$(CONFIG_MFD_INTEL_M10_BMC) += intel-m10-bmc.o
obj-$(CONFIG_MFD_ATC260X) += atc260x-core.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
11 changes: 5 additions & 6 deletions drivers/mfd/rsmu_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ static struct mfd_cell rsmu_sabre_devs[] = {
},
};

static struct mfd_cell rsmu_sl_devs[] = {
static struct mfd_cell rsmu_fc3_devs[] = {
[RSMU_PHC] = {
.name = "8v19n85x-phc",
.name = "rc38xxx-phc",
},
[RSMU_CDEV] = {
.name = "8v19n85x-cdev",
.name = "rc38xxx-cdev",
},
};

Expand All @@ -61,8 +61,8 @@ int rsmu_core_init(struct rsmu_ddata *rsmu)
case RSMU_SABRE:
cells = rsmu_sabre_devs;
break;
case RSMU_SL:
cells = rsmu_sl_devs;
case RSMU_FC3:
cells = rsmu_fc3_devs;
break;
default:
dev_err(rsmu->dev, "Unsupported RSMU device type: %d\n", rsmu->type);
Expand All @@ -82,7 +82,6 @@ int rsmu_core_init(struct rsmu_ddata *rsmu)
void rsmu_core_exit(struct rsmu_ddata *rsmu)
{
mutex_destroy(&rsmu->lock);
regmap_exit(rsmu->regmap);
}

MODULE_DESCRIPTION("Renesas SMU core driver");
Expand Down
126 changes: 102 additions & 24 deletions drivers/mfd/rsmu_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
* from the offset addr byte and the upper 24 bits come from the page register.
*/
#define RSMU_CM_PAGE_ADDR 0xFC
#define RSMU_CM_PAGE_MASK 0xFFFFFF00
#define RSMU_CM_ADDRESS_MASK 0x000000FF
#define RSMU_CM_PAGE_MASK 0xFFFFFF00
#define RSMU_CM_ADDRESS_MASK 0x000000FF

/*
* 15-bit register address: the lower 7 bits of the register address come
Expand All @@ -32,6 +32,8 @@
#define RSMU_SABRE_PAGE_ADDR 0x7F
#define RSMU_SABRE_PAGE_WINDOW 128

typedef int (*rsmu_rw_device)(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u8 bytes);

static const struct regmap_range_cfg rsmu_sabre_range_cfg[] = {
{
.range_min = 0,
Expand All @@ -54,7 +56,28 @@ static bool rsmu_sabre_volatile_reg(struct device *dev, unsigned int reg)
}
}

static int rsmu_read_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u16 bytes)
static int rsmu_smbus_i2c_write_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u8 bytes)
{
struct i2c_client *client = to_i2c_client(rsmu->dev);

return i2c_smbus_write_i2c_block_data(client, reg, bytes, buf);
}

static int rsmu_smbus_i2c_read_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u8 bytes)
{
struct i2c_client *client = to_i2c_client(rsmu->dev);
int ret;

ret = i2c_smbus_read_i2c_block_data(client, reg, bytes, buf);
if (ret == bytes)
return 0;
else if (ret < 0)
return ret;
else
return -EIO;
}

static int rsmu_i2c_read_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u8 bytes)
{
struct i2c_client *client = to_i2c_client(rsmu->dev);
struct i2c_msg msg[2];
Expand All @@ -73,7 +96,7 @@ static int rsmu_read_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u16 bytes)
cnt = i2c_transfer(client->adapter, msg, 2);

if (cnt < 0) {
dev_err(rsmu->dev, "i2c_transfer failed at at addr: %04x!",reg);
dev_err(rsmu->dev, "i2c_transfer failed at addr: %04x!", reg);
return cnt;
} else if (cnt != 2) {
dev_err(rsmu->dev,
Expand All @@ -84,7 +107,7 @@ static int rsmu_read_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u16 bytes)
return 0;
}

static int rsmu_write_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u16 bytes)
static int rsmu_i2c_write_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u8 bytes)
{
struct i2c_client *client = to_i2c_client(rsmu->dev);
/* we add 1 byte for device register */
Expand All @@ -108,7 +131,8 @@ static int rsmu_write_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u16 bytes
return 0;
}

static int rsmu_write_page_register(struct rsmu_ddata *rsmu, u32 reg)
static int rsmu_write_page_register(struct rsmu_ddata *rsmu, u32 reg,
rsmu_rw_device rsmu_write_device)
{
u32 page = reg & RSMU_CM_PAGE_MASK;
u8 buf[4];
Expand Down Expand Up @@ -137,48 +161,93 @@ static int rsmu_write_page_register(struct rsmu_ddata *rsmu, u32 reg)
return err;
}

static int rsmu_reg_read(void *context, unsigned int reg, unsigned int *val)
static int rsmu_i2c_reg_read(void *context, unsigned int reg, unsigned int *val)
{
struct rsmu_ddata *rsmu = i2c_get_clientdata((struct i2c_client *)context);
u8 addr = (u8)(reg & RSMU_CM_ADDRESS_MASK);
int err;

err = rsmu_write_page_register(rsmu, reg);
err = rsmu_write_page_register(rsmu, reg, rsmu_i2c_write_device);
if (err)
return err;

err = rsmu_read_device(rsmu, addr, (u8 *)val, 1);
err = rsmu_i2c_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)
static int rsmu_i2c_reg_write(void *context, unsigned int reg, unsigned int val)
{
struct rsmu_ddata *rsmu = i2c_get_clientdata((struct i2c_client *)context);
u8 addr = (u8)(reg & RSMU_CM_ADDRESS_MASK);
u8 data = (u8)val;
int err;

err = rsmu_write_page_register(rsmu, reg);
err = rsmu_write_page_register(rsmu, reg, rsmu_i2c_write_device);
if (err)
return err;

err = rsmu_write_device(rsmu, addr, &data, 1);
err = rsmu_i2c_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 = {
static int rsmu_smbus_i2c_reg_read(void *context, unsigned int reg, unsigned int *val)
{
struct rsmu_ddata *rsmu = i2c_get_clientdata((struct i2c_client *)context);
u8 addr = (u8)(reg & RSMU_CM_ADDRESS_MASK);
int err;

err = rsmu_write_page_register(rsmu, reg, rsmu_smbus_i2c_write_device);
if (err)
return err;

err = rsmu_smbus_i2c_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_smbus_i2c_reg_write(void *context, unsigned int reg, unsigned int val)
{
struct rsmu_ddata *rsmu = i2c_get_clientdata((struct i2c_client *)context);
u8 addr = (u8)(reg & RSMU_CM_ADDRESS_MASK);
u8 data = (u8)val;
int err;

err = rsmu_write_page_register(rsmu, reg, rsmu_smbus_i2c_write_device);
if (err)
return err;

err = rsmu_smbus_i2c_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_i2c_cm_regmap_config = {
.reg_bits = 32,
.val_bits = 8,
.max_register = 0x20120000,
.reg_read = rsmu_reg_read,
.reg_write = rsmu_reg_write,
.reg_read = rsmu_i2c_reg_read,
.reg_write = rsmu_i2c_reg_write,
.cache_type = REGCACHE_NONE,
};

static const struct regmap_config rsmu_smbus_i2c_cm_regmap_config = {
.reg_bits = 32,
.val_bits = 8,
.max_register = 0x20120000,
.reg_read = rsmu_smbus_i2c_reg_read,
.reg_write = rsmu_smbus_i2c_reg_write,
.cache_type = REGCACHE_NONE,
};

Expand All @@ -193,11 +262,11 @@ static const struct regmap_config rsmu_sabre_regmap_config = {
.can_multi_write = true,
};

static const struct regmap_config rsmu_sl_regmap_config = {
static const struct regmap_config rsmu_fc3_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
.reg_format_endian = REGMAP_ENDIAN_BIG,
.max_register = 0x340,
.max_register = 0xE88,
.cache_type = REGCACHE_NONE,
.can_multi_write = true,
};
Expand All @@ -220,13 +289,21 @@ static int rsmu_i2c_probe(struct i2c_client *client,

switch (rsmu->type) {
case RSMU_CM:
cfg = &rsmu_cm_regmap_config;
if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
cfg = &rsmu_i2c_cm_regmap_config;
} else if (i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_I2C_BLOCK)) {
cfg = &rsmu_smbus_i2c_cm_regmap_config;
} else {
dev_err(rsmu->dev, "Unsupported i2c adapter\n");
return -ENOTSUPP;
}
break;
case RSMU_SABRE:
cfg = &rsmu_sabre_regmap_config;
break;
case RSMU_SL:
cfg = &rsmu_sl_regmap_config;
case RSMU_FC3:
cfg = &rsmu_fc3_regmap_config;
break;
default:
dev_err(rsmu->dev, "Unsupported RSMU device type: %d\n", rsmu->type);
Expand All @@ -237,6 +314,7 @@ static int rsmu_i2c_probe(struct i2c_client *client,
rsmu->regmap = devm_regmap_init(&client->dev, NULL, client, cfg);
else
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);
Expand All @@ -260,8 +338,8 @@ static const struct i2c_device_id rsmu_i2c_id[] = {
{ "8a34001", RSMU_CM },
{ "82p33810", RSMU_SABRE },
{ "82p33811", RSMU_SABRE },
{ "8v19n850", RSMU_SL },
{ "8v19n851", RSMU_SL },
{ "rc38xxx0", RSMU_FC3 },
{ "rc38xxx1", RSMU_FC3 },
{}
};
MODULE_DEVICE_TABLE(i2c, rsmu_i2c_id);
Expand All @@ -271,8 +349,8 @@ static const struct of_device_id rsmu_i2c_of_match[] = {
{ .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 },
{ .compatible = "idt,rc38xxx0", .data = (void *)RSMU_FC3 },
{ .compatible = "idt,rc38xxx1", .data = (void *)RSMU_FC3 },
{}
};
MODULE_DEVICE_TABLE(of, rsmu_i2c_of_match);
Expand Down
9 changes: 5 additions & 4 deletions drivers/misc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ config RSMU
tristate "Renesas Synchronization Management Unit (SMU)"
depends on MFD_RSMU_I2C || MFD_RSMU_SPI
help
This option enables support for Renesas SMU, such as Clockmatrix and
82P33XXX series. It will be used by Renesas PTP Clock Manager for
Linux (pcm4l) software to provide support to GNSS assisted partial
timing support (APTS) and other networking timing functions.
This option enables support for Renesas SMUs, such as the Clockmatrix and
82P33XXX families. It is used by the Renesas PTP Clock Manager for Linux (pcm4l)
software to provide support to GNSS assisted partial timing support (APTS)
and other networking timing functions. It is used by the synced software to
manage the Synchronous Ethernet (SyncE) device.

config SENSORS_LIS3LV02D
tristate
Expand Down
2 changes: 1 addition & 1 deletion drivers/misc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,5 @@ obj-$(CONFIG_HABANA_AI) += habanalabs/
obj-$(CONFIG_UACCE) += uacce/
obj-$(CONFIG_XILINX_SDFEC) += xilinx_sdfec.o
obj-$(CONFIG_HISI_HIKEY_USB) += hisi_hikey_usb.o
rsmu-objs := rsmu_cdev.o rsmu_cm.o rsmu_sabre.o
rsmu-objs := rsmu_cdev.o rsmu_cm.o rsmu_sabre.o rsmu_fc3.o
obj-$(CONFIG_RSMU) += rsmu.o
Loading