From owner-svn-src-all@freebsd.org Wed Dec 12 20:57:00 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 630DF1325775; Wed, 12 Dec 2018 20:57:00 +0000 (UTC) (envelope-from manu@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id A60E6808AA; Wed, 12 Dec 2018 20:56:59 +0000 (UTC) (envelope-from manu@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 32DFFD887; Wed, 12 Dec 2018 20:56:59 +0000 (UTC) (envelope-from manu@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id wBCKux8V073116; Wed, 12 Dec 2018 20:56:59 GMT (envelope-from manu@FreeBSD.org) Received: (from manu@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id wBCKuvkH073105; Wed, 12 Dec 2018 20:56:57 GMT (envelope-from manu@FreeBSD.org) Message-Id: <201812122056.wBCKuvkH073105@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: manu set sender to manu@FreeBSD.org using -f From: Emmanuel Vadot Date: Wed, 12 Dec 2018 20:56:57 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r342003 - in head: share/man/man9 sys/conf sys/dev/pwm sys/sys usr.sbin usr.sbin/pwm X-SVN-Group: head X-SVN-Commit-Author: manu X-SVN-Commit-Paths: in head: share/man/man9 sys/conf sys/dev/pwm sys/sys usr.sbin usr.sbin/pwm X-SVN-Commit-Revision: 342003 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: A60E6808AA X-Spamd-Bar: - Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-1.66 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-0.81)[-0.814,0]; NEURAL_HAM_SHORT(-0.85)[-0.849,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US] X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Dec 2018 20:57:00 -0000 Author: manu Date: Wed Dec 12 20:56:56 2018 New Revision: 342003 URL: https://svnweb.freebsd.org/changeset/base/342003 Log: Add a pwm subsystem so we can configure pwm controller from kernel and userland. The pwm subsystem consist of API for PWM controllers, pwmbus to register them and a pwm(8) utility to talk to them from userland. Reviewed by: oshgobo (capsicum), bcr (manpage), 0mp (manpage) Differential Revision: https://reviews.freebsd.org/D17938 Added: head/share/man/man9/pwm.9 (contents, props changed) head/share/man/man9/pwmbus.9 (contents, props changed) head/sys/dev/pwm/ head/sys/dev/pwm/ofw_pwm.c (contents, props changed) head/sys/dev/pwm/pwm_if.m (contents, props changed) head/sys/dev/pwm/pwmbus.c (contents, props changed) head/sys/dev/pwm/pwmbus.h (contents, props changed) head/sys/dev/pwm/pwmbus_if.m (contents, props changed) head/sys/dev/pwm/pwmc.c (contents, props changed) head/sys/sys/pwm.h (contents, props changed) head/usr.sbin/pwm/ head/usr.sbin/pwm/Makefile (contents, props changed) head/usr.sbin/pwm/pwm.8 (contents, props changed) head/usr.sbin/pwm/pwm.c (contents, props changed) Modified: head/share/man/man9/Makefile head/sys/conf/files head/usr.sbin/Makefile Modified: head/share/man/man9/Makefile ============================================================================== --- head/share/man/man9/Makefile Wed Dec 12 20:40:01 2018 (r342002) +++ head/share/man/man9/Makefile Wed Dec 12 20:56:56 2018 (r342003) @@ -269,6 +269,8 @@ MAN= accept_filter.9 \ proc_rwmem.9 \ pseudofs.9 \ psignal.9 \ + pwm.9 \ + pwmbus.9 \ random.9 \ random_harvest.9 \ ratecheck.9 \ Added: head/share/man/man9/pwm.9 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/share/man/man9/pwm.9 Wed Dec 12 20:56:56 2018 (r342003) @@ -0,0 +1,93 @@ +.\" Copyright (c) 2018 Emmanuel Vadot +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd November 12, 2018 +.Dt PWM 9 +.Os +.Sh NAME +.Nm pwm , +.Nm PWM_GET_BUS , +.Nm PWM_CHANNEL_CONFIG , +.Nm PWM_CHANNEL_GET_CONFIG , +.Nm PWM_CHANNEL_SET_FLAGS , +.Nm PWM_CHANNEL_GET_FLAGS , +.Nm PWM_CHANNEL_ENABLE , +.Nm PWM_CHANNEL_IS_ENABLED , +.Nm PWM_CHANNEL_MAX +.Nd PWM methods +.Sh SYNOPSIS +.Cd "device pwm" +.In "pwm_if.h" +.Ft device_t +.Fn PWM_GET_BUS "device_t dev" +.Ft int +.Fn PWM_CHANNEL_CONFIG "device_t dev" "int channel" "uint64_t period" "uint64_t duty" +.Ft int +.Fn PWM_CHANNEL_GET_CONFIG "device_t dev" "int channel" "uint64_t *period" "uint64_t *duty" +.Ft int +.Fn PWM_CHANNEL_SET_FLAGS "device_t dev" "int channel" "uint32_t flags" +.Ft int +.Fn PWM_CHANNEL_GET_FLAGS "device_t dev" "int channel" "uint32_t *flags" +.Ft int +.Fn PWM_CHANNEL_ENABLE "device_t dev" "int channel" "bool enable" +.Ft int +.Fn PWM_CHANNEL_IS_ENABLED "device_t dev" "int channel" "bool *enabled" +.Ft int +.Fn PWM_CHANNEL_MAX "device_t dev" "int channel" "int *nchannel" +.Sh DESCRIPTION +The PWM (Pulse-Width Modulation) interface allows the device driver to register to a global +bus so other devices in the kernel can use them in a generic way. +.Sh INTERFACE +.Bl -tag -width indent +.It Fn PWM_GET_BUS "device_t dev" +Return the bus device. +.It Fn PWM_CHANNEL_CONFIG "device_t dev" "int channel" "uint64_t period" "uint64_t duty" +Configure the period and duty (in nanoseconds) in the PWM controller for the specified channel. +Returns 0 on success or +.Er EINVAL +if the values are not supported by the controller or +.Er EBUSY +is the PWM controller is in use and does not support changing the value on the fly. +.It Fn PWM_CHANNEL_GET_CONFIG "device_t dev" "int channel" "uint64_t *period" "uint64_t *duty" +Get the current configuration of the period and duty for the specified channel. +.It Fn PWM_CHANNEL_SET_FLAGS "device_t dev" "int channel" "uint32_t flags" +Set the flags of the channel (like inverted polarity). +.It Fn PWM_CHANNEL_GET_FLAGS "device_t dev" "int channel" "uint32_t *flags" +Get the current flags for the channel. +.It Fn PWM_CHANNEL_ENABLE "device_t dev" "int channel" "bool enable" +Enable the PWM channel. +.It Fn PWM_CHANNEL_ISENABLED "device_t dev" "int channel" "bool *enable" +Test if the PWM channel is enabled. +.It PWM_CHANNEL_MAX "device_t dev" "int channel" "int *nchannel" +Get the maximum number of channels supported by the controller. +.El +.Sh HISTORY +The +.Nm pwm +interface first appeared in +.Fx 13.0 . +The +.Nm pwm +interface and manual page was written by +.An Emmanuel Vadot Aq Mt manu@FreeBSD.org . Added: head/share/man/man9/pwmbus.9 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/share/man/man9/pwmbus.9 Wed Dec 12 20:56:56 2018 (r342003) @@ -0,0 +1,98 @@ +.\" Copyright (c) 2018 Emmanuel Vadot +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd November 12, 2018 +.Dt PWMBUS 9 +.Os +.Sh NAME +.Nm pwmbus , +.Nm pwmbus_attach_bus , +.Nm PWMBUS_GET_BUS , +.Nm PWMBUS_CHANNEL_CONFIG , +.Nm PWMBUS_CHANNEL_GET_CONFIG , +.Nm PWMBUS_CHANNEL_SET_FLAGS , +.Nm PWMBUS_CHANNEL_GET_FLAGS , +.Nm PWMBUS_CHANNEL_ENABLE , +.Nm PWMBUS_CHANNEL_IS_ENABLED , +.Nm PWMBUS_CHANNEL_MAX +.Nd PWMBUS methods +.Sh SYNOPSIS +.Cd "device pwm" +.In "pwmbus_if.h" +.Ft device_t +.Fn pwmbus_attach_bus "device_t dev" +.Ft int +.Fn PWMBUS_CHANNEL_CONFIG "device_t bus" "int channel" "uint64_t period" "uint64_t duty" +.Ft int +.Fn PWMBUS_CHANNEL_GET_CONFIG "device_t bus" "int channel" "uint64_t *period" "uint64_t *duty" +.Ft int +.Fn PWMBUS_CHANNEL_SET_FLAGS "device_t bus" "int channel" "uint32_t flags" +.Ft int +.Fn PWMBUS_CHANNEL_GET_FLAGS "device_t bus" "int channel" "uint32_t *flags" +.Ft int +.Fn PWMBUS_CHANNEL_ENABLE "device_t bus" "int channel" "bool enable" +.Ft int +.Fn PWMBUS_CHANNEL_IS_ENABLED "device_t bus" "int channel" "bool *enabled" +.Ft int +.Fn PWMBUS_CHANNEL_MAX "device_t bus" "int channel" "int *nchannel" +.Sh DESCRIPTION +The PWMBUS (Pulse-Width Modulation) interface allows the device driver to register to a global +bus so other devices in the kernel can use them in a generic way +.Sh INTERFACE +.Bl -tag -width indent +.It Fn pwmbus_attach_bus "device_t dev" +Attach the +.Nm pwmbus +to the device driver +.It Fn PWMBUS_CHANNEL_CONFIG "device_t bus" "int channel" "uint64_t period" "uint64_t duty" +Configure the period and duty (in nanoseconds) in the PWM controller on the bus for the specified channel. +Returns 0 on success or +.Er EINVAL +is the values are not supported by the controller or +.Er EBUSY +is the PWMBUS controller is in use and doesn't support changing the value on the fly. +.It Fn PWMBUS_CHANNEL_GET_CONFIG "device_t bus" "int channel" "uint64_t *period" "uint64_t *duty" +Get the current configuration of the period and duty for the specified channel. +.It Fn PWMBUS_CHANNEL_SET_FLAGS "device_t bus" "int channel" "uint32_t flags" +Set the flags of the channel (like inverted polarity), if the driver or controller +doesn't support this a default method is used. +.It Fn PWMBUS_CHANNEL_GET_FLAGS "device_t bus" "int channel" "uint32_t *flags" +Get the current flags for the channel, if the driver or controller +doesn't support this, a default method is used. +.It Fn PWMBUS_CHANNEL_ENABLE "device_t bus" "int channel" "bool enable" +Enable the PWM channel. +.It Fn PWMBUS_CHANNEL_ISENABLED "device_t bus" "int channel" "bool *enable" +Test if the PWM channel is enabled. +.It PWMBUS_CHANNEL_MAX "device_t bus" "int channel" "int *nchannel" +Get the maximum number of channel supported by the controller. +.El +.Sh HISTORY +The +.Nm pwmbus +interface first appear in +.Fx 13.0 . +The +.Nm pwmbus +interface and manual page was written by +.An Emmanuel Vadot Aq Mt manu@FreeBSD.org . Modified: head/sys/conf/files ============================================================================== --- head/sys/conf/files Wed Dec 12 20:40:01 2018 (r342002) +++ head/sys/conf/files Wed Dec 12 20:56:56 2018 (r342003) @@ -2746,6 +2746,11 @@ dev/puc/puc.c optional puc dev/puc/puc_cfg.c optional puc dev/puc/puc_pccard.c optional puc pccard dev/puc/puc_pci.c optional puc pci +dev/pwm/pwmc.c optional pwm +dev/pwm/pwmbus.c optional pwm +dev/pwm/pwm_if.m optional pwm +dev/pwm/pwmbus_if.m optional pwm +dev/pwm/ofw_pwm.c optional pwm fdt dev/quicc/quicc_core.c optional quicc dev/ral/rt2560.c optional ral dev/ral/rt2661.c optional ral Added: head/sys/dev/pwm/ofw_pwm.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/dev/pwm/ofw_pwm.c Wed Dec 12 20:56:56 2018 (r342003) @@ -0,0 +1,109 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2018 Emmanuel Vadot + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "pwm_if.h" + +int +pwm_get_by_ofw_propidx(device_t consumer, phandle_t node, + const char *prop_name, int idx, pwm_channel_t *out_channel) +{ + phandle_t xref; + pcell_t *cells; + struct pwm_channel channel; + int ncells, rv; + + rv = ofw_bus_parse_xref_list_alloc(node, prop_name, "#pwm-cells", + idx, &xref, &ncells, &cells); + if (rv != 0) + return (rv); + + channel.dev = OF_device_from_xref(xref); + if (channel.dev == NULL) { + OF_prop_free(cells); + return (ENODEV); + } + + channel.busdev = PWM_GET_BUS(channel.dev); + if (channel.busdev == NULL) { + OF_prop_free(cells); + return (ENODEV); + } + + channel.channel = cells[0]; + channel.period = cells[1]; + + if (ncells >= 3) + channel.flags = cells[2]; + + *out_channel = malloc(sizeof(struct pwm_channel), M_DEVBUF, M_WAITOK | M_ZERO); + **out_channel = channel; + return (0); +} + +int +pwm_get_by_ofw_idx(device_t consumer, phandle_t node, int idx, + pwm_channel_t *out_channel) +{ + + return (pwm_get_by_ofw_propidx(consumer, node, "pwms", idx, out_channel)); +} + +int +pwm_get_by_ofw_property(device_t consumer, phandle_t node, + const char *prop_name, pwm_channel_t *out_channel) +{ + + return (pwm_get_by_ofw_propidx(consumer, node, prop_name, 0, out_channel)); +} + +int +pwm_get_by_ofw_name(device_t consumer, phandle_t node, const char *name, + pwm_channel_t *out_channel) +{ + int rv, idx; + + rv = ofw_bus_find_string_index(node, "pwm-names", name, &idx); + if (rv != 0) + return (rv); + + return (pwm_get_by_ofw_idx(consumer, node, idx, out_channel)); +} Added: head/sys/dev/pwm/pwm_if.m ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/dev/pwm/pwm_if.m Wed Dec 12 20:56:56 2018 (r342003) @@ -0,0 +1,106 @@ +#- +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Emmanuel Vadot +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ +# + +#include + +INTERFACE pwm; + +# +# Get the bus +# + +METHOD device_t get_bus { + device_t dev; +}; + +# +# Config the period (Total number of cycle in ns) and +# the duty (active number of cycle in ns) +# +METHOD int channel_config { + device_t dev; + int channel; + uint64_t period; + uint64_t duty; +}; + +# +# Get the period (Total number of cycle in ns) and +# the duty (active number of cycle in ns) +# +METHOD int channel_get_config { + device_t dev; + int channel; + uint64_t *period; + uint64_t *duty; +}; + +# +# Set the flags +# +METHOD int channel_set_flags { + device_t dev; + int channel; + uint32_t flags; +}; + +# +# Get the flags +# +METHOD int channel_get_flags { + device_t dev; + int channel; + uint32_t *flags; +}; + +# +# Enable the pwm output +# +METHOD int channel_enable { + device_t dev; + int channel; + bool enable; +}; + +# +# Is the pwm output enabled +# +METHOD int channel_is_enabled { + device_t dev; + int channel; + bool *enabled; +}; + +# +# Get the number of channels +# +METHOD int channel_max { + device_t dev; + int *nchannel; +}; Added: head/sys/dev/pwm/pwmbus.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/dev/pwm/pwmbus.c Wed Dec 12 20:56:56 2018 (r342003) @@ -0,0 +1,244 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2018 Emmanuel Vadot + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "opt_platform.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#include "pwmbus_if.h" +#include "pwm_if.h" + +struct pwmbus_channel_data { + int reserved; + char *name; +}; + +struct pwmbus_softc { + device_t busdev; + device_t dev; + + int nchannels; +}; + +device_t +pwmbus_attach_bus(device_t dev) +{ + device_t busdev; +#ifdef FDT + phandle_t node; +#endif + + busdev = device_add_child(dev, "pwmbus", -1); + if (busdev == NULL) { + device_printf(dev, "Cannot add child pwmbus\n"); + return (NULL); + } + if (device_add_child(dev, "pwmc", -1) == NULL) { + device_printf(dev, "Cannot add pwmc\n"); + device_delete_child(dev, busdev); + return (NULL); + } + +#ifdef FDT + node = ofw_bus_get_node(dev); + OF_device_register_xref(OF_xref_from_node(node), dev); +#endif + + bus_generic_attach(dev); + + return (busdev); +} + +static int +pwmbus_probe(device_t dev) +{ + + device_set_desc(dev, "PWM bus"); + return (BUS_PROBE_GENERIC); +} + +static int +pwmbus_attach(device_t dev) +{ + struct pwmbus_softc *sc; + + sc = device_get_softc(dev); + sc->busdev = dev; + sc->dev = device_get_parent(dev); + + if (PWM_CHANNEL_MAX(sc->dev, &sc->nchannels) != 0 || + sc->nchannels == 0) + return (ENXIO); + + if (bootverbose) + device_printf(dev, "Registering %d channel(s)\n", sc->nchannels); + bus_generic_probe(dev); + + return (bus_generic_attach(dev)); +} + +static int +pwmbus_detach(device_t dev) +{ + device_t *devlist; + int i, rv, ndevs; + + rv = bus_generic_detach(dev); + if (rv != 0) + return (rv); + + rv = device_get_children(dev, &devlist, &ndevs); + if (rv != 0) + return (rv); + for (i = 0; i < ndevs; i++) + device_delete_child(dev, devlist[i]); + + return (0); +} + +static int +pwmbus_channel_config(device_t bus, int channel, uint64_t period, uint64_t duty) +{ + struct pwmbus_softc *sc; + + sc = device_get_softc(bus); + + if (channel > sc->nchannels) + return (EINVAL); + + return (PWM_CHANNEL_CONFIG(sc->dev, channel, period, duty)); +} + +static int +pwmbus_channel_get_config(device_t bus, int channel, uint64_t *period, uint64_t *duty) +{ + struct pwmbus_softc *sc; + + sc = device_get_softc(bus); + + if (channel > sc->nchannels) + return (EINVAL); + + return (PWM_CHANNEL_GET_CONFIG(sc->dev, channel, period, duty)); +} + +static int +pwmbus_channel_set_flags(device_t bus, int channel, uint32_t flags) +{ + struct pwmbus_softc *sc; + + sc = device_get_softc(bus); + + if (channel > sc->nchannels) + return (EINVAL); + + return (PWM_CHANNEL_SET_FLAGS(sc->dev, channel, flags)); +} + +static int +pwmbus_channel_get_flags(device_t bus, int channel, uint32_t *flags) +{ + struct pwmbus_softc *sc; + + sc = device_get_softc(bus); + + if (channel > sc->nchannels) + return (EINVAL); + + return (PWM_CHANNEL_GET_FLAGS(sc->dev, channel, flags)); +} + +static int +pwmbus_channel_enable(device_t bus, int channel, bool enable) +{ + struct pwmbus_softc *sc; + + sc = device_get_softc(bus); + + if (channel > sc->nchannels) + return (EINVAL); + + return (PWM_CHANNEL_ENABLE(sc->dev, channel, enable)); +} + +static int +pwmbus_channel_is_enabled(device_t bus, int channel, bool *enable) +{ + struct pwmbus_softc *sc; + + sc = device_get_softc(bus); + + if (channel > sc->nchannels) + return (EINVAL); + + return (PWM_CHANNEL_IS_ENABLED(sc->dev, channel, enable)); +} + +static device_method_t pwmbus_methods[] = { + /* device_if */ + DEVMETHOD(device_probe, pwmbus_probe), + DEVMETHOD(device_attach, pwmbus_attach), + DEVMETHOD(device_detach, pwmbus_detach), + + /* pwm interface */ + DEVMETHOD(pwmbus_channel_config, pwmbus_channel_config), + DEVMETHOD(pwmbus_channel_get_config, pwmbus_channel_get_config), + DEVMETHOD(pwmbus_channel_set_flags, pwmbus_channel_set_flags), + DEVMETHOD(pwmbus_channel_get_flags, pwmbus_channel_get_flags), + DEVMETHOD(pwmbus_channel_enable, pwmbus_channel_enable), + DEVMETHOD(pwmbus_channel_is_enabled, pwmbus_channel_is_enabled), + + DEVMETHOD_END +}; + +driver_t pwmbus_driver = { + "pwmbus", + pwmbus_methods, + sizeof(struct pwmbus_softc), +}; +devclass_t pwmbus_devclass; + +EARLY_DRIVER_MODULE(pwmbus, pwm, pwmbus_driver, pwmbus_devclass, 0, 0, + BUS_PASS_SUPPORTDEV + BUS_PASS_ORDER_MIDDLE); +MODULE_VERSION(pwmbus, 1); Added: head/sys/dev/pwm/pwmbus.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/dev/pwm/pwmbus.h Wed Dec 12 20:56:56 2018 (r342003) @@ -0,0 +1,64 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2018 Emmanuel Vadot + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _PWMBUS_H_ + +#include +#include + +struct pwm_channel { + device_t dev; + device_t busdev; + int channel; + uint64_t period; + uint64_t duty; + uint32_t flags; + bool enabled; +}; +typedef struct pwm_channel *pwm_channel_t; + +device_t pwmbus_attach_bus(device_t dev); +int pwmbus_acquire_channel(device_t bus, int channel); +int pwmbus_release_channel(device_t bus, int channel); + +int +pwm_get_by_ofw_propidx(device_t consumer, phandle_t node, + const char *prop_name, int idx, pwm_channel_t *channel); +int +pwm_get_by_ofw_idx(device_t consumer, phandle_t node, int idx, + pwm_channel_t *out_channel); +int +pwm_get_by_ofw_property(device_t consumer, phandle_t node, + const char *prop_name, pwm_channel_t *out_channel); +int +pwm_get_by_ofw_name(device_t consumer, phandle_t node, const char *name, + pwm_channel_t *out_channel); + +#endif /* _PWMBUS_H_ */ Added: head/sys/dev/pwm/pwmbus_if.m ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/dev/pwm/pwmbus_if.m Wed Dec 12 20:56:56 2018 (r342003) @@ -0,0 +1,111 @@ +#- +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Emmanuel Vadot +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ +# + +#include + +INTERFACE pwmbus; + +CODE { + static int + pwm_default_set_flags(device_t dev, int channel, uint32_t flags) + { + + return (EOPNOTSUPP); + } + + static int + pwm_default_get_flags(device_t dev, int channel, uint32_t *flags) + { + + *flags = 0; + return (0); + } +}; + +HEADER { + #include +}; + +# +# Config the period (Total number of cycle in ns) and +# the duty (active number of cycle in ns) +# +METHOD int channel_config { + device_t bus; + int channel; + uint64_t period; + uint64_t duty; +}; + +# +# Get the period (Total number of cycle in ns) and +# the duty (active number of cycle in ns) +# +METHOD int channel_get_config { + device_t bus; + int channel; + uint64_t *period; + uint64_t *duty; +}; + +# +# Set the flags +# +METHOD int channel_set_flags { + device_t bus; + int channel; + uint32_t flags; +} DEFAULT pwm_default_set_flags; + +# +# Get the flags +# +METHOD int channel_get_flags { + device_t dev; + int channel; + uint32_t *flags; +} DEFAULT pwm_default_get_flags; + +# +# Enable the pwm output +# +METHOD int channel_enable { + device_t bus; + int channel; + bool enable; +}; + +# +# Is the pwm output enabled +# +METHOD int channel_is_enabled { + device_t bus; + int channel; + bool *enabled; +}; Added: head/sys/dev/pwm/pwmc.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/dev/pwm/pwmc.c Wed Dec 12 20:56:56 2018 (r342003) @@ -0,0 +1,161 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2018 Emmanuel Vadot + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "pwmbus_if.h" +#include "pwm_if.h" + +struct pwmc_softc { + device_t dev; + device_t pdev; + struct cdev *pwm_dev; + char name[32]; +}; + +static int +pwm_ioctl(struct cdev *dev, u_long cmd, caddr_t data, + int fflag, struct thread *td) +{ + struct pwmc_softc *sc; + struct pwm_state state; + device_t bus; + int nchannel; + int rv = 0; + + sc = dev->si_drv1; + bus = PWM_GET_BUS(sc->pdev); + if (bus == NULL) + return (EINVAL); + + switch (cmd) { + case PWMMAXCHANNEL: + nchannel = -1; + rv = PWM_CHANNEL_MAX(sc->pdev, &nchannel); + bcopy(&nchannel, data, sizeof(nchannel)); + break; + case PWMSETSTATE: + bcopy(data, &state, sizeof(state)); + rv = PWMBUS_CHANNEL_CONFIG(bus, state.channel, + state.period, state.duty); + if (rv == 0) + rv = PWMBUS_CHANNEL_ENABLE(bus, state.channel, + state.enable); + break; + case PWMGETSTATE: + bcopy(data, &state, sizeof(state)); + rv = PWMBUS_CHANNEL_GET_CONFIG(bus, state.channel, + &state.period, &state.duty); + if (rv != 0) + return (rv); + rv = PWMBUS_CHANNEL_IS_ENABLED(bus, state.channel, + &state.enable); + if (rv != 0) + return (rv); + bcopy(&state, data, sizeof(state)); + break; + } + + return (rv); +} + +static struct cdevsw pwm_cdevsw = { + .d_version = D_VERSION, + .d_name = "pwm", + .d_ioctl = pwm_ioctl +}; + +static int +pwmc_probe(device_t dev) +{ + + device_set_desc(dev, "PWM Controller"); + return (0); +} + +static int +pwmc_attach(device_t dev) +{ + struct pwmc_softc *sc; + struct make_dev_args args; + + sc = device_get_softc(dev); + sc->dev = dev; + sc->pdev = device_get_parent(dev); + + snprintf(sc->name, sizeof(sc->name), "pwmc%d", device_get_unit(dev)); + make_dev_args_init(&args); + args.mda_flags = MAKEDEV_CHECKNAME | MAKEDEV_WAITOK; + args.mda_devsw = &pwm_cdevsw; + args.mda_uid = UID_ROOT; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***