linux/drivers/pwm/pwm-meson.c

// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
 * PWM controller driver for Amlogic Meson SoCs.
 *
 * This PWM is only a set of Gates, Dividers and Counters:
 * PWM output is achieved by calculating a clock that permits calculating
 * two periods (low and high). The counter then has to be set to switch after
 * N cycles for the first half period.
 * The hardware has no "polarity" setting. This driver reverses the period
 * cycles (the low length is inverted with the high length) for
 * PWM_POLARITY_INVERSED. This means that .get_state cannot read the polarity
 * from the hardware.
 * Setting the duty cycle will disable and re-enable the PWM output.
 * Disabling the PWM stops the output immediately (without waiting for the
 * current period to complete first).
 *
 * The public S912 (GXM) datasheet contains some documentation for this PWM
 * controller starting on page 543:
 * https://dl.khadas.com/Hardware/VIM2/Datasheet/S912_Datasheet_V0.220170314publicversion-Wesion.pdf
 * An updated version of this IP block is found in S922X (G12B) SoCs. The
 * datasheet contains the description for this IP block revision starting at
 * page 1084:
 * https://dn.odroid.com/S922X/ODROID-N2/Datasheet/S922X_Public_Datasheet_V0.2.pdf
 *
 * Copyright (c) 2016 BayLibre, SAS.
 * Author: Neil Armstrong <[email protected]>
 * Copyright (C) 2014 Amlogic, Inc.
 */

#include <linux/bitfield.h>
#include <linux/bits.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/math64.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pwm.h>
#include <linux/slab.h>
#include <linux/spinlock.h>

#define REG_PWM_A
#define REG_PWM_B
#define PWM_LOW_MASK
#define PWM_HIGH_MASK

#define REG_MISC_AB
#define MISC_B_CLK_EN_SHIFT
#define MISC_A_CLK_EN_SHIFT
#define MISC_CLK_DIV_WIDTH
#define MISC_B_CLK_DIV_SHIFT
#define MISC_A_CLK_DIV_SHIFT
#define MISC_B_CLK_SEL_SHIFT
#define MISC_A_CLK_SEL_SHIFT
#define MISC_CLK_SEL_MASK
#define MISC_B_EN
#define MISC_A_EN

#define MESON_NUM_PWMS
#define MESON_NUM_MUX_PARENTS

static struct meson_pwm_channel_data {} meson_pwm_per_channel_data[MESON_NUM_PWMS] =;

struct meson_pwm_channel {};

struct meson_pwm_data {};

struct meson_pwm {};

static inline struct meson_pwm *to_meson_pwm(struct pwm_chip *chip)
{}

static int meson_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
{}

static void meson_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
{}

static int meson_pwm_calc(struct pwm_chip *chip, struct pwm_device *pwm,
			  const struct pwm_state *state)
{}

static void meson_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
{}

static void meson_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
{}

static int meson_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
			   const struct pwm_state *state)
{}

static u64 meson_pwm_cnt_to_ns(struct pwm_chip *chip, struct pwm_device *pwm,
			       u32 cnt)
{}

static int meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
			       struct pwm_state *state)
{}

static const struct pwm_ops meson_pwm_ops =;

static int meson_pwm_init_clocks_meson8b(struct pwm_chip *chip,
					 struct clk_parent_data *mux_parent_data)
{}

static int meson_pwm_init_channels_meson8b_legacy(struct pwm_chip *chip)
{}

static int meson_pwm_init_channels_meson8b_v2(struct pwm_chip *chip)
{}

static void meson_pwm_s4_put_clk(void *data)
{}

static int meson_pwm_init_channels_s4(struct pwm_chip *chip)
{}

static const struct meson_pwm_data pwm_meson8b_data =;

/*
 * Only the 2 first inputs of the GXBB AO PWMs are valid
 * The last 2 are grounded
 */
static const struct meson_pwm_data pwm_gxbb_ao_data =;

static const struct meson_pwm_data pwm_axg_ee_data =;

static const struct meson_pwm_data pwm_axg_ao_data =;

static const struct meson_pwm_data pwm_g12a_ao_ab_data =;

static const struct meson_pwm_data pwm_g12a_ao_cd_data =;

static const struct meson_pwm_data pwm_meson8_v2_data =;

static const struct meson_pwm_data pwm_s4_data =;

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

static int meson_pwm_probe(struct platform_device *pdev)
{}

static struct platform_driver meson_pwm_driver =;
module_platform_driver();

MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_LICENSE();