lkml.org 
[lkml]   [2023]   [May]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v7 6/6] samples: Add userspace example for TI TPS6594 PFSM
    Date
    This patch adds an example showing how to use PFSM devices
    from a userspace application. The PMIC is armed to be triggered
    by a RTC alarm to execute state transition.

    Signed-off-by: Julien Panis <jpanis@baylibre.com>
    ---
    samples/Kconfig | 6 ++
    samples/Makefile | 1 +
    samples/pfsm/.gitignore | 2 +
    samples/pfsm/Makefile | 4 ++
    samples/pfsm/pfsm-wakeup.c | 125 +++++++++++++++++++++++++++++++++++++
    5 files changed, 138 insertions(+)
    create mode 100644 samples/pfsm/.gitignore
    create mode 100644 samples/pfsm/Makefile
    create mode 100644 samples/pfsm/pfsm-wakeup.c

    diff --git a/samples/Kconfig b/samples/Kconfig
    index b2db430bd3ff..3edf73a3dc9b 100644
    --- a/samples/Kconfig
    +++ b/samples/Kconfig
    @@ -253,6 +253,12 @@ config SAMPLE_INTEL_MEI
    help
    Build a sample program to work with mei device.

    +config SAMPLE_TPS6594_PFSM
    + bool "Build example program working with TPS6594 PFSM driver"
    + depends on HEADERS_INSTALL
    + help
    + Build a sample program to work with PFSM devices.
    +
    config SAMPLE_WATCHDOG
    bool "watchdog sample"
    depends on CC_CAN_LINK
    diff --git a/samples/Makefile b/samples/Makefile
    index 7727f1a0d6d1..0a551c2b33f4 100644
    --- a/samples/Makefile
    +++ b/samples/Makefile
    @@ -31,6 +31,7 @@ obj-$(CONFIG_VIDEO_PCI_SKELETON) += v4l/
    obj-y += vfio-mdev/
    subdir-$(CONFIG_SAMPLE_VFS) += vfs
    obj-$(CONFIG_SAMPLE_INTEL_MEI) += mei/
    +obj-$(CONFIG_SAMPLE_TPS6594_PFSM) += pfsm/
    subdir-$(CONFIG_SAMPLE_WATCHDOG) += watchdog
    subdir-$(CONFIG_SAMPLE_WATCH_QUEUE) += watch_queue
    obj-$(CONFIG_SAMPLE_KMEMLEAK) += kmemleak/
    diff --git a/samples/pfsm/.gitignore b/samples/pfsm/.gitignore
    new file mode 100644
    index 000000000000..f350a030a060
    --- /dev/null
    +++ b/samples/pfsm/.gitignore
    @@ -0,0 +1,2 @@
    +# SPDX-License-Identifier: GPL-2.0
    +/pfsm-wakeup
    diff --git a/samples/pfsm/Makefile b/samples/pfsm/Makefile
    new file mode 100644
    index 000000000000..213e8d9f5dbc
    --- /dev/null
    +++ b/samples/pfsm/Makefile
    @@ -0,0 +1,4 @@
    +# SPDX-License-Identifier: GPL-2.0
    +userprogs-always-y += pfsm-wakeup
    +
    +userccflags += -I usr/include
    diff --git a/samples/pfsm/pfsm-wakeup.c b/samples/pfsm/pfsm-wakeup.c
    new file mode 100644
    index 000000000000..299dd9e1f607
    --- /dev/null
    +++ b/samples/pfsm/pfsm-wakeup.c
    @@ -0,0 +1,125 @@
    +// SPDX-License-Identifier: GPL-2.0
    +/*
    + * TPS6594 PFSM userspace example
    + *
    + * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
    + *
    + * This example shows how to use PFSMs from a userspace application,
    + * on TI j721s2 platform. The PMIC is armed to be triggered by a RTC
    + * alarm to execute state transition (RETENTION to ACTIVE).
    + */
    +
    +#include <fcntl.h>
    +#include <stdio.h>
    +#include <sys/ioctl.h>
    +#include <unistd.h>
    +
    +#include <linux/rtc.h>
    +#include <linux/tps6594_pfsm.h>
    +
    +#define ALARM_DELTA_SEC 30
    +
    +#define RTC_A "/dev/rtc0"
    +
    +#define PMIC_NB 3
    +#define PMIC_A "/dev/pfsm-0-0x48"
    +#define PMIC_B "/dev/pfsm-0-0x4c"
    +#define PMIC_C "/dev/pfsm-2-0x58"
    +
    +static const char * const dev_pfsm[] = {PMIC_A, PMIC_B, PMIC_C};
    +
    +int main(int argc, char *argv[])
    +{
    + int i, ret, fd_rtc, fd_pfsm[PMIC_NB] = { 0 };
    + struct rtc_time rtc_tm;
    + struct pmic_state_opt pmic_opt = { 0 };
    + unsigned long data;
    +
    + fd_rtc = open(RTC_A, O_RDONLY);
    + if (fd_rtc < 0) {
    + perror("Failed to open RTC device.");
    + goto out;
    + }
    +
    + for (i = 0 ; i < PMIC_NB ; i++) {
    + fd_pfsm[i] = open(dev_pfsm[i], O_RDWR);
    + if (fd_pfsm[i] < 0) {
    + perror("Failed to open PFSM device.");
    + goto out;
    + }
    + }
    +
    + /* Read RTC date/time */
    + ret = ioctl(fd_rtc, RTC_RD_TIME, &rtc_tm);
    + if (ret < 0) {
    + perror("Failed to read RTC date/time.");
    + goto out;
    + }
    + printf("Current RTC date/time is %d-%d-%d, %02d:%02d:%02d.\n",
    + rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900,
    + rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
    +
    + /* Set RTC alarm to ALARM_DELTA_SEC sec in the future, and check for rollover */
    + rtc_tm.tm_sec += ALARM_DELTA_SEC;
    + if (rtc_tm.tm_sec >= 60) {
    + rtc_tm.tm_sec %= 60;
    + rtc_tm.tm_min++;
    + }
    + if (rtc_tm.tm_min == 60) {
    + rtc_tm.tm_min = 0;
    + rtc_tm.tm_hour++;
    + }
    + if (rtc_tm.tm_hour == 24)
    + rtc_tm.tm_hour = 0;
    + ret = ioctl(fd_rtc, RTC_ALM_SET, &rtc_tm);
    + if (ret < 0) {
    + perror("Failed to set RTC alarm.");
    + goto out;
    + }
    +
    + /* Enable alarm interrupts */
    + ret = ioctl(fd_rtc, RTC_AIE_ON, 0);
    + if (ret < 0) {
    + perror("Failed to enable alarm interrupts.");
    + goto out;
    + }
    + printf("Waiting %d seconds for alarm...\n", ALARM_DELTA_SEC);
    +
    + /*
    + * Set RETENTION state with options for PMIC_C/B/A respectively.
    + * Since PMIC_A is master, it should be the last one to be configured.
    + */
    + pmic_opt.ddr_retention = 1;
    + for (i = PMIC_NB - 1 ; i >= 0 ; i--) {
    + printf("Set RETENTION state for PMIC_%d.\n", i);
    + sleep(1);
    + ret = ioctl(fd_pfsm[i], PMIC_SET_RETENTION_STATE, &pmic_opt);
    + if (ret < 0) {
    + perror("Failed to set RETENTION state.");
    + goto out_reset;
    + }
    + }
    +
    + /* This blocks until the alarm ring causes an interrupt */
    + ret = read(fd_rtc, &data, sizeof(unsigned long));
    + if (ret < 0)
    + perror("Failed to get RTC alarm.");
    + else
    + puts("Alarm rang.\n");
    +
    +out_reset:
    + ioctl(fd_rtc, RTC_AIE_OFF, 0);
    +
    + /* Set ACTIVE state for PMIC_A */
    + ioctl(fd_pfsm[0], PMIC_SET_ACTIVE_STATE, 0);
    +
    +out:
    + for (i = 0 ; i < PMIC_NB ; i++)
    + if (fd_pfsm[i])
    + close(fd_pfsm[i]);
    +
    + if (fd_rtc)
    + close(fd_rtc);
    +
    + return 0;
    +}
    --
    2.37.3
    \
     
     \ /
      Last update: 2023-05-11 11:53    [W:2.306 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site