linux/drivers/pwm/core.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Generic pwmlib implementation
 *
 * Copyright (C) 2011 Sascha Hauer <[email protected]>
 * Copyright (C) 2011-2012 Avionic Design GmbH
 */

#define DEFAULT_SYMBOL_NAMESPACE

#include <linux/acpi.h>
#include <linux/module.h>
#include <linux/idr.h>
#include <linux/of.h>
#include <linux/pwm.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>

#include <dt-bindings/pwm/pwm.h>

#define CREATE_TRACE_POINTS
#include <trace/events/pwm.h>

/* protects access to pwm_chips */
static DEFINE_MUTEX(pwm_lock);

static DEFINE_IDR(pwm_chips);

static void pwm_apply_debug(struct pwm_device *pwm,
			    const struct pwm_state *state)
{}

static bool pwm_state_valid(const struct pwm_state *state)
{}

/**
 * __pwm_apply() - atomically apply a new state to a PWM device
 * @pwm: PWM device
 * @state: new state to apply
 */
static int __pwm_apply(struct pwm_device *pwm, const struct pwm_state *state)
{}

/**
 * pwm_apply_might_sleep() - atomically apply a new state to a PWM device
 * Cannot be used in atomic context.
 * @pwm: PWM device
 * @state: new state to apply
 */
int pwm_apply_might_sleep(struct pwm_device *pwm, const struct pwm_state *state)
{}
EXPORT_SYMBOL_GPL();

/**
 * pwm_apply_atomic() - apply a new state to a PWM device from atomic context
 * Not all PWM devices support this function, check with pwm_might_sleep().
 * @pwm: PWM device
 * @state: new state to apply
 */
int pwm_apply_atomic(struct pwm_device *pwm, const struct pwm_state *state)
{}
EXPORT_SYMBOL_GPL();

/**
 * pwm_adjust_config() - adjust the current PWM config to the PWM arguments
 * @pwm: PWM device
 *
 * This function will adjust the PWM config to the PWM arguments provided
 * by the DT or PWM lookup table. This is particularly useful to adapt
 * the bootloader config to the Linux one.
 */
int pwm_adjust_config(struct pwm_device *pwm)
{}
EXPORT_SYMBOL_GPL();

/**
 * pwm_capture() - capture and report a PWM signal
 * @pwm: PWM device
 * @result: structure to fill with capture result
 * @timeout: time to wait, in milliseconds, before giving up on capture
 *
 * Returns: 0 on success or a negative error code on failure.
 */
int pwm_capture(struct pwm_device *pwm, struct pwm_capture *result,
		unsigned long timeout)
{}
EXPORT_SYMBOL_GPL();

static struct pwm_chip *pwmchip_find_by_name(const char *name)
{}

static int pwm_device_request(struct pwm_device *pwm, const char *label)
{}

/**
 * pwm_request_from_chip() - request a PWM device relative to a PWM chip
 * @chip: PWM chip
 * @index: per-chip index of the PWM to request
 * @label: a literal description string of this PWM
 *
 * Returns: A pointer to the PWM device at the given index of the given PWM
 * chip. A negative error code is returned if the index is not valid for the
 * specified PWM chip or if the PWM device cannot be requested.
 */
static struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip,
						unsigned int index,
						const char *label)
{}

struct pwm_device *
of_pwm_xlate_with_flags(struct pwm_chip *chip, const struct of_phandle_args *args)
{}
EXPORT_SYMBOL_GPL();

struct pwm_device *
of_pwm_single_xlate(struct pwm_chip *chip, const struct of_phandle_args *args)
{}
EXPORT_SYMBOL_GPL();

struct pwm_export {};

static inline struct pwm_chip *pwmchip_from_dev(struct device *pwmchip_dev)
{}

static inline struct pwm_export *pwmexport_from_dev(struct device *pwm_dev)
{}

static inline struct pwm_device *pwm_from_dev(struct device *pwm_dev)
{}

static ssize_t period_show(struct device *pwm_dev,
			   struct device_attribute *attr,
			   char *buf)
{}

static ssize_t period_store(struct device *pwm_dev,
			    struct device_attribute *attr,
			    const char *buf, size_t size)
{}

static ssize_t duty_cycle_show(struct device *pwm_dev,
			       struct device_attribute *attr,
			       char *buf)
{}

static ssize_t duty_cycle_store(struct device *pwm_dev,
				struct device_attribute *attr,
				const char *buf, size_t size)
{}

static ssize_t enable_show(struct device *pwm_dev,
			   struct device_attribute *attr,
			   char *buf)
{}

static ssize_t enable_store(struct device *pwm_dev,
			    struct device_attribute *attr,
			    const char *buf, size_t size)
{}

