linux/drivers/pwm/pwm-samsung.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2007 Ben Dooks
 * Copyright (c) 2008 Simtec Electronics
 *     Ben Dooks <[email protected]>, <[email protected]>
 * Copyright (c) 2013 Tomasz Figa <[email protected]>
 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
 *
 * PWM driver for Samsung SoCs
 */

#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/export.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/kernel.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>
#include <linux/time.h>

/* For struct samsung_timer_variant and samsung_pwm_lock. */
#include <clocksource/samsung_pwm.h>

#define REG_TCFG0
#define REG_TCFG1
#define REG_TCON

#define REG_TCNTB(chan)
#define REG_TCMPB(chan)

#define TCFG0_PRESCALER_MASK
#define TCFG0_PRESCALER1_SHIFT

#define TCFG1_MUX_MASK
#define TCFG1_SHIFT(chan)

/*
 * Each channel occupies 4 bits in TCON register, but there is a gap of 4
 * bits (one channel) after channel 0, so channels have different numbering
 * when accessing TCON register. See to_tcon_channel() function.
 *
 * In addition, the location of autoreload bit for channel 4 (TCON channel 5)
 * in its set of bits is 2 as opposed to 3 for other channels.
 */
#define TCON_START(chan)
#define TCON_MANUALUPDATE(chan)
#define TCON_INVERT(chan)
#define _TCON_AUTORELOAD(chan)
#define _TCON_AUTORELOAD4(chan)
#define TCON_AUTORELOAD(chan)

/**
 * struct samsung_pwm_channel - private data of PWM channel
 * @period_ns:	current period in nanoseconds programmed to the hardware
 * @duty_ns:	current duty time in nanoseconds programmed to the hardware
 * @tin_ns:	time of one timer tick in nanoseconds with current timer rate
 */
struct samsung_pwm_channel {};

/**
 * struct samsung_pwm_chip - private data of PWM chip
 * @variant:		local copy of hardware variant data
 * @inverter_mask:	inverter status for all channels - one bit per channel
 * @disabled_mask:	disabled status for all channels - one bit per channel
 * @base:		base address of mapped PWM registers
 * @base_clk:		base clock used to drive the timers
 * @tclk0:		external clock 0 (can be ERR_PTR if not present)
 * @tclk1:		external clock 1 (can be ERR_PTR if not present)
 * @channel:		per channel driver data
 */
struct samsung_pwm_chip {};

#ifndef CONFIG_CLKSRC_SAMSUNG_PWM
/*
 * PWM block is shared between pwm-samsung and samsung_pwm_timer drivers
 * and some registers need access synchronization. If both drivers are
 * compiled in, the spinlock is defined in the clocksource driver,
 * otherwise following definition is used.
 *
 * Currently we do not need any more complex synchronization method
 * because all the supported SoCs contain only one instance of the PWM
 * IP. Should this change, both drivers will need to be modified to
 * properly synchronize accesses to particular instances.
 */
static DEFINE_SPINLOCK(samsung_pwm_lock);
#endif

static inline
struct samsung_pwm_chip *to_samsung_pwm_chip(struct pwm_chip *chip)
{}

static inline unsigned int to_tcon_channel(unsigned int channel)
{}

static void __pwm_samsung_manual_update(struct samsung_pwm_chip *our_chip,
				      struct pwm_device *pwm)
{}

static void pwm_samsung_set_divisor(struct samsung_pwm_chip *our_chip,
				    unsigned int channel, u8 divisor)
{}

static int pwm_samsung_is_tdiv(struct samsung_pwm_chip *our_chip, unsigned int chan)
{}

static unsigned long pwm_samsung_get_tin_rate(struct samsung_pwm_chip *our_chip,
					      unsigned int chan)
{}

static unsigned long pwm_samsung_calc_tin(struct pwm_chip *chip,
					  unsigned int chan, unsigned long freq)
{}

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

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

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

static void pwm_samsung_manual_update(struct samsung_pwm_chip *our_chip,
				      struct pwm_device *pwm)
{}

static int __pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm,
				int duty_ns, int period_ns, bool force_period)
{}

static int pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm,
			      int duty_ns, int period_ns)
{}

static void pwm_samsung_set_invert(struct samsung_pwm_chip *our_chip,
				   unsigned int channel, bool invert)
{}

static int pwm_samsung_set_polarity(struct pwm_chip *chip,
				    struct pwm_device *pwm,
				    enum pwm_polarity polarity)
{}

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

static const struct pwm_ops pwm_samsung_ops =;

#ifdef CONFIG_OF
static const struct samsung_pwm_variant s3c24xx_variant =;

static const struct samsung_pwm_variant s3c64xx_variant =;

static const struct samsung_pwm_variant s5p64x0_variant =;

static const struct samsung_pwm_variant s5pc100_variant =;

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

static int pwm_samsung_parse_dt(struct pwm_chip *chip)
{}
#else
static int pwm_samsung_parse_dt(struct pwm_chip *chip)
{
	return -ENODEV;
}
#endif

static int pwm_samsung_probe(struct platform_device *pdev)
{}

static int pwm_samsung_resume(struct device *dev)
{}

static DEFINE_SIMPLE_DEV_PM_OPS(pwm_samsung_pm_ops, NULL, pwm_samsung_resume);

static struct platform_driver pwm_samsung_driver =;
module_platform_driver();

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