linux/drivers/leds/rgb/leds-qcom-lpg.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2017-2022 Linaro Ltd
 * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
 * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
 */
#include <linux/bits.h>
#include <linux/bitfield.h>
#include <linux/led-class-multicolor.h>
#include <linux/module.h>
#include <linux/nvmem-consumer.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pwm.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/soc/qcom/qcom-pbs.h>

#define LPG_SUBTYPE_REG
#define LPG_SUBTYPE_LPG
#define LPG_SUBTYPE_PWM
#define LPG_SUBTYPE_HI_RES_PWM
#define LPG_SUBTYPE_LPG_LITE
#define LPG_PATTERN_CONFIG_REG
#define LPG_SIZE_CLK_REG
#define PWM_CLK_SELECT_MASK
#define PWM_CLK_SELECT_HI_RES_MASK
#define PWM_SIZE_HI_RES_MASK
#define LPG_PREDIV_CLK_REG
#define PWM_FREQ_PRE_DIV_MASK
#define PWM_FREQ_EXP_MASK
#define PWM_TYPE_CONFIG_REG
#define PWM_VALUE_REG
#define PWM_ENABLE_CONTROL_REG
#define PWM_SYNC_REG
#define LPG_RAMP_DURATION_REG
#define LPG_HI_PAUSE_REG
#define LPG_LO_PAUSE_REG
#define LPG_HI_IDX_REG
#define LPG_LO_IDX_REG
#define PWM_SEC_ACCESS_REG
#define PWM_DTEST_REG(x)

#define SDAM_REG_PBS_SEQ_EN
#define SDAM_PBS_TRIG_SET
#define SDAM_PBS_TRIG_CLR

#define TRI_LED_SRC_SEL
#define TRI_LED_EN_CTL
#define TRI_LED_ATC_CTL

#define LPG_LUT_REG(x)
#define RAMP_CONTROL_REG

#define LPG_RESOLUTION_9BIT
#define LPG_RESOLUTION_15BIT
#define PPG_MAX_LED_BRIGHTNESS

#define LPG_MAX_M
#define LPG_MAX_PREDIV

#define DEFAULT_TICK_DURATION_US
#define RAMP_STEP_DURATION(x)

#define SDAM_MAX_DEVICES
/* LPG common config settings for PPG */
#define SDAM_START_BASE
#define SDAM_REG_RAMP_STEP_DURATION

#define SDAM_LUT_SDAM_LUT_PATTERN_OFFSET
#define SDAM_LPG_SDAM_LUT_PATTERN_OFFSET

/* LPG per channel config settings for PPG */
#define SDAM_LUT_EN_OFFSET
#define SDAM_PATTERN_CONFIG_OFFSET
#define SDAM_END_INDEX_OFFSET
#define SDAM_START_INDEX_OFFSET
#define SDAM_PBS_SCRATCH_LUT_COUNTER_OFFSET
#define SDAM_PAUSE_HI_MULTIPLIER_OFFSET
#define SDAM_PAUSE_LO_MULTIPLIER_OFFSET

struct lpg_channel;
struct lpg_data;

/**
 * struct lpg - LPG device context
 * @dev:	pointer to LPG device
 * @map:	regmap for register access
 * @lock:	used to synchronize LED and pwm callback requests
 * @pwm:	PWM-chip object, if operating in PWM mode
 * @data:	reference to version specific data
 * @lut_base:	base address of the LUT block (optional)
 * @lut_size:	number of entries in the LUT block
 * @lut_bitmap:	allocation bitmap for LUT entries
 * @pbs_dev:	PBS device
 * @lpg_chan_sdam:	LPG SDAM peripheral device
 * @lut_sdam:	LUT SDAM peripheral device
 * @pbs_en_bitmap:	bitmap for tracking PBS triggers
 * @triled_base: base address of the TRILED block (optional)
 * @triled_src:	power-source for the TRILED
 * @triled_has_atc_ctl:	true if there is TRI_LED_ATC_CTL register
 * @triled_has_src_sel:	true if there is TRI_LED_SRC_SEL register
 * @channels:	list of PWM channels
 * @num_channels: number of @channels
 */
struct lpg {};