static ssize_t polarity_show(struct device *pwm_dev,
			     struct device_attribute *attr,
			     char *buf)
{}

static ssize_t polarity_store(struct device *pwm_dev,
			      struct device_attribute *attr,
			      const char *buf, size_t size)
{}

static ssize_t capture_show(struct device *pwm_dev,
			    struct device_attribute *attr,
			    char *buf)
{}

static DEVICE_ATTR_RW(period);
static DEVICE_ATTR_RW(duty_cycle);
static DEVICE_ATTR_RW(enable);
static DEVICE_ATTR_RW(polarity);
static DEVICE_ATTR_RO(capture);

static struct attribute *pwm_attrs[] =;
ATTRIBUTE_GROUPS();

static void pwm_export_release(struct device *pwm_dev)
{}

static int pwm_export_child(struct device *pwmchip_dev, struct pwm_device *pwm)
{}

static int pwm_unexport_match(struct device *pwm_dev, void *data)
{}

static int pwm_unexport_child(struct device *pwmchip_dev, struct pwm_device *pwm)
{}

static ssize_t export_store(struct device *pwmchip_dev,
			    struct device_attribute *attr,
			    const char *buf, size_t len)
{}
static DEVICE_ATTR_WO(export);

static ssize_t unexport_store(struct device *pwmchip_dev,
			      struct device_attribute *attr,
			      const char *buf, size_t len)
{}
static DEVICE_ATTR_WO(unexport);

static ssize_t npwm_show(struct device *pwmchip_dev, struct device_attribute *attr,
			 char *buf)
{}
static DEVICE_ATTR_RO(npwm);

static struct attribute *pwm_chip_attrs[] =;
ATTRIBUTE_GROUPS();

/* takes export->lock on success */
static struct pwm_export *pwm_class_get_state(struct device *pwmchip_dev,
					      struct pwm_device *pwm,
					      struct pwm_state *state)
{}

static int pwm_class_apply_state(struct pwm_export *export,
				 struct pwm_device *pwm,
				 struct pwm_state *state)
{}

static int pwm_class_resume_npwm(struct device *pwmchip_dev, unsigned int npwm)
{}

static int pwm_class_suspend(struct device *pwmchip_dev)
{}

static int pwm_class_resume(struct device *pwmchip_dev)
{}

static DEFINE_SIMPLE_DEV_PM_OPS(pwm_class_pm_ops, pwm_class_suspend, pwm_class_resume);

static struct class pwm_class =;

static void pwmchip_sysfs_unexport(struct pwm_chip *chip)
{}

#define PWMCHIP_ALIGN

static void *pwmchip_priv(struct pwm_chip *chip)
{}

/* This is the counterpart to pwmchip_alloc() */
void pwmchip_put(struct pwm_chip *chip)
{}
EXPORT_SYMBOL_GPL();

static void pwmchip_release(struct device *pwmchip_dev)
{}

struct pwm_chip *pwmchip_alloc(struct device *parent, unsigned int npwm, size_t sizeof_priv)
{}
EXPORT_SYMBOL_GPL();

static void devm_pwmchip_put(void *data)
{}

struct pwm_chip *devm_pwmchip_alloc(struct device *parent, unsigned int npwm, size_t sizeof_priv)
{}
EXPORT_SYMBOL_GPL();

static void of_pwmchip_add(struct pwm_chip *chip)
{}

static void of_pwmchip_remove(struct pwm_chip *chip)
{}

static bool pwm_ops_check(const struct pwm_chip *chip)
{}

/**
 * __pwmchip_add() - register a new PWM chip
 * @chip: the PWM chip to add
 * @owner: reference to the module providing the chip.
 *
 * Register a new PWM chip. @owner is supposed to be THIS_MODULE, use the
 * pwmchip_add wrapper to do this right.
 *
 * Returns: 0 on success or a negative error code on failure.
 */
int __pwmchip_add(struct pwm_chip *chip, struct module *owner)
{}
EXPORT_SYMBOL_GPL();

/**
 * pwmchip_remove() - remove a PWM chip
 * @chip: the PWM chip to remove
 *
 * Removes a PWM chip.
 */
void pwmchip_remove(struct pwm_chip *chip)
{}
EXPORT_SYMBOL_GPL();

static void devm_pwmchip_remove(void *data)
{}

int __devm_pwmchip_add(struct device *dev, struct pwm_chip *chip, struct module *owner)
{}
EXPORT_SYMBOL_GPL();

static struct device_link *pwm_device_link_add(struct device *dev,
					       struct pwm_device *pwm)
{}

static struct pwm_chip *fwnode_to_pwmchip(struct fwnode_handle *fwnode)
{}

