From patchwork Thu Oct 20 23:24:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vadim Fedorenko X-Patchwork-Id: 13014145 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E1A3DC433FE for ; Thu, 20 Oct 2022 23:25:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229757AbiJTXZb (ORCPT ); Thu, 20 Oct 2022 19:25:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59400 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229747AbiJTXZX (ORCPT ); Thu, 20 Oct 2022 19:25:23 -0400 Received: from novek.ru (unknown [213.148.174.62]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7EE708D226 for ; Thu, 20 Oct 2022 16:25:17 -0700 (PDT) Received: from nat1.ooonet.ru (gw.zelenaya.net [91.207.137.40]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by novek.ru (Postfix) with ESMTPSA id E5FEF504EED; Fri, 21 Oct 2022 02:21:07 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 novek.ru E5FEF504EED DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=novek.ru; s=mail; t=1666308069; bh=lPBrbvbrUPzBLiAl8PK8x2uOda+OujkuedTY/srEzv0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hEW0lcqrXmn5E7UItmEEfT6lSnzK2pKquMQOWhOkmctDGMMZAYYvtMY5py8Lvna3Z IZlm2RJRfDm6O3FEhwZDVLAN5qM7oawFx3FUw+hpgHtrE5Bvh+JEt+QJoLoUZEDOBR WXyiBlJJlfAz9tpjWivZwICG/co77vqww3+kHJ14= From: Vadim Fedorenko To: Richard Cochran , Jonathan Lemon , Jakub Kicinski Cc: netdev@vger.kernel.org, Vadim Fedorenko , Charles Parent Subject: [PATCH net-next v6 4/5] ptp: ocp: expose config and temperature for ART card Date: Fri, 21 Oct 2022 02:24:32 +0300 Message-Id: <20221020232433.9593-5-vfedorenko@novek.ru> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20221020232433.9593-1-vfedorenko@novek.ru> References: <20221020232433.9593-1-vfedorenko@novek.ru> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org From: Vadim Fedorenko 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 Co-developed-by: Charles Parent Signed-off-by: Jonathan Lemon Signed-off-by: Vadim Fedorenko --- drivers/ptp/ptp_ocp.c | 136 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index 223980d725fe..d2d486ccd714 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -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[] = {