/**
 * struct lpg_channel - per channel data
 * @lpg:	reference to parent lpg
 * @base:	base address of the PWM channel
 * @triled_mask: mask in TRILED to enable this channel
 * @lut_mask:	mask in LUT to start pattern generator for this channel
 * @subtype:	PMIC hardware block subtype
 * @sdam_offset:	channel offset in LPG SDAM
 * @in_use:	channel is exposed to LED framework
 * @color:	color of the LED attached to this channel
 * @dtest_line:	DTEST line for output, or 0 if disabled
 * @dtest_value: DTEST line configuration
 * @pwm_value:	duty (in microseconds) of the generated pulses, overridden by LUT
 * @enabled:	output enabled?
 * @period:	period (in nanoseconds) of the generated pulses
 * @clk_sel:	reference clock frequency selector
 * @pre_div_sel: divider selector of the reference clock
 * @pre_div_exp: exponential divider of the reference clock
 * @pwm_resolution_sel:	pwm resolution selector
 * @ramp_enabled: duty cycle is driven by iterating over lookup table
 * @ramp_ping_pong: reverse through pattern, rather than wrapping to start
 * @ramp_oneshot: perform only a single pass over the pattern
 * @ramp_reverse: iterate over pattern backwards
 * @ramp_tick_ms: length (in milliseconds) of one step in the pattern
 * @ramp_lo_pause_ms: pause (in milliseconds) before iterating over pattern
 * @ramp_hi_pause_ms: pause (in milliseconds) after iterating over pattern
 * @pattern_lo_idx: start index of associated pattern
 * @pattern_hi_idx: last index of associated pattern
 */
struct lpg_channel {};

/**
 * struct lpg_led - logical LED object
 * @lpg:		lpg context reference
 * @cdev:		LED class device
 * @mcdev:		Multicolor LED class device
 * @num_channels:	number of @channels
 * @channels:		list of channels associated with the LED
 */
struct lpg_led {};

/**
 * struct lpg_channel_data - per channel initialization data
 * @sdam_offset:	Channel offset in LPG SDAM
 * @base:		base address for PWM channel registers
 * @triled_mask:	bitmask for controlling this channel in TRILED
 */
struct lpg_channel_data {};

/**
 * struct lpg_data - initialization data
 * @lut_base:		base address of LUT block
 * @lut_size:		number of entries in LUT
 * @triled_base:	base address of TRILED
 * @triled_has_atc_ctl:	true if there is TRI_LED_ATC_CTL register
 * @triled_has_src_sel:	true if there is TRI_LED_SRC_SEL register
 * @num_channels:	number of channels in LPG
 * @channels:		list of channel initialization data
 */
struct lpg_data {};

#define PBS_SW_TRIG_BIT

static int lpg_clear_pbs_trigger(struct lpg *lpg, unsigned int lut_mask)
{}

static int lpg_set_pbs_trigger(struct lpg *lpg, unsigned int lut_mask)
{}

static int lpg_sdam_configure_triggers(struct lpg_channel *chan, u8 set_trig)
{}

static int triled_set(struct lpg *lpg, unsigned int mask, unsigned int enable)
{}

static int lpg_lut_store_sdam(struct lpg *lpg, struct led_pattern *pattern,
			 size_t len, unsigned int *lo_idx, unsigned int *hi_idx)
{}

static int lpg_lut_store(struct lpg *lpg, struct led_pattern *pattern,
			 size_t len, unsigned int *lo_idx, unsigned int *hi_idx)
{}

static void lpg_lut_free(struct lpg *lpg, unsigned int lo_idx, unsigned int hi_idx)
{}

static int lpg_lut_sync(struct lpg *lpg, unsigned int mask)
{}

static const unsigned int lpg_clk_rates[] =;
static const unsigned int lpg_clk_rates_hi_res[] =;
static const unsigned int lpg_pre_divs[] =;
static const unsigned int lpg_pwm_resolution[] =;
static const unsigned int lpg_pwm_resolution_hi_res[] =;

static int lpg_calc_freq(struct lpg_channel *chan, uint64_t period)
{}

static void lpg_calc_duty(struct lpg_channel *chan, uint64_t duty)
{}

static void lpg_apply_freq(struct lpg_channel *chan)
{}

#define LPG_ENABLE_GLITCH_REMOVAL

static void lpg_enable_glitch(struct lpg_channel *chan)
{}

static void lpg_disable_glitch(struct lpg_channel *chan)
{}

static void lpg_apply_pwm_value(struct lpg_channel *chan)
{}

