linux/drivers/pwm/pwm-xilinx.c

// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2021 Sean Anderson <[email protected]>
 *
 * Limitations:
 * - When changing both duty cycle and period, we may end up with one cycle
 *   with the old duty cycle and the new period. This is because the counters
 *   may only be reloaded by first stopping them, or by letting them be
 *   automatically reloaded at the end of a cycle. If this automatic reload
 *   happens after we set TLR0 but before we set TLR1 then we will have a
 *   bad cycle. This could probably be fixed by reading TCR0 just before
 *   reprogramming, but I think it would add complexity for little gain.
 * - Cannot produce 100% duty cycle by configuring the TLRs. This might be
 *   possible by stopping the counters at an appropriate point in the cycle,
 *   but this is not (yet) implemented.
 * - Only produces "normal" output.
 * - Always produces low output if disabled.
 */

#include <clocksource/timer-xilinx.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pwm.h>
#include <linux/regmap.h>

/*
 * The following functions are "common" to drivers for this device, and may be
 * exported at a future date.
 */
u32 xilinx_timer_tlr_cycles(struct xilinx_timer_priv *priv, u32 tcsr,
			    u64 cycles)
{}

unsigned int xilinx_timer_get_period(struct xilinx_timer_priv *priv,
				     u32 tlr, u32 tcsr)
{}

/*
 * The idea here is to capture whether the PWM is actually running (e.g.
 * because we or the bootloader set it up) and we need to be careful to ensure
 * we don't cause a glitch. According to the data sheet, to enable the PWM we
 * need to
 *
 * - Set both timers to generate mode (MDT=1)
 * - Set both timers to PWM mode (PWMA=1)
 * - Enable the generate out signals (GENT=1)
 *
 * In addition,
 *
 * - The timer must be running (ENT=1)
 * - The timer must auto-reload TLR into TCR (ARHT=1)
 * - We must not be in the process of loading TLR into TCR (LOAD=0)
 * - Cascade mode must be disabled (CASC=0)
 *
 * If any of these differ from usual, then the PWM is either disabled, or is
 * running in a mode that this driver does not support.
 */
#define TCSR_PWM_SET
#define TCSR_PWM_CLEAR
#define TCSR_PWM_MASK

static inline struct xilinx_timer_priv
*xilinx_pwm_chip_to_priv(struct pwm_chip *chip)
{}

static bool xilinx_timer_pwm_enabled(u32 tcsr0, u32 tcsr1)
{}

static int xilinx_pwm_apply(struct pwm_chip *chip, struct pwm_device *unused,
			    const struct pwm_state *state)
{}

static int xilinx_pwm_get_state(struct pwm_chip *chip,
				struct pwm_device *unused,
				struct pwm_state *state)
{}

static const struct pwm_ops xilinx_pwm_ops =;

static const struct regmap_config xilinx_pwm_regmap_config =;

static int xilinx_pwm_probe(struct platform_device *pdev)
{}

static const struct of_device_id xilinx_pwm_of_match[] =;
MODULE_DEVICE_TABLE(of, xilinx_pwm_of_match);

static struct platform_driver xilinx_pwm_driver =;
module_platform_driver();

MODULE_ALIAS();
MODULE_DESCRIPTION();
MODULE_LICENSE();