19312900fSEmmanuel Vadot /*- 2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 39312900fSEmmanuel Vadot * 49312900fSEmmanuel Vadot * Copyright (c) 2018 Emmanuel Vadot <manu@FreeBSD.org> 59312900fSEmmanuel Vadot * 69312900fSEmmanuel Vadot * Redistribution and use in source and binary forms, with or without 79312900fSEmmanuel Vadot * modification, are permitted provided that the following conditions 89312900fSEmmanuel Vadot * are met: 99312900fSEmmanuel Vadot * 1. Redistributions of source code must retain the above copyright 109312900fSEmmanuel Vadot * notice, this list of conditions and the following disclaimer. 119312900fSEmmanuel Vadot * 2. Redistributions in binary form must reproduce the above copyright 129312900fSEmmanuel Vadot * notice, this list of conditions and the following disclaimer in the 139312900fSEmmanuel Vadot * documentation and/or other materials provided with the distribution. 149312900fSEmmanuel Vadot * 159312900fSEmmanuel Vadot * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 169312900fSEmmanuel Vadot * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 179312900fSEmmanuel Vadot * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 189312900fSEmmanuel Vadot * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 199312900fSEmmanuel Vadot * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 209312900fSEmmanuel Vadot * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 219312900fSEmmanuel Vadot * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 229312900fSEmmanuel Vadot * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 239312900fSEmmanuel Vadot * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 249312900fSEmmanuel Vadot * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 259312900fSEmmanuel Vadot * SUCH DAMAGE. 269312900fSEmmanuel Vadot */ 279312900fSEmmanuel Vadot 289312900fSEmmanuel Vadot #include <sys/cdefs.h> 299312900fSEmmanuel Vadot __FBSDID("$FreeBSD$"); 309312900fSEmmanuel Vadot 319312900fSEmmanuel Vadot #include <sys/param.h> 329312900fSEmmanuel Vadot #include <sys/systm.h> 339312900fSEmmanuel Vadot #include <sys/bus.h> 349312900fSEmmanuel Vadot #include <sys/kernel.h> 359312900fSEmmanuel Vadot #include <sys/resource.h> 369312900fSEmmanuel Vadot 379312900fSEmmanuel Vadot #include <dev/ofw/ofw_bus.h> 389312900fSEmmanuel Vadot #include <dev/ofw/ofw_bus_subr.h> 399312900fSEmmanuel Vadot 40b9353973SIan Lepore #include <dev/pwm/ofw_pwm.h> 419312900fSEmmanuel Vadot 429312900fSEmmanuel Vadot int 439312900fSEmmanuel Vadot pwm_get_by_ofw_propidx(device_t consumer, phandle_t node, 449312900fSEmmanuel Vadot const char *prop_name, int idx, pwm_channel_t *out_channel) 459312900fSEmmanuel Vadot { 469312900fSEmmanuel Vadot phandle_t xref; 479312900fSEmmanuel Vadot pcell_t *cells; 489312900fSEmmanuel Vadot struct pwm_channel channel; 499312900fSEmmanuel Vadot int ncells, rv; 509312900fSEmmanuel Vadot 519312900fSEmmanuel Vadot rv = ofw_bus_parse_xref_list_alloc(node, prop_name, "#pwm-cells", 529312900fSEmmanuel Vadot idx, &xref, &ncells, &cells); 539312900fSEmmanuel Vadot if (rv != 0) 549312900fSEmmanuel Vadot return (rv); 559312900fSEmmanuel Vadot 569312900fSEmmanuel Vadot channel.dev = OF_device_from_xref(xref); 579312900fSEmmanuel Vadot if (channel.dev == NULL) { 589312900fSEmmanuel Vadot OF_prop_free(cells); 599312900fSEmmanuel Vadot return (ENODEV); 609312900fSEmmanuel Vadot } 619312900fSEmmanuel Vadot 629312900fSEmmanuel Vadot channel.channel = cells[0]; 639312900fSEmmanuel Vadot channel.period = cells[1]; 649312900fSEmmanuel Vadot 659312900fSEmmanuel Vadot if (ncells >= 3) 669312900fSEmmanuel Vadot channel.flags = cells[2]; 679312900fSEmmanuel Vadot 689312900fSEmmanuel Vadot *out_channel = malloc(sizeof(struct pwm_channel), M_DEVBUF, M_WAITOK | M_ZERO); 699312900fSEmmanuel Vadot **out_channel = channel; 709312900fSEmmanuel Vadot return (0); 719312900fSEmmanuel Vadot } 729312900fSEmmanuel Vadot 739312900fSEmmanuel Vadot int 749312900fSEmmanuel Vadot pwm_get_by_ofw_idx(device_t consumer, phandle_t node, int idx, 759312900fSEmmanuel Vadot pwm_channel_t *out_channel) 769312900fSEmmanuel Vadot { 779312900fSEmmanuel Vadot 789312900fSEmmanuel Vadot return (pwm_get_by_ofw_propidx(consumer, node, "pwms", idx, out_channel)); 799312900fSEmmanuel Vadot } 809312900fSEmmanuel Vadot 819312900fSEmmanuel Vadot int 829312900fSEmmanuel Vadot pwm_get_by_ofw_property(device_t consumer, phandle_t node, 839312900fSEmmanuel Vadot const char *prop_name, pwm_channel_t *out_channel) 849312900fSEmmanuel Vadot { 859312900fSEmmanuel Vadot 869312900fSEmmanuel Vadot return (pwm_get_by_ofw_propidx(consumer, node, prop_name, 0, out_channel)); 879312900fSEmmanuel Vadot } 889312900fSEmmanuel Vadot 899312900fSEmmanuel Vadot int 909312900fSEmmanuel Vadot pwm_get_by_ofw_name(device_t consumer, phandle_t node, const char *name, 919312900fSEmmanuel Vadot pwm_channel_t *out_channel) 929312900fSEmmanuel Vadot { 939312900fSEmmanuel Vadot int rv, idx; 949312900fSEmmanuel Vadot 959312900fSEmmanuel Vadot rv = ofw_bus_find_string_index(node, "pwm-names", name, &idx); 969312900fSEmmanuel Vadot if (rv != 0) 979312900fSEmmanuel Vadot return (rv); 989312900fSEmmanuel Vadot 999312900fSEmmanuel Vadot return (pwm_get_by_ofw_idx(consumer, node, idx, out_channel)); 1009312900fSEmmanuel Vadot } 101