/**
 * of_pwm_get() - request a PWM via the PWM framework
 * @dev: device for PWM consumer
 * @np: device node to get the PWM from
 * @con_id: consumer name
 *
 * Returns the PWM device parsed from the phandle and index specified in the
 * "pwms" property of a device tree node or a negative error-code on failure.
 * Values parsed from the device tree are stored in the returned PWM device
 * object.
 *
 * If con_id is NULL, the first PWM device listed in the "pwms" property will
 * be requested. Otherwise the "pwm-names" property is used to do a reverse
 * lookup of the PWM index. This also means that the "pwm-names" property
 * becomes mandatory for devices that look up the PWM device via the con_id
 * parameter.
 *
 * Returns: A pointer to the requested PWM device or an ERR_PTR()-encoded
 * error code on failure.
 */
static struct pwm_device *of_pwm_get(struct device *dev, struct device_node *np,
				     const char *con_id)
{}

/**
 * acpi_pwm_get() - request a PWM via parsing "pwms" property in ACPI
 * @fwnode: firmware node to get the "pwms" property from
 *
 * Returns the PWM device parsed from the fwnode and index specified in the
 * "pwms" property or a negative error-code on failure.
 * Values parsed from the device tree are stored in the returned PWM device
 * object.
 *
 * This is analogous to of_pwm_get() except con_id is not yet supported.
 * ACPI entries must look like
 * Package () {"pwms", Package ()
 *     { <PWM device reference>, <PWM index>, <PWM period> [, <PWM flags>]}}
 *
 * Returns: A pointer to the requested PWM device or an ERR_PTR()-encoded
 * error code on failure.
 */
static struct pwm_device *acpi_pwm_get(const struct fwnode_handle *fwnode)
{}

static DEFINE_MUTEX(pwm_lookup_lock);
static LIST_HEAD(pwm_lookup_list);

/**
 * pwm_add_table() - register PWM device consumers
 * @table: array of consumers to register
 * @num: number of consumers in table
 */
void pwm_add_table(struct pwm_lookup *table, size_t num)
{}

/**
 * pwm_remove_table() - unregister PWM device consumers
 * @table: array of consumers to unregister
 * @num: number of consumers in table
 */
void pwm_remove_table(struct pwm_lookup *table, size_t num)
{}

/**
 * pwm_get() - look up and request a PWM device
 * @dev: device for PWM consumer
 * @con_id: consumer name
 *
 * Lookup is first attempted using DT. If the device was not instantiated from
 * a device tree, a PWM chip and a relative index is looked up via a table
 * supplied by board setup code (see pwm_add_table()).
 *
 * Once a PWM chip has been found the specified PWM device will be requested
 * and is ready to be used.
 *
 * Returns: A pointer to the requested PWM device or an ERR_PTR()-encoded
 * error code on failure.
 */
struct pwm_device *pwm_get(struct device *dev, const char *con_id)
{}
EXPORT_SYMBOL_GPL();

/**
 * pwm_put() - release a PWM device
 * @pwm: PWM device
 */
void pwm_put(struct pwm_device *pwm)
{}
EXPORT_SYMBOL_GPL();

static void devm_pwm_release(void *pwm)
{}

/**
 * devm_pwm_get() - resource managed pwm_get()
 * @dev: device for PWM consumer
 * @con_id: consumer name
 *
 * This function performs like pwm_get() but the acquired PWM device will
 * automatically be released on driver detach.
 *
 * Returns: A pointer to the requested PWM device or an ERR_PTR()-encoded
 * error code on failure.
 */
struct pwm_device *devm_pwm_get(struct device *dev, const char *con_id)
{}
EXPORT_SYMBOL_GPL();

/**
 * devm_fwnode_pwm_get() - request a resource managed PWM from firmware node
 * @dev: device for PWM consumer
 * @fwnode: firmware node to get the PWM from
 * @con_id: consumer name
 *
 * Returns the PWM device parsed from the firmware node. See of_pwm_get() and
 * acpi_pwm_get() for a detailed description.
 *
 * Returns: A pointer to the requested PWM device or an ERR_PTR()-encoded
 * error code on failure.
 */
struct pwm_device *devm_fwnode_pwm_get(struct device *dev,
				       struct fwnode_handle *fwnode,
				       const char *con_id)
{}
EXPORT_SYMBOL_GPL();

static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s)
{}

static void *pwm_seq_start(struct seq_file *s, loff_t *pos)
{}

static void *pwm_seq_next(struct seq_file *s, void *v, loff_t *pos)
{}

static void pwm_seq_stop(struct seq_file *s, void *v)
{}

static int pwm_seq_show(struct seq_file *s, void *v)
{}

static const struct seq_operations pwm_debugfs_sops =;

DEFINE_SEQ_ATTRIBUTE();

static int __init pwm_init(void)
{}
subsys_initcall(pwm_init);