cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

leds-qcom-lpg.c (36541B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (c) 2017-2022 Linaro Ltd
      4 * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
      5 */
      6#include <linux/bits.h>
      7#include <linux/bitfield.h>
      8#include <linux/led-class-multicolor.h>
      9#include <linux/module.h>
     10#include <linux/of.h>
     11#include <linux/of_device.h>
     12#include <linux/platform_device.h>
     13#include <linux/pwm.h>
     14#include <linux/regmap.h>
     15#include <linux/slab.h>
     16
     17#define LPG_SUBTYPE_REG		0x05
     18#define  LPG_SUBTYPE_LPG	0x2
     19#define  LPG_SUBTYPE_PWM	0xb
     20#define  LPG_SUBTYPE_LPG_LITE	0x11
     21#define LPG_PATTERN_CONFIG_REG	0x40
     22#define LPG_SIZE_CLK_REG	0x41
     23#define  PWM_CLK_SELECT_MASK	GENMASK(1, 0)
     24#define LPG_PREDIV_CLK_REG	0x42
     25#define  PWM_FREQ_PRE_DIV_MASK	GENMASK(6, 5)
     26#define  PWM_FREQ_EXP_MASK	GENMASK(2, 0)
     27#define PWM_TYPE_CONFIG_REG	0x43
     28#define PWM_VALUE_REG		0x44
     29#define PWM_ENABLE_CONTROL_REG	0x46
     30#define PWM_SYNC_REG		0x47
     31#define LPG_RAMP_DURATION_REG	0x50
     32#define LPG_HI_PAUSE_REG	0x52
     33#define LPG_LO_PAUSE_REG	0x54
     34#define LPG_HI_IDX_REG		0x56
     35#define LPG_LO_IDX_REG		0x57
     36#define PWM_SEC_ACCESS_REG	0xd0
     37#define PWM_DTEST_REG(x)	(0xe2 + (x) - 1)
     38
     39#define TRI_LED_SRC_SEL		0x45
     40#define TRI_LED_EN_CTL		0x46
     41#define TRI_LED_ATC_CTL		0x47
     42
     43#define LPG_LUT_REG(x)		(0x40 + (x) * 2)
     44#define RAMP_CONTROL_REG	0xc8
     45
     46#define LPG_RESOLUTION		512
     47#define LPG_MAX_M		7
     48
     49struct lpg_channel;
     50struct lpg_data;
     51
     52/**
     53 * struct lpg - LPG device context
     54 * @dev:	pointer to LPG device
     55 * @map:	regmap for register access
     56 * @lock:	used to synchronize LED and pwm callback requests
     57 * @pwm:	PWM-chip object, if operating in PWM mode
     58 * @data:	reference to version specific data
     59 * @lut_base:	base address of the LUT block (optional)
     60 * @lut_size:	number of entries in the LUT block
     61 * @lut_bitmap:	allocation bitmap for LUT entries
     62 * @triled_base: base address of the TRILED block (optional)
     63 * @triled_src:	power-source for the TRILED
     64 * @triled_has_atc_ctl:	true if there is TRI_LED_ATC_CTL register
     65 * @triled_has_src_sel:	true if there is TRI_LED_SRC_SEL register
     66 * @channels:	list of PWM channels
     67 * @num_channels: number of @channels
     68 */
     69struct lpg {
     70	struct device *dev;
     71	struct regmap *map;
     72
     73	struct mutex lock;
     74
     75	struct pwm_chip pwm;
     76
     77	const struct lpg_data *data;
     78
     79	u32 lut_base;
     80	u32 lut_size;
     81	unsigned long *lut_bitmap;
     82
     83	u32 triled_base;
     84	u32 triled_src;
     85	bool triled_has_atc_ctl;
     86	bool triled_has_src_sel;
     87
     88	struct lpg_channel *channels;
     89	unsigned int num_channels;
     90};
     91
     92/**
     93 * struct lpg_channel - per channel data
     94 * @lpg:	reference to parent lpg
     95 * @base:	base address of the PWM channel
     96 * @triled_mask: mask in TRILED to enable this channel
     97 * @lut_mask:	mask in LUT to start pattern generator for this channel
     98 * @subtype:	PMIC hardware block subtype
     99 * @in_use:	channel is exposed to LED framework
    100 * @color:	color of the LED attached to this channel
    101 * @dtest_line:	DTEST line for output, or 0 if disabled
    102 * @dtest_value: DTEST line configuration
    103 * @pwm_value:	duty (in microseconds) of the generated pulses, overridden by LUT
    104 * @enabled:	output enabled?
    105 * @period:	period (in nanoseconds) of the generated pulses
    106 * @clk_sel:	reference clock frequency selector
    107 * @pre_div_sel: divider selector of the reference clock
    108 * @pre_div_exp: exponential divider of the reference clock
    109 * @ramp_enabled: duty cycle is driven by iterating over lookup table
    110 * @ramp_ping_pong: reverse through pattern, rather than wrapping to start
    111 * @ramp_oneshot: perform only a single pass over the pattern
    112 * @ramp_reverse: iterate over pattern backwards
    113 * @ramp_tick_ms: length (in milliseconds) of one step in the pattern
    114 * @ramp_lo_pause_ms: pause (in milliseconds) before iterating over pattern
    115 * @ramp_hi_pause_ms: pause (in milliseconds) after iterating over pattern
    116 * @pattern_lo_idx: start index of associated pattern
    117 * @pattern_hi_idx: last index of associated pattern
    118 */
    119struct lpg_channel {
    120	struct lpg *lpg;
    121
    122	u32 base;
    123	unsigned int triled_mask;
    124	unsigned int lut_mask;
    125	unsigned int subtype;
    126
    127	bool in_use;
    128
    129	int color;
    130
    131	u32 dtest_line;
    132	u32 dtest_value;
    133
    134	u16 pwm_value;
    135	bool enabled;
    136
    137	u64 period;
    138	unsigned int clk_sel;
    139	unsigned int pre_div_sel;
    140	unsigned int pre_div_exp;
    141
    142	bool ramp_enabled;
    143	bool ramp_ping_pong;
    144	bool ramp_oneshot;
    145	bool ramp_reverse;
    146	unsigned short ramp_tick_ms;
    147	unsigned long ramp_lo_pause_ms;
    148	unsigned long ramp_hi_pause_ms;
    149
    150	unsigned int pattern_lo_idx;
    151	unsigned int pattern_hi_idx;
    152};
    153
    154/**
    155 * struct lpg_led - logical LED object
    156 * @lpg:		lpg context reference
    157 * @cdev:		LED class device
    158 * @mcdev:		Multicolor LED class device
    159 * @num_channels:	number of @channels
    160 * @channels:		list of channels associated with the LED
    161 */
    162struct lpg_led {
    163	struct lpg *lpg;
    164
    165	struct led_classdev cdev;
    166	struct led_classdev_mc mcdev;
    167
    168	unsigned int num_channels;
    169	struct lpg_channel *channels[];
    170};
    171
    172/**
    173 * struct lpg_channel_data - per channel initialization data
    174 * @base:		base address for PWM channel registers
    175 * @triled_mask:	bitmask for controlling this channel in TRILED
    176 */
    177struct lpg_channel_data {
    178	unsigned int base;
    179	u8 triled_mask;
    180};
    181
    182/**
    183 * struct lpg_data - initialization data
    184 * @lut_base:		base address of LUT block
    185 * @lut_size:		number of entries in LUT
    186 * @triled_base:	base address of TRILED
    187 * @triled_has_atc_ctl:	true if there is TRI_LED_ATC_CTL register
    188 * @triled_has_src_sel:	true if there is TRI_LED_SRC_SEL register
    189 * @num_channels:	number of channels in LPG
    190 * @channels:		list of channel initialization data
    191 */
    192struct lpg_data {
    193	unsigned int lut_base;
    194	unsigned int lut_size;
    195	unsigned int triled_base;
    196	bool triled_has_atc_ctl;
    197	bool triled_has_src_sel;
    198	int num_channels;
    199	const struct lpg_channel_data *channels;
    200};
    201
    202static int triled_set(struct lpg *lpg, unsigned int mask, unsigned int enable)
    203{
    204	/* Skip if we don't have a triled block */
    205	if (!lpg->triled_base)
    206		return 0;
    207
    208	return regmap_update_bits(lpg->map, lpg->triled_base + TRI_LED_EN_CTL,
    209				  mask, enable);
    210}
    211
    212static int lpg_lut_store(struct lpg *lpg, struct led_pattern *pattern,
    213			 size_t len, unsigned int *lo_idx, unsigned int *hi_idx)
    214{
    215	unsigned int idx;
    216	u16 val;
    217	int i;
    218
    219	idx = bitmap_find_next_zero_area(lpg->lut_bitmap, lpg->lut_size,
    220					 0, len, 0);
    221	if (idx >= lpg->lut_size)
    222		return -ENOMEM;
    223
    224	for (i = 0; i < len; i++) {
    225		val = pattern[i].brightness;
    226
    227		regmap_bulk_write(lpg->map, lpg->lut_base + LPG_LUT_REG(idx + i),
    228				  &val, sizeof(val));
    229	}
    230
    231	bitmap_set(lpg->lut_bitmap, idx, len);
    232
    233	*lo_idx = idx;
    234	*hi_idx = idx + len - 1;
    235
    236	return 0;
    237}
    238
    239static void lpg_lut_free(struct lpg *lpg, unsigned int lo_idx, unsigned int hi_idx)
    240{
    241	int len;
    242
    243	len = hi_idx - lo_idx + 1;
    244	if (len == 1)
    245		return;
    246
    247	bitmap_clear(lpg->lut_bitmap, lo_idx, len);
    248}
    249
    250static int lpg_lut_sync(struct lpg *lpg, unsigned int mask)
    251{
    252	return regmap_write(lpg->map, lpg->lut_base + RAMP_CONTROL_REG, mask);
    253}
    254
    255static const unsigned int lpg_clk_rates[] = {0, 1024, 32768, 19200000};
    256static const unsigned int lpg_pre_divs[] = {1, 3, 5, 6};
    257
    258static int lpg_calc_freq(struct lpg_channel *chan, uint64_t period)
    259{
    260	unsigned int clk_sel, best_clk = 0;
    261	unsigned int div, best_div = 0;
    262	unsigned int m, best_m = 0;
    263	unsigned int error;
    264	unsigned int best_err = UINT_MAX;
    265	u64 best_period = 0;
    266	u64 max_period;
    267
    268	/*
    269	 * The PWM period is determined by:
    270	 *
    271	 *          resolution * pre_div * 2^M
    272	 * period = --------------------------
    273	 *                   refclk
    274	 *
    275	 * With resolution fixed at 2^9 bits, pre_div = {1, 3, 5, 6} and
    276	 * M = [0..7].
    277	 *
    278	 * This allows for periods between 27uS and 384s, as the PWM framework
    279	 * wants a period of equal or lower length than requested, reject
    280	 * anything below 27uS.
    281	 */
    282	if (period <= (u64)NSEC_PER_SEC * LPG_RESOLUTION / 19200000)
    283		return -EINVAL;
    284
    285	/* Limit period to largest possible value, to avoid overflows */
    286	max_period = (u64)NSEC_PER_SEC * LPG_RESOLUTION * 6 * (1 << LPG_MAX_M) / 1024;
    287	if (period > max_period)
    288		period = max_period;
    289
    290	/*
    291	 * Search for the pre_div, refclk and M by solving the rewritten formula
    292	 * for each refclk and pre_div value:
    293	 *
    294	 *                     period * refclk
    295	 * M = log2 -------------------------------------
    296	 *           NSEC_PER_SEC * pre_div * resolution
    297	 */
    298	for (clk_sel = 1; clk_sel < ARRAY_SIZE(lpg_clk_rates); clk_sel++) {
    299		u64 numerator = period * lpg_clk_rates[clk_sel];
    300
    301		for (div = 0; div < ARRAY_SIZE(lpg_pre_divs); div++) {
    302			u64 denominator = (u64)NSEC_PER_SEC * lpg_pre_divs[div] * LPG_RESOLUTION;
    303			u64 actual;
    304			u64 ratio;
    305
    306			if (numerator < denominator)
    307				continue;
    308
    309			ratio = div64_u64(numerator, denominator);
    310			m = ilog2(ratio);
    311			if (m > LPG_MAX_M)
    312				m = LPG_MAX_M;
    313
    314			actual = DIV_ROUND_UP_ULL(denominator * (1 << m), lpg_clk_rates[clk_sel]);
    315
    316			error = period - actual;
    317			if (error < best_err) {
    318				best_err = error;
    319
    320				best_div = div;
    321				best_m = m;
    322				best_clk = clk_sel;
    323				best_period = actual;
    324			}
    325		}
    326	}
    327
    328	chan->clk_sel = best_clk;
    329	chan->pre_div_sel = best_div;
    330	chan->pre_div_exp = best_m;
    331	chan->period = best_period;
    332
    333	return 0;
    334}
    335
    336static void lpg_calc_duty(struct lpg_channel *chan, uint64_t duty)
    337{
    338	unsigned int max = LPG_RESOLUTION - 1;
    339	unsigned int val;
    340
    341	val = div64_u64(duty * lpg_clk_rates[chan->clk_sel],
    342			(u64)NSEC_PER_SEC * lpg_pre_divs[chan->pre_div_sel] * (1 << chan->pre_div_exp));
    343
    344	chan->pwm_value = min(val, max);
    345}
    346
    347static void lpg_apply_freq(struct lpg_channel *chan)
    348{
    349	unsigned long val;
    350	struct lpg *lpg = chan->lpg;
    351
    352	if (!chan->enabled)
    353		return;
    354
    355	val = chan->clk_sel;
    356
    357	/* Specify 9bit resolution, based on the subtype of the channel */
    358	switch (chan->subtype) {
    359	case LPG_SUBTYPE_LPG:
    360		val |= GENMASK(5, 4);
    361		break;
    362	case LPG_SUBTYPE_PWM:
    363		val |= BIT(2);
    364		break;
    365	case LPG_SUBTYPE_LPG_LITE:
    366	default:
    367		val |= BIT(4);
    368		break;
    369	}
    370
    371	regmap_write(lpg->map, chan->base + LPG_SIZE_CLK_REG, val);
    372
    373	val = FIELD_PREP(PWM_FREQ_PRE_DIV_MASK, chan->pre_div_sel) |
    374	      FIELD_PREP(PWM_FREQ_EXP_MASK, chan->pre_div_exp);
    375	regmap_write(lpg->map, chan->base + LPG_PREDIV_CLK_REG, val);
    376}
    377
    378#define LPG_ENABLE_GLITCH_REMOVAL	BIT(5)
    379
    380static void lpg_enable_glitch(struct lpg_channel *chan)
    381{
    382	struct lpg *lpg = chan->lpg;
    383
    384	regmap_update_bits(lpg->map, chan->base + PWM_TYPE_CONFIG_REG,
    385			   LPG_ENABLE_GLITCH_REMOVAL, 0);
    386}
    387
    388static void lpg_disable_glitch(struct lpg_channel *chan)
    389{
    390	struct lpg *lpg = chan->lpg;
    391
    392	regmap_update_bits(lpg->map, chan->base + PWM_TYPE_CONFIG_REG,
    393			   LPG_ENABLE_GLITCH_REMOVAL,
    394			   LPG_ENABLE_GLITCH_REMOVAL);
    395}
    396
    397static void lpg_apply_pwm_value(struct lpg_channel *chan)
    398{
    399	struct lpg *lpg = chan->lpg;
    400	u16 val = chan->pwm_value;
    401
    402	if (!chan->enabled)
    403		return;
    404
    405	regmap_bulk_write(lpg->map, chan->base + PWM_VALUE_REG, &val, sizeof(val));
    406}
    407
    408#define LPG_PATTERN_CONFIG_LO_TO_HI	BIT(4)
    409#define LPG_PATTERN_CONFIG_REPEAT	BIT(3)
    410#define LPG_PATTERN_CONFIG_TOGGLE	BIT(2)
    411#define LPG_PATTERN_CONFIG_PAUSE_HI	BIT(1)
    412#define LPG_PATTERN_CONFIG_PAUSE_LO	BIT(0)
    413
    414static void lpg_apply_lut_control(struct lpg_channel *chan)
    415{
    416	struct lpg *lpg = chan->lpg;
    417	unsigned int hi_pause;
    418	unsigned int lo_pause;
    419	unsigned int conf = 0;
    420	unsigned int lo_idx = chan->pattern_lo_idx;
    421	unsigned int hi_idx = chan->pattern_hi_idx;
    422	u16 step = chan->ramp_tick_ms;
    423
    424	if (!chan->ramp_enabled || chan->pattern_lo_idx == chan->pattern_hi_idx)
    425		return;
    426
    427	hi_pause = DIV_ROUND_UP(chan->ramp_hi_pause_ms, step);
    428	lo_pause = DIV_ROUND_UP(chan->ramp_lo_pause_ms, step);
    429
    430	if (!chan->ramp_reverse)
    431		conf |= LPG_PATTERN_CONFIG_LO_TO_HI;
    432	if (!chan->ramp_oneshot)
    433		conf |= LPG_PATTERN_CONFIG_REPEAT;
    434	if (chan->ramp_ping_pong)
    435		conf |= LPG_PATTERN_CONFIG_TOGGLE;
    436	if (chan->ramp_hi_pause_ms)
    437		conf |= LPG_PATTERN_CONFIG_PAUSE_HI;
    438	if (chan->ramp_lo_pause_ms)
    439		conf |= LPG_PATTERN_CONFIG_PAUSE_LO;
    440
    441	regmap_write(lpg->map, chan->base + LPG_PATTERN_CONFIG_REG, conf);
    442	regmap_write(lpg->map, chan->base + LPG_HI_IDX_REG, hi_idx);
    443	regmap_write(lpg->map, chan->base + LPG_LO_IDX_REG, lo_idx);
    444
    445	regmap_bulk_write(lpg->map, chan->base + LPG_RAMP_DURATION_REG, &step, sizeof(step));
    446	regmap_write(lpg->map, chan->base + LPG_HI_PAUSE_REG, hi_pause);
    447	regmap_write(lpg->map, chan->base + LPG_LO_PAUSE_REG, lo_pause);
    448}
    449
    450#define LPG_ENABLE_CONTROL_OUTPUT		BIT(7)
    451#define LPG_ENABLE_CONTROL_BUFFER_TRISTATE	BIT(5)
    452#define LPG_ENABLE_CONTROL_SRC_PWM		BIT(2)
    453#define LPG_ENABLE_CONTROL_RAMP_GEN		BIT(1)
    454
    455static void lpg_apply_control(struct lpg_channel *chan)
    456{
    457	unsigned int ctrl;
    458	struct lpg *lpg = chan->lpg;
    459
    460	ctrl = LPG_ENABLE_CONTROL_BUFFER_TRISTATE;
    461
    462	if (chan->enabled)
    463		ctrl |= LPG_ENABLE_CONTROL_OUTPUT;
    464
    465	if (chan->pattern_lo_idx != chan->pattern_hi_idx)
    466		ctrl |= LPG_ENABLE_CONTROL_RAMP_GEN;
    467	else
    468		ctrl |= LPG_ENABLE_CONTROL_SRC_PWM;
    469
    470	regmap_write(lpg->map, chan->base + PWM_ENABLE_CONTROL_REG, ctrl);
    471
    472	/*
    473	 * Due to LPG hardware bug, in the PWM mode, having enabled PWM,
    474	 * We have to write PWM values one more time.
    475	 */
    476	if (chan->enabled)
    477		lpg_apply_pwm_value(chan);
    478}
    479
    480#define LPG_SYNC_PWM	BIT(0)
    481
    482static void lpg_apply_sync(struct lpg_channel *chan)
    483{
    484	struct lpg *lpg = chan->lpg;
    485
    486	regmap_write(lpg->map, chan->base + PWM_SYNC_REG, LPG_SYNC_PWM);
    487}
    488
    489static int lpg_parse_dtest(struct lpg *lpg)
    490{
    491	struct lpg_channel *chan;
    492	struct device_node *np = lpg->dev->of_node;
    493	int count;
    494	int ret;
    495	int i;
    496
    497	count = of_property_count_u32_elems(np, "qcom,dtest");
    498	if (count == -EINVAL) {
    499		return 0;
    500	} else if (count < 0) {
    501		ret = count;
    502		goto err_malformed;
    503	} else if (count != lpg->data->num_channels * 2) {
    504		dev_err(lpg->dev, "qcom,dtest needs to be %d items\n",
    505			lpg->data->num_channels * 2);
    506		return -EINVAL;
    507	}
    508
    509	for (i = 0; i < lpg->data->num_channels; i++) {
    510		chan = &lpg->channels[i];
    511
    512		ret = of_property_read_u32_index(np, "qcom,dtest", i * 2,
    513						 &chan->dtest_line);
    514		if (ret)
    515			goto err_malformed;
    516
    517		ret = of_property_read_u32_index(np, "qcom,dtest", i * 2 + 1,
    518						 &chan->dtest_value);
    519		if (ret)
    520			goto err_malformed;
    521	}
    522
    523	return 0;
    524
    525err_malformed:
    526	dev_err(lpg->dev, "malformed qcom,dtest\n");
    527	return ret;
    528}
    529
    530static void lpg_apply_dtest(struct lpg_channel *chan)
    531{
    532	struct lpg *lpg = chan->lpg;
    533
    534	if (!chan->dtest_line)
    535		return;
    536
    537	regmap_write(lpg->map, chan->base + PWM_SEC_ACCESS_REG, 0xa5);
    538	regmap_write(lpg->map, chan->base + PWM_DTEST_REG(chan->dtest_line),
    539		     chan->dtest_value);
    540}
    541
    542static void lpg_apply(struct lpg_channel *chan)
    543{
    544	lpg_disable_glitch(chan);
    545	lpg_apply_freq(chan);
    546	lpg_apply_pwm_value(chan);
    547	lpg_apply_control(chan);
    548	lpg_apply_sync(chan);
    549	lpg_apply_lut_control(chan);
    550	lpg_enable_glitch(chan);
    551}
    552
    553static void lpg_brightness_set(struct lpg_led *led, struct led_classdev *cdev,
    554			       struct mc_subled *subleds)
    555{
    556	enum led_brightness brightness;
    557	struct lpg_channel *chan;
    558	unsigned int triled_enabled = 0;
    559	unsigned int triled_mask = 0;
    560	unsigned int lut_mask = 0;
    561	unsigned int duty;
    562	struct lpg *lpg = led->lpg;
    563	int i;
    564
    565	for (i = 0; i < led->num_channels; i++) {
    566		chan = led->channels[i];
    567		brightness = subleds[i].brightness;
    568
    569		if (brightness == LED_OFF) {
    570			chan->enabled = false;
    571			chan->ramp_enabled = false;
    572		} else if (chan->pattern_lo_idx != chan->pattern_hi_idx) {
    573			lpg_calc_freq(chan, NSEC_PER_MSEC);
    574
    575			chan->enabled = true;
    576			chan->ramp_enabled = true;
    577
    578			lut_mask |= chan->lut_mask;
    579			triled_enabled |= chan->triled_mask;
    580		} else {
    581			lpg_calc_freq(chan, NSEC_PER_MSEC);
    582
    583			duty = div_u64(brightness * chan->period, cdev->max_brightness);
    584			lpg_calc_duty(chan, duty);
    585			chan->enabled = true;
    586			chan->ramp_enabled = false;
    587
    588			triled_enabled |= chan->triled_mask;
    589		}
    590
    591		triled_mask |= chan->triled_mask;
    592
    593		lpg_apply(chan);
    594	}
    595
    596	/* Toggle triled lines */
    597	if (triled_mask)
    598		triled_set(lpg, triled_mask, triled_enabled);
    599
    600	/* Trigger start of ramp generator(s) */
    601	if (lut_mask)
    602		lpg_lut_sync(lpg, lut_mask);
    603}
    604
    605static void lpg_brightness_single_set(struct led_classdev *cdev,
    606				      enum led_brightness value)
    607{
    608	struct lpg_led *led = container_of(cdev, struct lpg_led, cdev);
    609	struct mc_subled info;
    610
    611	mutex_lock(&led->lpg->lock);
    612
    613	info.brightness = value;
    614	lpg_brightness_set(led, cdev, &info);
    615
    616	mutex_unlock(&led->lpg->lock);
    617}
    618
    619static void lpg_brightness_mc_set(struct led_classdev *cdev,
    620				  enum led_brightness value)
    621{
    622	struct led_classdev_mc *mc = lcdev_to_mccdev(cdev);
    623	struct lpg_led *led = container_of(mc, struct lpg_led, mcdev);
    624
    625	mutex_lock(&led->lpg->lock);
    626
    627	led_mc_calc_color_components(mc, value);
    628	lpg_brightness_set(led, cdev, mc->subled_info);
    629
    630	mutex_unlock(&led->lpg->lock);
    631}
    632
    633static int lpg_blink_set(struct lpg_led *led,
    634			 unsigned long *delay_on, unsigned long *delay_off)
    635{
    636	struct lpg_channel *chan;
    637	unsigned int period;
    638	unsigned int triled_mask = 0;
    639	struct lpg *lpg = led->lpg;
    640	u64 duty;
    641	int i;
    642
    643	if (!*delay_on && !*delay_off) {
    644		*delay_on = 500;
    645		*delay_off = 500;
    646	}
    647
    648	duty = *delay_on * NSEC_PER_MSEC;
    649	period = (*delay_on + *delay_off) * NSEC_PER_MSEC;
    650
    651	for (i = 0; i < led->num_channels; i++) {
    652		chan = led->channels[i];
    653
    654		lpg_calc_freq(chan, period);
    655		lpg_calc_duty(chan, duty);
    656
    657		chan->enabled = true;
    658		chan->ramp_enabled = false;
    659
    660		triled_mask |= chan->triled_mask;
    661
    662		lpg_apply(chan);
    663	}
    664
    665	/* Enable triled lines */
    666	triled_set(lpg, triled_mask, triled_mask);
    667
    668	chan = led->channels[0];
    669	duty = div_u64(chan->pwm_value * chan->period, LPG_RESOLUTION);
    670	*delay_on = div_u64(duty, NSEC_PER_MSEC);
    671	*delay_off = div_u64(chan->period - duty, NSEC_PER_MSEC);
    672
    673	return 0;
    674}
    675
    676static int lpg_blink_single_set(struct led_classdev *cdev,
    677				unsigned long *delay_on, unsigned long *delay_off)
    678{
    679	struct lpg_led *led = container_of(cdev, struct lpg_led, cdev);
    680	int ret;
    681
    682	mutex_lock(&led->lpg->lock);
    683
    684	ret = lpg_blink_set(led, delay_on, delay_off);
    685
    686	mutex_unlock(&led->lpg->lock);
    687
    688	return ret;
    689}
    690
    691static int lpg_blink_mc_set(struct led_classdev *cdev,
    692			    unsigned long *delay_on, unsigned long *delay_off)
    693{
    694	struct led_classdev_mc *mc = lcdev_to_mccdev(cdev);
    695	struct lpg_led *led = container_of(mc, struct lpg_led, mcdev);
    696	int ret;
    697
    698	mutex_lock(&led->lpg->lock);
    699
    700	ret = lpg_blink_set(led, delay_on, delay_off);
    701
    702	mutex_unlock(&led->lpg->lock);
    703
    704	return ret;
    705}
    706
    707static int lpg_pattern_set(struct lpg_led *led, struct led_pattern *led_pattern,
    708			   u32 len, int repeat)
    709{
    710	struct lpg_channel *chan;
    711	struct lpg *lpg = led->lpg;
    712	struct led_pattern *pattern;
    713	unsigned int brightness_a;
    714	unsigned int brightness_b;
    715	unsigned int actual_len;
    716	unsigned int hi_pause;
    717	unsigned int lo_pause;
    718	unsigned int delta_t;
    719	unsigned int lo_idx;
    720	unsigned int hi_idx;
    721	unsigned int i;
    722	bool ping_pong = true;
    723	int ret = -EINVAL;
    724
    725	/* Hardware only support oneshot or indefinite loops */
    726	if (repeat != -1 && repeat != 1)
    727		return -EINVAL;
    728
    729	/*
    730	 * The standardized leds-trigger-pattern format defines that the
    731	 * brightness of the LED follows a linear transition from one entry
    732	 * in the pattern to the next, over the given delta_t time. It
    733	 * describes that the way to perform instant transitions a zero-length
    734	 * entry should be added following a pattern entry.
    735	 *
    736	 * The LPG hardware is only able to perform the latter (no linear
    737	 * transitions), so require each entry in the pattern to be followed by
    738	 * a zero-length transition.
    739	 */
    740	if (len % 2)
    741		return -EINVAL;
    742
    743	pattern = kcalloc(len / 2, sizeof(*pattern), GFP_KERNEL);
    744	if (!pattern)
    745		return -ENOMEM;
    746
    747	for (i = 0; i < len; i += 2) {
    748		if (led_pattern[i].brightness != led_pattern[i + 1].brightness)
    749			goto out_free_pattern;
    750		if (led_pattern[i + 1].delta_t != 0)
    751			goto out_free_pattern;
    752
    753		pattern[i / 2].brightness = led_pattern[i].brightness;
    754		pattern[i / 2].delta_t = led_pattern[i].delta_t;
    755	}
    756
    757	len /= 2;
    758
    759	/*
    760	 * Specifying a pattern of length 1 causes the hardware to iterate
    761	 * through the entire LUT, so prohibit this.
    762	 */
    763	if (len < 2)
    764		goto out_free_pattern;
    765
    766	/*
    767	 * The LPG plays patterns with at a fixed pace, a "low pause" can be
    768	 * used to stretch the first delay of the pattern and a "high pause"
    769	 * the last one.
    770	 *
    771	 * In order to save space the pattern can be played in "ping pong"
    772	 * mode, in which the pattern is first played forward, then "high
    773	 * pause" is applied, then the pattern is played backwards and finally
    774	 * the "low pause" is applied.
    775	 *
    776	 * The middle elements of the pattern are used to determine delta_t and
    777	 * the "low pause" and "high pause" multipliers are derrived from this.
    778	 *
    779	 * The first element in the pattern is used to determine "low pause".
    780	 *
    781	 * If the specified pattern is a palindrome the ping pong mode is
    782	 * enabled. In this scenario the delta_t of the middle entry (i.e. the
    783	 * last in the programmed pattern) determines the "high pause".
    784	 */
    785
    786	/* Detect palindromes and use "ping pong" to reduce LUT usage */
    787	for (i = 0; i < len / 2; i++) {
    788		brightness_a = pattern[i].brightness;
    789		brightness_b = pattern[len - i - 1].brightness;
    790
    791		if (brightness_a != brightness_b) {
    792			ping_pong = false;
    793			break;
    794		}
    795	}
    796
    797	/* The pattern length to be written to the LUT */
    798	if (ping_pong)
    799		actual_len = (len + 1) / 2;
    800	else
    801		actual_len = len;
    802
    803	/*
    804	 * Validate that all delta_t in the pattern are the same, with the
    805	 * exception of the middle element in case of ping_pong.
    806	 */
    807	delta_t = pattern[1].delta_t;
    808	for (i = 2; i < len; i++) {
    809		if (pattern[i].delta_t != delta_t) {
    810			/*
    811			 * Allow last entry in the full or shortened pattern to
    812			 * specify hi pause. Reject other variations.
    813			 */
    814			if (i != actual_len - 1)
    815				goto out_free_pattern;
    816		}
    817	}
    818
    819	/* LPG_RAMP_DURATION_REG is a 9bit */
    820	if (delta_t >= BIT(9))
    821		goto out_free_pattern;
    822
    823	/* Find "low pause" and "high pause" in the pattern */
    824	lo_pause = pattern[0].delta_t;
    825	hi_pause = pattern[actual_len - 1].delta_t;
    826
    827	mutex_lock(&lpg->lock);
    828	ret = lpg_lut_store(lpg, pattern, actual_len, &lo_idx, &hi_idx);
    829	if (ret < 0)
    830		goto out_unlock;
    831
    832	for (i = 0; i < led->num_channels; i++) {
    833		chan = led->channels[i];
    834
    835		chan->ramp_tick_ms = delta_t;
    836		chan->ramp_ping_pong = ping_pong;
    837		chan->ramp_oneshot = repeat != -1;
    838
    839		chan->ramp_lo_pause_ms = lo_pause;
    840		chan->ramp_hi_pause_ms = hi_pause;
    841
    842		chan->pattern_lo_idx = lo_idx;
    843		chan->pattern_hi_idx = hi_idx;
    844	}
    845
    846out_unlock:
    847	mutex_unlock(&lpg->lock);
    848out_free_pattern:
    849	kfree(pattern);
    850
    851	return ret;
    852}
    853
    854static int lpg_pattern_single_set(struct led_classdev *cdev,
    855				  struct led_pattern *pattern, u32 len,
    856				  int repeat)
    857{
    858	struct lpg_led *led = container_of(cdev, struct lpg_led, cdev);
    859	int ret;
    860
    861	ret = lpg_pattern_set(led, pattern, len, repeat);
    862	if (ret < 0)
    863		return ret;
    864
    865	lpg_brightness_single_set(cdev, LED_FULL);
    866
    867	return 0;
    868}
    869
    870static int lpg_pattern_mc_set(struct led_classdev *cdev,
    871			      struct led_pattern *pattern, u32 len,
    872			      int repeat)
    873{
    874	struct led_classdev_mc *mc = lcdev_to_mccdev(cdev);
    875	struct lpg_led *led = container_of(mc, struct lpg_led, mcdev);
    876	int ret;
    877
    878	ret = lpg_pattern_set(led, pattern, len, repeat);
    879	if (ret < 0)
    880		return ret;
    881
    882	led_mc_calc_color_components(mc, LED_FULL);
    883	lpg_brightness_set(led, cdev, mc->subled_info);
    884
    885	return 0;
    886}
    887
    888static int lpg_pattern_clear(struct lpg_led *led)
    889{
    890	struct lpg_channel *chan;
    891	struct lpg *lpg = led->lpg;
    892	int i;
    893
    894	mutex_lock(&lpg->lock);
    895
    896	chan = led->channels[0];
    897	lpg_lut_free(lpg, chan->pattern_lo_idx, chan->pattern_hi_idx);
    898
    899	for (i = 0; i < led->num_channels; i++) {
    900		chan = led->channels[i];
    901		chan->pattern_lo_idx = 0;
    902		chan->pattern_hi_idx = 0;
    903	}
    904
    905	mutex_unlock(&lpg->lock);
    906
    907	return 0;
    908}
    909
    910static int lpg_pattern_single_clear(struct led_classdev *cdev)
    911{
    912	struct lpg_led *led = container_of(cdev, struct lpg_led, cdev);
    913
    914	return lpg_pattern_clear(led);
    915}
    916
    917static int lpg_pattern_mc_clear(struct led_classdev *cdev)
    918{
    919	struct led_classdev_mc *mc = lcdev_to_mccdev(cdev);
    920	struct lpg_led *led = container_of(mc, struct lpg_led, mcdev);
    921
    922	return lpg_pattern_clear(led);
    923}
    924
    925static int lpg_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
    926{
    927	struct lpg *lpg = container_of(chip, struct lpg, pwm);
    928	struct lpg_channel *chan = &lpg->channels[pwm->hwpwm];
    929
    930	return chan->in_use ? -EBUSY : 0;
    931}
    932
    933/*
    934 * Limitations:
    935 * - Updating both duty and period is not done atomically, so the output signal
    936 *   will momentarily be a mix of the settings.
    937 * - Changed parameters takes effect immediately.
    938 * - A disabled channel outputs a logical 0.
    939 */
    940static int lpg_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
    941			 const struct pwm_state *state)
    942{
    943	struct lpg *lpg = container_of(chip, struct lpg, pwm);
    944	struct lpg_channel *chan = &lpg->channels[pwm->hwpwm];
    945	int ret = 0;
    946
    947	if (state->polarity != PWM_POLARITY_NORMAL)
    948		return -EINVAL;
    949
    950	mutex_lock(&lpg->lock);
    951
    952	if (state->enabled) {
    953		ret = lpg_calc_freq(chan, state->period);
    954		if (ret < 0)
    955			goto out_unlock;
    956
    957		lpg_calc_duty(chan, state->duty_cycle);
    958	}
    959	chan->enabled = state->enabled;
    960
    961	lpg_apply(chan);
    962
    963	triled_set(lpg, chan->triled_mask, chan->enabled ? chan->triled_mask : 0);
    964
    965out_unlock:
    966	mutex_unlock(&lpg->lock);
    967
    968	return ret;
    969}
    970
    971static void lpg_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
    972			      struct pwm_state *state)
    973{
    974	struct lpg *lpg = container_of(chip, struct lpg, pwm);
    975	struct lpg_channel *chan = &lpg->channels[pwm->hwpwm];
    976	unsigned int pre_div;
    977	unsigned int refclk;
    978	unsigned int val;
    979	unsigned int m;
    980	u16 pwm_value;
    981	int ret;
    982
    983	ret = regmap_read(lpg->map, chan->base + LPG_SIZE_CLK_REG, &val);
    984	if (ret)
    985		return;
    986
    987	refclk = lpg_clk_rates[val & PWM_CLK_SELECT_MASK];
    988	if (refclk) {
    989		ret = regmap_read(lpg->map, chan->base + LPG_PREDIV_CLK_REG, &val);
    990		if (ret)
    991			return;
    992
    993		pre_div = lpg_pre_divs[FIELD_GET(PWM_FREQ_PRE_DIV_MASK, val)];
    994		m = FIELD_GET(PWM_FREQ_EXP_MASK, val);
    995
    996		ret = regmap_bulk_read(lpg->map, chan->base + PWM_VALUE_REG, &pwm_value, sizeof(pwm_value));
    997		if (ret)
    998			return;
    999
   1000		state->period = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC * LPG_RESOLUTION * pre_div * (1 << m), refclk);
   1001		state->duty_cycle = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC * pwm_value * pre_div * (1 << m), refclk);
   1002	} else {
   1003		state->period = 0;
   1004		state->duty_cycle = 0;
   1005	}
   1006
   1007	ret = regmap_read(lpg->map, chan->base + PWM_ENABLE_CONTROL_REG, &val);
   1008	if (ret)
   1009		return;
   1010
   1011	state->enabled = FIELD_GET(LPG_ENABLE_CONTROL_OUTPUT, val);
   1012	state->polarity = PWM_POLARITY_NORMAL;
   1013
   1014	if (state->duty_cycle > state->period)
   1015		state->duty_cycle = state->period;
   1016}
   1017
   1018static const struct pwm_ops lpg_pwm_ops = {
   1019	.request = lpg_pwm_request,
   1020	.apply = lpg_pwm_apply,
   1021	.get_state = lpg_pwm_get_state,
   1022	.owner = THIS_MODULE,
   1023};
   1024
   1025static int lpg_add_pwm(struct lpg *lpg)
   1026{
   1027	int ret;
   1028
   1029	lpg->pwm.base = -1;
   1030	lpg->pwm.dev = lpg->dev;
   1031	lpg->pwm.npwm = lpg->num_channels;
   1032	lpg->pwm.ops = &lpg_pwm_ops;
   1033
   1034	ret = pwmchip_add(&lpg->pwm);
   1035	if (ret)
   1036		dev_err(lpg->dev, "failed to add PWM chip: ret %d\n", ret);
   1037
   1038	return ret;
   1039}
   1040
   1041static int lpg_parse_channel(struct lpg *lpg, struct device_node *np,
   1042			     struct lpg_channel **channel)
   1043{
   1044	struct lpg_channel *chan;
   1045	u32 color = LED_COLOR_ID_GREEN;
   1046	u32 reg;
   1047	int ret;
   1048
   1049	ret = of_property_read_u32(np, "reg", &reg);
   1050	if (ret || !reg || reg > lpg->num_channels) {
   1051		dev_err(lpg->dev, "invalid \"reg\" of %pOFn\n", np);
   1052		return -EINVAL;
   1053	}
   1054
   1055	chan = &lpg->channels[reg - 1];
   1056	chan->in_use = true;
   1057
   1058	ret = of_property_read_u32(np, "color", &color);
   1059	if (ret < 0 && ret != -EINVAL) {
   1060		dev_err(lpg->dev, "failed to parse \"color\" of %pOF\n", np);
   1061		return ret;
   1062	}
   1063
   1064	chan->color = color;
   1065
   1066	*channel = chan;
   1067
   1068	return 0;
   1069}
   1070
   1071static int lpg_add_led(struct lpg *lpg, struct device_node *np)
   1072{
   1073	struct led_init_data init_data = {};
   1074	struct led_classdev *cdev;
   1075	struct device_node *child;
   1076	struct mc_subled *info;
   1077	struct lpg_led *led;
   1078	const char *state;
   1079	int num_channels;
   1080	u32 color = 0;
   1081	int ret;
   1082	int i;
   1083
   1084	ret = of_property_read_u32(np, "color", &color);
   1085	if (ret < 0 && ret != -EINVAL) {
   1086		dev_err(lpg->dev, "failed to parse \"color\" of %pOF\n", np);
   1087		return ret;
   1088	}
   1089
   1090	if (color == LED_COLOR_ID_RGB)
   1091		num_channels = of_get_available_child_count(np);
   1092	else
   1093		num_channels = 1;
   1094
   1095	led = devm_kzalloc(lpg->dev, struct_size(led, channels, num_channels), GFP_KERNEL);
   1096	if (!led)
   1097		return -ENOMEM;
   1098
   1099	led->lpg = lpg;
   1100	led->num_channels = num_channels;
   1101
   1102	if (color == LED_COLOR_ID_RGB) {
   1103		info = devm_kcalloc(lpg->dev, num_channels, sizeof(*info), GFP_KERNEL);
   1104		if (!info)
   1105			return -ENOMEM;
   1106		i = 0;
   1107		for_each_available_child_of_node(np, child) {
   1108			ret = lpg_parse_channel(lpg, child, &led->channels[i]);
   1109			if (ret < 0)
   1110				return ret;
   1111
   1112			info[i].color_index = led->channels[i]->color;
   1113			info[i].intensity = 0;
   1114			i++;
   1115		}
   1116
   1117		led->mcdev.subled_info = info;
   1118		led->mcdev.num_colors = num_channels;
   1119
   1120		cdev = &led->mcdev.led_cdev;
   1121		cdev->brightness_set = lpg_brightness_mc_set;
   1122		cdev->blink_set = lpg_blink_mc_set;
   1123
   1124		/* Register pattern accessors only if we have a LUT block */
   1125		if (lpg->lut_base) {
   1126			cdev->pattern_set = lpg_pattern_mc_set;
   1127			cdev->pattern_clear = lpg_pattern_mc_clear;
   1128		}
   1129	} else {
   1130		ret = lpg_parse_channel(lpg, np, &led->channels[0]);
   1131		if (ret < 0)
   1132			return ret;
   1133
   1134		cdev = &led->cdev;
   1135		cdev->brightness_set = lpg_brightness_single_set;
   1136		cdev->blink_set = lpg_blink_single_set;
   1137
   1138		/* Register pattern accessors only if we have a LUT block */
   1139		if (lpg->lut_base) {
   1140			cdev->pattern_set = lpg_pattern_single_set;
   1141			cdev->pattern_clear = lpg_pattern_single_clear;
   1142		}
   1143	}
   1144
   1145	cdev->default_trigger = of_get_property(np, "linux,default-trigger", NULL);
   1146	cdev->max_brightness = LPG_RESOLUTION - 1;
   1147
   1148	if (!of_property_read_string(np, "default-state", &state) &&
   1149	    !strcmp(state, "on"))
   1150		cdev->brightness = cdev->max_brightness;
   1151	else
   1152		cdev->brightness = LED_OFF;
   1153
   1154	cdev->brightness_set(cdev, cdev->brightness);
   1155
   1156	init_data.fwnode = of_fwnode_handle(np);
   1157
   1158	if (color == LED_COLOR_ID_RGB)
   1159		ret = devm_led_classdev_multicolor_register_ext(lpg->dev, &led->mcdev, &init_data);
   1160	else
   1161		ret = devm_led_classdev_register_ext(lpg->dev, &led->cdev, &init_data);
   1162	if (ret)
   1163		dev_err(lpg->dev, "unable to register %s\n", cdev->name);
   1164
   1165	return ret;
   1166}
   1167
   1168static int lpg_init_channels(struct lpg *lpg)
   1169{
   1170	const struct lpg_data *data = lpg->data;
   1171	struct lpg_channel *chan;
   1172	int i;
   1173
   1174	lpg->num_channels = data->num_channels;
   1175	lpg->channels = devm_kcalloc(lpg->dev, data->num_channels,
   1176				     sizeof(struct lpg_channel), GFP_KERNEL);
   1177	if (!lpg->channels)
   1178		return -ENOMEM;
   1179
   1180	for (i = 0; i < data->num_channels; i++) {
   1181		chan = &lpg->channels[i];
   1182
   1183		chan->lpg = lpg;
   1184		chan->base = data->channels[i].base;
   1185		chan->triled_mask = data->channels[i].triled_mask;
   1186		chan->lut_mask = BIT(i);
   1187
   1188		regmap_read(lpg->map, chan->base + LPG_SUBTYPE_REG, &chan->subtype);
   1189	}
   1190
   1191	return 0;
   1192}
   1193
   1194static int lpg_init_triled(struct lpg *lpg)
   1195{
   1196	struct device_node *np = lpg->dev->of_node;
   1197	int ret;
   1198
   1199	/* Skip initialization if we don't have a triled block */
   1200	if (!lpg->data->triled_base)
   1201		return 0;
   1202
   1203	lpg->triled_base = lpg->data->triled_base;
   1204	lpg->triled_has_atc_ctl = lpg->data->triled_has_atc_ctl;
   1205	lpg->triled_has_src_sel = lpg->data->triled_has_src_sel;
   1206
   1207	if (lpg->triled_has_src_sel) {
   1208		ret = of_property_read_u32(np, "qcom,power-source", &lpg->triled_src);
   1209		if (ret || lpg->triled_src == 2 || lpg->triled_src > 3) {
   1210			dev_err(lpg->dev, "invalid power source\n");
   1211			return -EINVAL;
   1212		}
   1213	}
   1214
   1215	/* Disable automatic trickle charge LED */
   1216	if (lpg->triled_has_atc_ctl)
   1217		regmap_write(lpg->map, lpg->triled_base + TRI_LED_ATC_CTL, 0);
   1218
   1219	/* Configure power source */
   1220	if (lpg->triled_has_src_sel)
   1221		regmap_write(lpg->map, lpg->triled_base + TRI_LED_SRC_SEL, lpg->triled_src);
   1222
   1223	/* Default all outputs to off */
   1224	regmap_write(lpg->map, lpg->triled_base + TRI_LED_EN_CTL, 0);
   1225
   1226	return 0;
   1227}
   1228
   1229static int lpg_init_lut(struct lpg *lpg)
   1230{
   1231	const struct lpg_data *data = lpg->data;
   1232
   1233	if (!data->lut_base)
   1234		return 0;
   1235
   1236	lpg->lut_base = data->lut_base;
   1237	lpg->lut_size = data->lut_size;
   1238
   1239	lpg->lut_bitmap = devm_bitmap_zalloc(lpg->dev, lpg->lut_size, GFP_KERNEL);
   1240	if (!lpg->lut_bitmap)
   1241		return -ENOMEM;
   1242
   1243	return 0;
   1244}
   1245
   1246static int lpg_probe(struct platform_device *pdev)
   1247{
   1248	struct device_node *np;
   1249	struct lpg *lpg;
   1250	int ret;
   1251	int i;
   1252
   1253	lpg = devm_kzalloc(&pdev->dev, sizeof(*lpg), GFP_KERNEL);
   1254	if (!lpg)
   1255		return -ENOMEM;
   1256
   1257	lpg->data = of_device_get_match_data(&pdev->dev);
   1258	if (!lpg->data)
   1259		return -EINVAL;
   1260
   1261	platform_set_drvdata(pdev, lpg);
   1262
   1263	lpg->dev = &pdev->dev;
   1264	mutex_init(&lpg->lock);
   1265
   1266	lpg->map = dev_get_regmap(pdev->dev.parent, NULL);
   1267	if (!lpg->map)
   1268		return dev_err_probe(&pdev->dev, -ENXIO, "parent regmap unavailable\n");
   1269
   1270	ret = lpg_init_channels(lpg);
   1271	if (ret < 0)
   1272		return ret;
   1273
   1274	ret = lpg_parse_dtest(lpg);
   1275	if (ret < 0)
   1276		return ret;
   1277
   1278	ret = lpg_init_triled(lpg);
   1279	if (ret < 0)
   1280		return ret;
   1281
   1282	ret = lpg_init_lut(lpg);
   1283	if (ret < 0)
   1284		return ret;
   1285
   1286	for_each_available_child_of_node(pdev->dev.of_node, np) {
   1287		ret = lpg_add_led(lpg, np);
   1288		if (ret)
   1289			return ret;
   1290	}
   1291
   1292	for (i = 0; i < lpg->num_channels; i++)
   1293		lpg_apply_dtest(&lpg->channels[i]);
   1294
   1295	return lpg_add_pwm(lpg);
   1296}
   1297
   1298static int lpg_remove(struct platform_device *pdev)
   1299{
   1300	struct lpg *lpg = platform_get_drvdata(pdev);
   1301
   1302	pwmchip_remove(&lpg->pwm);
   1303
   1304	return 0;
   1305}
   1306
   1307static const struct lpg_data pm8916_pwm_data = {
   1308	.num_channels = 1,
   1309	.channels = (const struct lpg_channel_data[]) {
   1310		{ .base = 0xbc00 },
   1311	},
   1312};
   1313
   1314static const struct lpg_data pm8941_lpg_data = {
   1315	.lut_base = 0xb000,
   1316	.lut_size = 64,
   1317
   1318	.triled_base = 0xd000,
   1319	.triled_has_atc_ctl = true,
   1320	.triled_has_src_sel = true,
   1321
   1322	.num_channels = 8,
   1323	.channels = (const struct lpg_channel_data[]) {
   1324		{ .base = 0xb100 },
   1325		{ .base = 0xb200 },
   1326		{ .base = 0xb300 },
   1327		{ .base = 0xb400 },
   1328		{ .base = 0xb500, .triled_mask = BIT(5) },
   1329		{ .base = 0xb600, .triled_mask = BIT(6) },
   1330		{ .base = 0xb700, .triled_mask = BIT(7) },
   1331		{ .base = 0xb800 },
   1332	},
   1333};
   1334
   1335static const struct lpg_data pm8994_lpg_data = {
   1336	.lut_base = 0xb000,
   1337	.lut_size = 64,
   1338
   1339	.num_channels = 6,
   1340	.channels = (const struct lpg_channel_data[]) {
   1341		{ .base = 0xb100 },
   1342		{ .base = 0xb200 },
   1343		{ .base = 0xb300 },
   1344		{ .base = 0xb400 },
   1345		{ .base = 0xb500 },
   1346		{ .base = 0xb600 },
   1347	},
   1348};
   1349
   1350static const struct lpg_data pmi8994_lpg_data = {
   1351	.lut_base = 0xb000,
   1352	.lut_size = 24,
   1353
   1354	.triled_base = 0xd000,
   1355	.triled_has_atc_ctl = true,
   1356	.triled_has_src_sel = true,
   1357
   1358	.num_channels = 4,
   1359	.channels = (const struct lpg_channel_data[]) {
   1360		{ .base = 0xb100, .triled_mask = BIT(5) },
   1361		{ .base = 0xb200, .triled_mask = BIT(6) },
   1362		{ .base = 0xb300, .triled_mask = BIT(7) },
   1363		{ .base = 0xb400 },
   1364	},
   1365};
   1366
   1367static const struct lpg_data pmi8998_lpg_data = {
   1368	.lut_base = 0xb000,
   1369	.lut_size = 49,
   1370
   1371	.triled_base = 0xd000,
   1372
   1373	.num_channels = 6,
   1374	.channels = (const struct lpg_channel_data[]) {
   1375		{ .base = 0xb100 },
   1376		{ .base = 0xb200 },
   1377		{ .base = 0xb300, .triled_mask = BIT(5) },
   1378		{ .base = 0xb400, .triled_mask = BIT(6) },
   1379		{ .base = 0xb500, .triled_mask = BIT(7) },
   1380		{ .base = 0xb600 },
   1381	},
   1382};
   1383
   1384static const struct lpg_data pm8150b_lpg_data = {
   1385	.lut_base = 0xb000,
   1386	.lut_size = 24,
   1387
   1388	.triled_base = 0xd000,
   1389
   1390	.num_channels = 2,
   1391	.channels = (const struct lpg_channel_data[]) {
   1392		{ .base = 0xb100, .triled_mask = BIT(7) },
   1393		{ .base = 0xb200, .triled_mask = BIT(6) },
   1394	},
   1395};
   1396
   1397static const struct lpg_data pm8150l_lpg_data = {
   1398	.lut_base = 0xb000,
   1399	.lut_size = 48,
   1400
   1401	.triled_base = 0xd000,
   1402
   1403	.num_channels = 5,
   1404	.channels = (const struct lpg_channel_data[]) {
   1405		{ .base = 0xb100, .triled_mask = BIT(7) },
   1406		{ .base = 0xb200, .triled_mask = BIT(6) },
   1407		{ .base = 0xb300, .triled_mask = BIT(5) },
   1408		{ .base = 0xbc00 },
   1409		{ .base = 0xbd00 },
   1410
   1411	},
   1412};
   1413
   1414static const struct lpg_data pm8350c_pwm_data = {
   1415	.triled_base = 0xef00,
   1416
   1417	.num_channels = 4,
   1418	.channels = (const struct lpg_channel_data[]) {
   1419		{ .base = 0xe800, .triled_mask = BIT(7) },
   1420		{ .base = 0xe900, .triled_mask = BIT(6) },
   1421		{ .base = 0xea00, .triled_mask = BIT(5) },
   1422		{ .base = 0xeb00 },
   1423	},
   1424};
   1425
   1426static const struct of_device_id lpg_of_table[] = {
   1427	{ .compatible = "qcom,pm8150b-lpg", .data = &pm8150b_lpg_data },
   1428	{ .compatible = "qcom,pm8150l-lpg", .data = &pm8150l_lpg_data },
   1429	{ .compatible = "qcom,pm8350c-pwm", .data = &pm8350c_pwm_data },
   1430	{ .compatible = "qcom,pm8916-pwm", .data = &pm8916_pwm_data },
   1431	{ .compatible = "qcom,pm8941-lpg", .data = &pm8941_lpg_data },
   1432	{ .compatible = "qcom,pm8994-lpg", .data = &pm8994_lpg_data },
   1433	{ .compatible = "qcom,pmi8994-lpg", .data = &pmi8994_lpg_data },
   1434	{ .compatible = "qcom,pmi8998-lpg", .data = &pmi8998_lpg_data },
   1435	{ .compatible = "qcom,pmc8180c-lpg", .data = &pm8150l_lpg_data },
   1436	{}
   1437};
   1438MODULE_DEVICE_TABLE(of, lpg_of_table);
   1439
   1440static struct platform_driver lpg_driver = {
   1441	.probe = lpg_probe,
   1442	.remove = lpg_remove,
   1443	.driver = {
   1444		.name = "qcom-spmi-lpg",
   1445		.of_match_table = lpg_of_table,
   1446	},
   1447};
   1448module_platform_driver(lpg_driver);
   1449
   1450MODULE_DESCRIPTION("Qualcomm LPG LED driver");
   1451MODULE_LICENSE("GPL v2");