ptp: ocp: expose config and temperature for ART card

Orolia card has disciplining configuration and temperature table
stored in EEPROM. This patch exposes them as binary attributes to
have read and write access.

Acked-by: Jonathan Lemon <jonathan.lemon@gmail.com>
Co-developed-by: Charles Parent <charles.parent@orolia2s.com>
Signed-off-by: Jonathan Lemon <jonathan.lemon@gmail.com>
Signed-off-by: Vadim Fedorenko <vadfed@fb.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Vadim Fedorenko 2022-10-21 02:24:32 +03:00 committed by David S. Miller
parent 9c44a7ac17
commit ee6439aaad

View file

@ -690,6 +690,9 @@ static struct ocp_resource ocp_fb_resource[] = {
{ }
};
#define OCP_ART_CONFIG_SIZE 144
#define OCP_ART_TEMP_TABLE_SIZE 368
struct ocp_art_gpio_reg {
struct {
u32 gpio;
@ -3334,6 +3337,130 @@ DEVICE_FREQ_GROUP(freq2, 1);
DEVICE_FREQ_GROUP(freq3, 2);
DEVICE_FREQ_GROUP(freq4, 3);
static ssize_t
disciplining_config_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
struct ptp_ocp *bp = dev_get_drvdata(kobj_to_dev(kobj));
size_t size = OCP_ART_CONFIG_SIZE;
struct nvmem_device *nvmem;
ssize_t err;
nvmem = ptp_ocp_nvmem_device_get(bp, NULL);
if (IS_ERR(nvmem))
return PTR_ERR(nvmem);
if (off > size) {
err = 0;
goto out;
}
if (off + count > size)
count = size - off;
// the configuration is in the very beginning of the EEPROM
err = nvmem_device_read(nvmem, off, count, buf);
if (err != count) {
err = -EFAULT;
goto out;
}
out:
ptp_ocp_nvmem_device_put(&nvmem);
return err;
}
static ssize_t
disciplining_config_write(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
struct ptp_ocp *bp = dev_get_drvdata(kobj_to_dev(kobj));
struct nvmem_device *nvmem;
ssize_t err;
/* Allow write of the whole area only */
if (off || count != OCP_ART_CONFIG_SIZE)
return -EFAULT;
nvmem = ptp_ocp_nvmem_device_get(bp, NULL);
if (IS_ERR(nvmem))
return PTR_ERR(nvmem);
err = nvmem_device_write(nvmem, 0x00, count, buf);
if (err != count)
err = -EFAULT;
ptp_ocp_nvmem_device_put(&nvmem);
return err;
}
static BIN_ATTR_RW(disciplining_config, OCP_ART_CONFIG_SIZE);
static ssize_t
temperature_table_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
struct ptp_ocp *bp = dev_get_drvdata(kobj_to_dev(kobj));
size_t size = OCP_ART_TEMP_TABLE_SIZE;
struct nvmem_device *nvmem;
ssize_t err;
nvmem = ptp_ocp_nvmem_device_get(bp, NULL);
if (IS_ERR(nvmem))
return PTR_ERR(nvmem);
if (off > size) {
err = 0;
goto out;
}
if (off + count > size)
count = size - off;
// the configuration is in the very beginning of the EEPROM
err = nvmem_device_read(nvmem, 0x90 + off, count, buf);
if (err != count) {
err = -EFAULT;
goto out;
}
out:
ptp_ocp_nvmem_device_put(&nvmem);
return err;
}
static ssize_t
temperature_table_write(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
struct ptp_ocp *bp = dev_get_drvdata(kobj_to_dev(kobj));
struct nvmem_device *nvmem;
ssize_t err;
/* Allow write of the whole area only */
if (off || count != OCP_ART_TEMP_TABLE_SIZE)
return -EFAULT;
nvmem = ptp_ocp_nvmem_device_get(bp, NULL);
if (IS_ERR(nvmem))
return PTR_ERR(nvmem);
err = nvmem_device_write(nvmem, 0x90, count, buf);
if (err != count)
err = -EFAULT;
ptp_ocp_nvmem_device_put(&nvmem);
return err;
}
static BIN_ATTR_RW(temperature_table, OCP_ART_TEMP_TABLE_SIZE);
static struct attribute *fb_timecard_attrs[] = {
&dev_attr_serialnum.attr,
&dev_attr_gnss_sync.attr,
@ -3353,9 +3480,11 @@ static struct attribute *fb_timecard_attrs[] = {
&dev_attr_tod_correction.attr,
NULL,
};
static const struct attribute_group fb_timecard_group = {
.attrs = fb_timecard_attrs,
};
static const struct ocp_attr_group fb_timecard_groups[] = {
{ .cap = OCP_CAP_BASIC, .group = &fb_timecard_group },
{ .cap = OCP_CAP_SIGNAL, .group = &fb_timecard_signal0_group },
@ -3384,8 +3513,15 @@ static struct attribute *art_timecard_attrs[] = {
NULL,
};
static struct bin_attribute *bin_art_timecard_attrs[] = {
&bin_attr_disciplining_config,
&bin_attr_temperature_table,
NULL,
};
static const struct attribute_group art_timecard_group = {
.attrs = art_timecard_attrs,
.bin_attrs = bin_art_timecard_attrs,
};
static const struct ocp_attr_group art_timecard_groups[] = {