#define LPG_PATTERN_CONFIG_LO_TO_HI
#define LPG_PATTERN_CONFIG_REPEAT
#define LPG_PATTERN_CONFIG_TOGGLE
#define LPG_PATTERN_CONFIG_PAUSE_HI
#define LPG_PATTERN_CONFIG_PAUSE_LO

static void lpg_sdam_apply_lut_control(struct lpg_channel *chan)
{}

static void lpg_apply_lut_control(struct lpg_channel *chan)
{}

#define LPG_ENABLE_CONTROL_OUTPUT
#define LPG_ENABLE_CONTROL_BUFFER_TRISTATE
#define LPG_ENABLE_CONTROL_SRC_PWM
#define LPG_ENABLE_CONTROL_RAMP_GEN

static void lpg_apply_control(struct lpg_channel *chan)
{}

#define LPG_SYNC_PWM

static void lpg_apply_sync(struct lpg_channel *chan)
{}

static int lpg_parse_dtest(struct lpg *lpg)
{}

static void lpg_apply_dtest(struct lpg_channel *chan)
{}

static void lpg_apply(struct lpg_channel *chan)
{}

static void lpg_brightness_set(struct lpg_led *led, struct led_classdev *cdev,
			       struct mc_subled *subleds)
{}

static int lpg_brightness_single_set(struct led_classdev *cdev,
				     enum led_brightness value)
{}

static int lpg_brightness_mc_set(struct led_classdev *cdev,
				 enum led_brightness value)
{}

static int lpg_blink_set(struct lpg_led *led,
			 unsigned long *delay_on, unsigned long *delay_off)
{}

static int lpg_blink_single_set(struct led_classdev *cdev,
				unsigned long *delay_on, unsigned long *delay_off)
{}

static int lpg_blink_mc_set(struct led_classdev *cdev,
			    unsigned long *delay_on, unsigned long *delay_off)
{}

static int lpg_pattern_set(struct lpg_led *led, struct led_pattern *led_pattern,
			   u32 len, int repeat)
{}

static int lpg_pattern_single_set(struct led_classdev *cdev,
				  struct led_pattern *pattern, u32 len,
				  int repeat)
{}

static int lpg_pattern_mc_set(struct led_classdev *cdev,
			      struct led_pattern *pattern, u32 len,
			      int repeat)
{}

static int lpg_pattern_clear(struct lpg_led *led)
{}

static int lpg_pattern_single_clear(struct led_classdev *cdev)
{}

static int lpg_pattern_mc_clear(struct led_classdev *cdev)
{}

static inline struct lpg *lpg_pwm_from_chip(struct pwm_chip *chip)
{}

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

/*
 * Limitations:
 * - Updating both duty and period is not done atomically, so the output signal
 *   will momentarily be a mix of the settings.
 * - Changed parameters takes effect immediately.
 * - A disabled channel outputs a logical 0.
 */
static int lpg_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
			 const struct pwm_state *state)
{}

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

static const struct pwm_ops lpg_pwm_ops =;

static int lpg_add_pwm(struct lpg *lpg)
{}

static int lpg_parse_channel(struct lpg *lpg, struct device_node *np,
			     struct lpg_channel **channel)
{}

static int lpg_add_led(struct lpg *lpg, struct device_node *np)
{}

static int lpg_init_channels(struct lpg *lpg)
{}

static int lpg_init_triled(struct lpg *lpg)
{}

static int lpg_init_lut(struct lpg *lpg)
{}

static int lpg_init_sdam(struct lpg *lpg)
{}

static int lpg_probe(struct platform_device *pdev)
{}

static const struct lpg_data pm660l_lpg_data =;

static const struct lpg_data pm8916_pwm_data =;

static const struct lpg_data pm8941_lpg_data =;

static const struct lpg_data pmi8950_pwm_data =;

static const struct lpg_data pm8994_lpg_data =;

/* PMI632 uses SDAM instead of LUT for pattern */
static const struct lpg_data pmi632_lpg_data =;

static const struct lpg_data pmi8994_lpg_data =;

static const struct lpg_data pmi8998_lpg_data =;

static const struct lpg_data pm8150b_lpg_data =;

static const struct lpg_data pm8150l_lpg_data =;

static const struct lpg_data pm8350c_pwm_data =;

static const struct lpg_data pmk8550_pwm_data =;

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

static struct platform_driver lpg_driver =;
module_platform_driver();

MODULE_DESCRIPTION();
MODULE_LICENSE();