Lines Matching +full:pm8916 +full:- +full:pwm

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2017-2022 Linaro Ltd
4 * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
9 #include <linux/led-class-multicolor.h>
13 #include <linux/pwm.h>
40 #define PWM_DTEST_REG(x) (0xe2 + (x) - 1)
58 * struct lpg - LPG device context
61 * @lock: used to synchronize LED and pwm callback requests
62 * @pwm: PWM-chip object, if operating in PWM mode
68 * @triled_src: power-source for the TRILED
71 * @channels: list of PWM channels
80 struct pwm_chip pwm; member
98 * struct lpg_channel - per channel data
100 * @base: base address of the PWM channel
114 * @pwm_resolution_sel: pwm resolution selector
162 * struct lpg_led - logical LED object
180 * struct lpg_channel_data - per channel initialization data
181 * @base: base address for PWM channel registers
190 * struct lpg_data - initialization data
212 if (!lpg->triled_base) in triled_set()
215 return regmap_update_bits(lpg->map, lpg->triled_base + TRI_LED_EN_CTL, in triled_set()
226 idx = bitmap_find_next_zero_area(lpg->lut_bitmap, lpg->lut_size, in lpg_lut_store()
228 if (idx >= lpg->lut_size) in lpg_lut_store()
229 return -ENOMEM; in lpg_lut_store()
234 regmap_bulk_write(lpg->map, lpg->lut_base + LPG_LUT_REG(idx + i), in lpg_lut_store()
238 bitmap_set(lpg->lut_bitmap, idx, len); in lpg_lut_store()
241 *hi_idx = idx + len - 1; in lpg_lut_store()
250 len = hi_idx - lo_idx + 1; in lpg_lut_free()
254 bitmap_clear(lpg->lut_bitmap, lo_idx, len); in lpg_lut_free()
259 return regmap_write(lpg->map, lpg->lut_base + RAMP_CONTROL_REG, mask); in lpg_lut_sync()
283 * The PWM period is determined by: in lpg_calc_freq()
286 * period = -------------------------- in lpg_calc_freq()
289 * Resolution = 2^9 bits for PWM or in lpg_calc_freq()
290 * 2^{8, 9, 10, 11, 12, 13, 14, 15} bits for high resolution PWM in lpg_calc_freq()
294 * This allows for periods between 27uS and 384s for PWM channels and periods between in lpg_calc_freq()
296 * The PWM framework wants a period of equal or lower length than requested, in lpg_calc_freq()
300 if (chan->subtype == LPG_SUBTYPE_HI_RES_PWM) { in lpg_calc_freq()
315 clk_rate_arr[clk_len - 1]); in lpg_calc_freq()
317 return -EINVAL; in lpg_calc_freq()
330 * M = log2 ------------------------------------- in lpg_calc_freq()
355 error = period - actual; in lpg_calc_freq()
367 chan->clk_sel = best_clk; in lpg_calc_freq()
368 chan->pre_div_sel = best_div; in lpg_calc_freq()
369 chan->pre_div_exp = best_m; in lpg_calc_freq()
370 chan->period = best_period; in lpg_calc_freq()
371 chan->pwm_resolution_sel = best_pwm_resolution_sel; in lpg_calc_freq()
381 if (chan->subtype == LPG_SUBTYPE_HI_RES_PWM) { in lpg_calc_duty()
382 max = LPG_RESOLUTION_15BIT - 1; in lpg_calc_duty()
383 clk_rate = lpg_clk_rates_hi_res[chan->clk_sel]; in lpg_calc_duty()
385 max = LPG_RESOLUTION_9BIT - 1; in lpg_calc_duty()
386 clk_rate = lpg_clk_rates[chan->clk_sel]; in lpg_calc_duty()
390 (u64)NSEC_PER_SEC * lpg_pre_divs[chan->pre_div_sel] * (1 << chan->pre_div_exp)); in lpg_calc_duty()
392 chan->pwm_value = min(val, max); in lpg_calc_duty()
398 struct lpg *lpg = chan->lpg; in lpg_apply_freq()
400 if (!chan->enabled) in lpg_apply_freq()
403 val = chan->clk_sel; in lpg_apply_freq()
406 switch (chan->subtype) { in lpg_apply_freq()
414 val |= FIELD_PREP(PWM_SIZE_HI_RES_MASK, chan->pwm_resolution_sel); in lpg_apply_freq()
422 regmap_write(lpg->map, chan->base + LPG_SIZE_CLK_REG, val); in lpg_apply_freq()
424 val = FIELD_PREP(PWM_FREQ_PRE_DIV_MASK, chan->pre_div_sel) | in lpg_apply_freq()
425 FIELD_PREP(PWM_FREQ_EXP_MASK, chan->pre_div_exp); in lpg_apply_freq()
426 regmap_write(lpg->map, chan->base + LPG_PREDIV_CLK_REG, val); in lpg_apply_freq()
433 struct lpg *lpg = chan->lpg; in lpg_enable_glitch()
435 regmap_update_bits(lpg->map, chan->base + PWM_TYPE_CONFIG_REG, in lpg_enable_glitch()
441 struct lpg *lpg = chan->lpg; in lpg_disable_glitch()
443 regmap_update_bits(lpg->map, chan->base + PWM_TYPE_CONFIG_REG, in lpg_disable_glitch()
450 struct lpg *lpg = chan->lpg; in lpg_apply_pwm_value()
451 u16 val = chan->pwm_value; in lpg_apply_pwm_value()
453 if (!chan->enabled) in lpg_apply_pwm_value()
456 regmap_bulk_write(lpg->map, chan->base + PWM_VALUE_REG, &val, sizeof(val)); in lpg_apply_pwm_value()
467 struct lpg *lpg = chan->lpg; in lpg_apply_lut_control()
471 unsigned int lo_idx = chan->pattern_lo_idx; in lpg_apply_lut_control()
472 unsigned int hi_idx = chan->pattern_hi_idx; in lpg_apply_lut_control()
473 u16 step = chan->ramp_tick_ms; in lpg_apply_lut_control()
475 if (!chan->ramp_enabled || chan->pattern_lo_idx == chan->pattern_hi_idx) in lpg_apply_lut_control()
478 hi_pause = DIV_ROUND_UP(chan->ramp_hi_pause_ms, step); in lpg_apply_lut_control()
479 lo_pause = DIV_ROUND_UP(chan->ramp_lo_pause_ms, step); in lpg_apply_lut_control()
481 if (!chan->ramp_reverse) in lpg_apply_lut_control()
483 if (!chan->ramp_oneshot) in lpg_apply_lut_control()
485 if (chan->ramp_ping_pong) in lpg_apply_lut_control()
487 if (chan->ramp_hi_pause_ms) in lpg_apply_lut_control()
489 if (chan->ramp_lo_pause_ms) in lpg_apply_lut_control()
492 regmap_write(lpg->map, chan->base + LPG_PATTERN_CONFIG_REG, conf); in lpg_apply_lut_control()
493 regmap_write(lpg->map, chan->base + LPG_HI_IDX_REG, hi_idx); in lpg_apply_lut_control()
494 regmap_write(lpg->map, chan->base + LPG_LO_IDX_REG, lo_idx); in lpg_apply_lut_control()
496 regmap_bulk_write(lpg->map, chan->base + LPG_RAMP_DURATION_REG, &step, sizeof(step)); in lpg_apply_lut_control()
497 regmap_write(lpg->map, chan->base + LPG_HI_PAUSE_REG, hi_pause); in lpg_apply_lut_control()
498 regmap_write(lpg->map, chan->base + LPG_LO_PAUSE_REG, lo_pause); in lpg_apply_lut_control()
509 struct lpg *lpg = chan->lpg; in lpg_apply_control()
513 if (chan->enabled) in lpg_apply_control()
516 if (chan->pattern_lo_idx != chan->pattern_hi_idx) in lpg_apply_control()
521 regmap_write(lpg->map, chan->base + PWM_ENABLE_CONTROL_REG, ctrl); in lpg_apply_control()
524 * Due to LPG hardware bug, in the PWM mode, having enabled PWM, in lpg_apply_control()
525 * We have to write PWM values one more time. in lpg_apply_control()
527 if (chan->enabled) in lpg_apply_control()
535 struct lpg *lpg = chan->lpg; in lpg_apply_sync()
537 regmap_write(lpg->map, chan->base + PWM_SYNC_REG, LPG_SYNC_PWM); in lpg_apply_sync()
543 struct device_node *np = lpg->dev->of_node; in lpg_parse_dtest()
549 if (count == -EINVAL) { in lpg_parse_dtest()
554 } else if (count != lpg->data->num_channels * 2) { in lpg_parse_dtest()
555 return dev_err_probe(lpg->dev, -EINVAL, in lpg_parse_dtest()
557 lpg->data->num_channels * 2); in lpg_parse_dtest()
560 for (i = 0; i < lpg->data->num_channels; i++) { in lpg_parse_dtest()
561 chan = &lpg->channels[i]; in lpg_parse_dtest()
564 &chan->dtest_line); in lpg_parse_dtest()
569 &chan->dtest_value); in lpg_parse_dtest()
577 return dev_err_probe(lpg->dev, ret, "malformed qcom,dtest\n"); in lpg_parse_dtest()
582 struct lpg *lpg = chan->lpg; in lpg_apply_dtest()
584 if (!chan->dtest_line) in lpg_apply_dtest()
587 regmap_write(lpg->map, chan->base + PWM_SEC_ACCESS_REG, 0xa5); in lpg_apply_dtest()
588 regmap_write(lpg->map, chan->base + PWM_DTEST_REG(chan->dtest_line), in lpg_apply_dtest()
589 chan->dtest_value); in lpg_apply_dtest()
612 struct lpg *lpg = led->lpg; in lpg_brightness_set()
615 for (i = 0; i < led->num_channels; i++) { in lpg_brightness_set()
616 chan = led->channels[i]; in lpg_brightness_set()
620 chan->enabled = false; in lpg_brightness_set()
621 chan->ramp_enabled = false; in lpg_brightness_set()
622 } else if (chan->pattern_lo_idx != chan->pattern_hi_idx) { in lpg_brightness_set()
625 chan->enabled = true; in lpg_brightness_set()
626 chan->ramp_enabled = true; in lpg_brightness_set()
628 lut_mask |= chan->lut_mask; in lpg_brightness_set()
629 triled_enabled |= chan->triled_mask; in lpg_brightness_set()
633 duty = div_u64(brightness * chan->period, cdev->max_brightness); in lpg_brightness_set()
635 chan->enabled = true; in lpg_brightness_set()
636 chan->ramp_enabled = false; in lpg_brightness_set()
638 triled_enabled |= chan->triled_mask; in lpg_brightness_set()
641 triled_mask |= chan->triled_mask; in lpg_brightness_set()
661 mutex_lock(&led->lpg->lock); in lpg_brightness_single_set()
666 mutex_unlock(&led->lpg->lock); in lpg_brightness_single_set()
677 mutex_lock(&led->lpg->lock); in lpg_brightness_mc_set()
680 lpg_brightness_set(led, cdev, mc->subled_info); in lpg_brightness_mc_set()
682 mutex_unlock(&led->lpg->lock); in lpg_brightness_mc_set()
693 struct lpg *lpg = led->lpg; in lpg_blink_set()
705 for (i = 0; i < led->num_channels; i++) { in lpg_blink_set()
706 chan = led->channels[i]; in lpg_blink_set()
711 chan->enabled = true; in lpg_blink_set()
712 chan->ramp_enabled = false; in lpg_blink_set()
714 triled_mask |= chan->triled_mask; in lpg_blink_set()
722 chan = led->channels[0]; in lpg_blink_set()
723 duty = div_u64(chan->pwm_value * chan->period, LPG_RESOLUTION_9BIT); in lpg_blink_set()
725 *delay_off = div_u64(chan->period - duty, NSEC_PER_MSEC); in lpg_blink_set()
736 mutex_lock(&led->lpg->lock); in lpg_blink_single_set()
740 mutex_unlock(&led->lpg->lock); in lpg_blink_single_set()
752 mutex_lock(&led->lpg->lock); in lpg_blink_mc_set()
756 mutex_unlock(&led->lpg->lock); in lpg_blink_mc_set()
765 struct lpg *lpg = led->lpg; in lpg_pattern_set()
777 int ret = -EINVAL; in lpg_pattern_set()
780 if (repeat != -1 && repeat != 1) in lpg_pattern_set()
781 return -EINVAL; in lpg_pattern_set()
784 * The standardized leds-trigger-pattern format defines that the in lpg_pattern_set()
787 * describes that the way to perform instant transitions a zero-length in lpg_pattern_set()
792 * a zero-length transition. in lpg_pattern_set()
795 return -EINVAL; in lpg_pattern_set()
799 return -ENOMEM; in lpg_pattern_set()
843 brightness_b = pattern[len - i - 1].brightness; in lpg_pattern_set()
868 if (i != actual_len - 1) in lpg_pattern_set()
879 hi_pause = pattern[actual_len - 1].delta_t; in lpg_pattern_set()
881 mutex_lock(&lpg->lock); in lpg_pattern_set()
886 for (i = 0; i < led->num_channels; i++) { in lpg_pattern_set()
887 chan = led->channels[i]; in lpg_pattern_set()
889 chan->ramp_tick_ms = delta_t; in lpg_pattern_set()
890 chan->ramp_ping_pong = ping_pong; in lpg_pattern_set()
891 chan->ramp_oneshot = repeat != -1; in lpg_pattern_set()
893 chan->ramp_lo_pause_ms = lo_pause; in lpg_pattern_set()
894 chan->ramp_hi_pause_ms = hi_pause; in lpg_pattern_set()
896 chan->pattern_lo_idx = lo_idx; in lpg_pattern_set()
897 chan->pattern_hi_idx = hi_idx; in lpg_pattern_set()
901 mutex_unlock(&lpg->lock); in lpg_pattern_set()
937 lpg_brightness_set(led, cdev, mc->subled_info); in lpg_pattern_mc_set()
945 struct lpg *lpg = led->lpg; in lpg_pattern_clear()
948 mutex_lock(&lpg->lock); in lpg_pattern_clear()
950 chan = led->channels[0]; in lpg_pattern_clear()
951 lpg_lut_free(lpg, chan->pattern_lo_idx, chan->pattern_hi_idx); in lpg_pattern_clear()
953 for (i = 0; i < led->num_channels; i++) { in lpg_pattern_clear()
954 chan = led->channels[i]; in lpg_pattern_clear()
955 chan->pattern_lo_idx = 0; in lpg_pattern_clear()
956 chan->pattern_hi_idx = 0; in lpg_pattern_clear()
959 mutex_unlock(&lpg->lock); in lpg_pattern_clear()
981 return container_of(chip, struct lpg, pwm); in lpg_pwm_from_chip()
984 static int lpg_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) in lpg_pwm_request() argument
987 struct lpg_channel *chan = &lpg->channels[pwm->hwpwm]; in lpg_pwm_request()
989 return chan->in_use ? -EBUSY : 0; in lpg_pwm_request()
994 * - Updating both duty and period is not done atomically, so the output signal
996 * - Changed parameters takes effect immediately.
997 * - A disabled channel outputs a logical 0.
999 static int lpg_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, in lpg_pwm_apply() argument
1003 struct lpg_channel *chan = &lpg->channels[pwm->hwpwm]; in lpg_pwm_apply()
1006 if (state->polarity != PWM_POLARITY_NORMAL) in lpg_pwm_apply()
1007 return -EINVAL; in lpg_pwm_apply()
1009 mutex_lock(&lpg->lock); in lpg_pwm_apply()
1011 if (state->enabled) { in lpg_pwm_apply()
1012 ret = lpg_calc_freq(chan, state->period); in lpg_pwm_apply()
1016 lpg_calc_duty(chan, state->duty_cycle); in lpg_pwm_apply()
1018 chan->enabled = state->enabled; in lpg_pwm_apply()
1022 triled_set(lpg, chan->triled_mask, chan->enabled ? chan->triled_mask : 0); in lpg_pwm_apply()
1025 mutex_unlock(&lpg->lock); in lpg_pwm_apply()
1030 static int lpg_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, in lpg_pwm_get_state() argument
1034 struct lpg_channel *chan = &lpg->channels[pwm->hwpwm]; in lpg_pwm_get_state()
1043 ret = regmap_read(lpg->map, chan->base + LPG_SIZE_CLK_REG, &val); in lpg_pwm_get_state()
1047 if (chan->subtype == LPG_SUBTYPE_HI_RES_PWM) { in lpg_pwm_get_state()
1056 ret = regmap_read(lpg->map, chan->base + LPG_PREDIV_CLK_REG, &val); in lpg_pwm_get_state()
1063 ret = regmap_bulk_read(lpg->map, chan->base + PWM_VALUE_REG, &pwm_value, sizeof(pwm_value)); in lpg_pwm_get_state()
1067 state->period = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC * (1 << resolution) * in lpg_pwm_get_state()
1069 state->duty_cycle = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC * pwm_value * pre_div * (1 << m), refclk); in lpg_pwm_get_state()
1071 state->period = 0; in lpg_pwm_get_state()
1072 state->duty_cycle = 0; in lpg_pwm_get_state()
1075 ret = regmap_read(lpg->map, chan->base + PWM_ENABLE_CONTROL_REG, &val); in lpg_pwm_get_state()
1079 state->enabled = FIELD_GET(LPG_ENABLE_CONTROL_OUTPUT, val); in lpg_pwm_get_state()
1080 state->polarity = PWM_POLARITY_NORMAL; in lpg_pwm_get_state()
1082 if (state->duty_cycle > state->period) in lpg_pwm_get_state()
1083 state->duty_cycle = state->period; in lpg_pwm_get_state()
1098 lpg->pwm.dev = lpg->dev; in lpg_add_pwm()
1099 lpg->pwm.npwm = lpg->num_channels; in lpg_add_pwm()
1100 lpg->pwm.ops = &lpg_pwm_ops; in lpg_add_pwm()
1102 ret = devm_pwmchip_add(lpg->dev, &lpg->pwm); in lpg_add_pwm()
1104 dev_err_probe(lpg->dev, ret, "failed to add PWM chip\n"); in lpg_add_pwm()
1118 if (ret || !reg || reg > lpg->num_channels) in lpg_parse_channel()
1119 return dev_err_probe(lpg->dev, -EINVAL, "invalid \"reg\" of %pOFn\n", np); in lpg_parse_channel()
1121 chan = &lpg->channels[reg - 1]; in lpg_parse_channel()
1122 chan->in_use = true; in lpg_parse_channel()
1125 if (ret < 0 && ret != -EINVAL) in lpg_parse_channel()
1126 return dev_err_probe(lpg->dev, ret, in lpg_parse_channel()
1129 chan->color = color; in lpg_parse_channel()
1150 if (ret < 0 && ret != -EINVAL) in lpg_add_led()
1151 return dev_err_probe(lpg->dev, ret, in lpg_add_led()
1159 led = devm_kzalloc(lpg->dev, struct_size(led, channels, num_channels), GFP_KERNEL); in lpg_add_led()
1161 return -ENOMEM; in lpg_add_led()
1163 led->lpg = lpg; in lpg_add_led()
1164 led->num_channels = num_channels; in lpg_add_led()
1167 info = devm_kcalloc(lpg->dev, num_channels, sizeof(*info), GFP_KERNEL); in lpg_add_led()
1169 return -ENOMEM; in lpg_add_led()
1172 ret = lpg_parse_channel(lpg, child, &led->channels[i]); in lpg_add_led()
1178 info[i].color_index = led->channels[i]->color; in lpg_add_led()
1183 led->mcdev.subled_info = info; in lpg_add_led()
1184 led->mcdev.num_colors = num_channels; in lpg_add_led()
1186 cdev = &led->mcdev.led_cdev; in lpg_add_led()
1187 cdev->brightness_set_blocking = lpg_brightness_mc_set; in lpg_add_led()
1188 cdev->blink_set = lpg_blink_mc_set; in lpg_add_led()
1191 if (lpg->lut_base) { in lpg_add_led()
1192 cdev->pattern_set = lpg_pattern_mc_set; in lpg_add_led()
1193 cdev->pattern_clear = lpg_pattern_mc_clear; in lpg_add_led()
1196 ret = lpg_parse_channel(lpg, np, &led->channels[0]); in lpg_add_led()
1200 cdev = &led->cdev; in lpg_add_led()
1201 cdev->brightness_set_blocking = lpg_brightness_single_set; in lpg_add_led()
1202 cdev->blink_set = lpg_blink_single_set; in lpg_add_led()
1205 if (lpg->lut_base) { in lpg_add_led()
1206 cdev->pattern_set = lpg_pattern_single_set; in lpg_add_led()
1207 cdev->pattern_clear = lpg_pattern_single_clear; in lpg_add_led()
1211 cdev->default_trigger = of_get_property(np, "linux,default-trigger", NULL); in lpg_add_led()
1212 cdev->max_brightness = LPG_RESOLUTION_9BIT - 1; in lpg_add_led()
1214 if (!of_property_read_string(np, "default-state", &state) && in lpg_add_led()
1216 cdev->brightness = cdev->max_brightness; in lpg_add_led()
1218 cdev->brightness = LED_OFF; in lpg_add_led()
1220 cdev->brightness_set_blocking(cdev, cdev->brightness); in lpg_add_led()
1225 ret = devm_led_classdev_multicolor_register_ext(lpg->dev, &led->mcdev, &init_data); in lpg_add_led()
1227 ret = devm_led_classdev_register_ext(lpg->dev, &led->cdev, &init_data); in lpg_add_led()
1229 dev_err_probe(lpg->dev, ret, "unable to register %s\n", cdev->name); in lpg_add_led()
1236 const struct lpg_data *data = lpg->data; in lpg_init_channels()
1240 lpg->num_channels = data->num_channels; in lpg_init_channels()
1241 lpg->channels = devm_kcalloc(lpg->dev, data->num_channels, in lpg_init_channels()
1243 if (!lpg->channels) in lpg_init_channels()
1244 return -ENOMEM; in lpg_init_channels()
1246 for (i = 0; i < data->num_channels; i++) { in lpg_init_channels()
1247 chan = &lpg->channels[i]; in lpg_init_channels()
1249 chan->lpg = lpg; in lpg_init_channels()
1250 chan->base = data->channels[i].base; in lpg_init_channels()
1251 chan->triled_mask = data->channels[i].triled_mask; in lpg_init_channels()
1252 chan->lut_mask = BIT(i); in lpg_init_channels()
1254 regmap_read(lpg->map, chan->base + LPG_SUBTYPE_REG, &chan->subtype); in lpg_init_channels()
1262 struct device_node *np = lpg->dev->of_node; in lpg_init_triled()
1266 if (!lpg->data->triled_base) in lpg_init_triled()
1269 lpg->triled_base = lpg->data->triled_base; in lpg_init_triled()
1270 lpg->triled_has_atc_ctl = lpg->data->triled_has_atc_ctl; in lpg_init_triled()
1271 lpg->triled_has_src_sel = lpg->data->triled_has_src_sel; in lpg_init_triled()
1273 if (lpg->triled_has_src_sel) { in lpg_init_triled()
1274 ret = of_property_read_u32(np, "qcom,power-source", &lpg->triled_src); in lpg_init_triled()
1275 if (ret || lpg->triled_src == 2 || lpg->triled_src > 3) in lpg_init_triled()
1276 return dev_err_probe(lpg->dev, -EINVAL, in lpg_init_triled()
1281 if (lpg->triled_has_atc_ctl) in lpg_init_triled()
1282 regmap_write(lpg->map, lpg->triled_base + TRI_LED_ATC_CTL, 0); in lpg_init_triled()
1285 if (lpg->triled_has_src_sel) in lpg_init_triled()
1286 regmap_write(lpg->map, lpg->triled_base + TRI_LED_SRC_SEL, lpg->triled_src); in lpg_init_triled()
1289 regmap_write(lpg->map, lpg->triled_base + TRI_LED_EN_CTL, 0); in lpg_init_triled()
1296 const struct lpg_data *data = lpg->data; in lpg_init_lut()
1298 if (!data->lut_base) in lpg_init_lut()
1301 lpg->lut_base = data->lut_base; in lpg_init_lut()
1302 lpg->lut_size = data->lut_size; in lpg_init_lut()
1304 lpg->lut_bitmap = devm_bitmap_zalloc(lpg->dev, lpg->lut_size, GFP_KERNEL); in lpg_init_lut()
1305 if (!lpg->lut_bitmap) in lpg_init_lut()
1306 return -ENOMEM; in lpg_init_lut()
1318 lpg = devm_kzalloc(&pdev->dev, sizeof(*lpg), GFP_KERNEL); in lpg_probe()
1320 return -ENOMEM; in lpg_probe()
1322 lpg->data = of_device_get_match_data(&pdev->dev); in lpg_probe()
1323 if (!lpg->data) in lpg_probe()
1324 return -EINVAL; in lpg_probe()
1326 lpg->dev = &pdev->dev; in lpg_probe()
1327 mutex_init(&lpg->lock); in lpg_probe()
1329 lpg->map = dev_get_regmap(pdev->dev.parent, NULL); in lpg_probe()
1330 if (!lpg->map) in lpg_probe()
1331 return dev_err_probe(&pdev->dev, -ENXIO, "parent regmap unavailable\n"); in lpg_probe()
1349 for_each_available_child_of_node(pdev->dev.of_node, np) { in lpg_probe()
1357 for (i = 0; i < lpg->num_channels; i++) in lpg_probe()
1358 lpg_apply_dtest(&lpg->channels[i]); in lpg_probe()
1505 { .compatible = "qcom,pm8150b-lpg", .data = &pm8150b_lpg_data },
1506 { .compatible = "qcom,pm8150l-lpg", .data = &pm8150l_lpg_data },
1507 { .compatible = "qcom,pm8350c-pwm", .data = &pm8350c_pwm_data },
1508 { .compatible = "qcom,pm8916-pwm", .data = &pm8916_pwm_data },
1509 { .compatible = "qcom,pm8941-lpg", .data = &pm8941_lpg_data },
1510 { .compatible = "qcom,pm8994-lpg", .data = &pm8994_lpg_data },
1511 { .compatible = "qcom,pmi632-lpg", .data = &pmi632_lpg_data },
1512 { .compatible = "qcom,pmi8994-lpg", .data = &pmi8994_lpg_data },
1513 { .compatible = "qcom,pmi8998-lpg", .data = &pmi8998_lpg_data },
1514 { .compatible = "qcom,pmc8180c-lpg", .data = &pm8150l_lpg_data },
1515 { .compatible = "qcom,pmk8550-pwm", .data = &pmk8550_pwm_data },
1523 .name = "qcom-spmi-lpg",