Lines Matching refs:lpg

69 struct lpg {  struct
120 struct lpg *lpg; member
163 struct lpg *lpg; member
202 static int triled_set(struct lpg *lpg, unsigned int mask, unsigned int enable) in triled_set() argument
205 if (!lpg->triled_base) in triled_set()
208 return regmap_update_bits(lpg->map, lpg->triled_base + TRI_LED_EN_CTL, in triled_set()
212 static int lpg_lut_store(struct lpg *lpg, struct led_pattern *pattern, in lpg_lut_store() argument
219 idx = bitmap_find_next_zero_area(lpg->lut_bitmap, lpg->lut_size, in lpg_lut_store()
221 if (idx >= lpg->lut_size) in lpg_lut_store()
227 regmap_bulk_write(lpg->map, lpg->lut_base + LPG_LUT_REG(idx + i), in lpg_lut_store()
231 bitmap_set(lpg->lut_bitmap, idx, len); in lpg_lut_store()
239 static void lpg_lut_free(struct lpg *lpg, unsigned int lo_idx, unsigned int hi_idx) in lpg_lut_free() argument
247 bitmap_clear(lpg->lut_bitmap, lo_idx, len); in lpg_lut_free()
250 static int lpg_lut_sync(struct lpg *lpg, unsigned int mask) in lpg_lut_sync() argument
252 return regmap_write(lpg->map, lpg->lut_base + RAMP_CONTROL_REG, mask); in lpg_lut_sync()
350 struct lpg *lpg = chan->lpg; in lpg_apply_freq() local
371 regmap_write(lpg->map, chan->base + LPG_SIZE_CLK_REG, val); in lpg_apply_freq()
375 regmap_write(lpg->map, chan->base + LPG_PREDIV_CLK_REG, val); in lpg_apply_freq()
382 struct lpg *lpg = chan->lpg; in lpg_enable_glitch() local
384 regmap_update_bits(lpg->map, chan->base + PWM_TYPE_CONFIG_REG, in lpg_enable_glitch()
390 struct lpg *lpg = chan->lpg; in lpg_disable_glitch() local
392 regmap_update_bits(lpg->map, chan->base + PWM_TYPE_CONFIG_REG, in lpg_disable_glitch()
399 struct lpg *lpg = chan->lpg; in lpg_apply_pwm_value() local
405 regmap_bulk_write(lpg->map, chan->base + PWM_VALUE_REG, &val, sizeof(val)); in lpg_apply_pwm_value()
416 struct lpg *lpg = chan->lpg; in lpg_apply_lut_control() local
441 regmap_write(lpg->map, chan->base + LPG_PATTERN_CONFIG_REG, conf); in lpg_apply_lut_control()
442 regmap_write(lpg->map, chan->base + LPG_HI_IDX_REG, hi_idx); in lpg_apply_lut_control()
443 regmap_write(lpg->map, chan->base + LPG_LO_IDX_REG, lo_idx); in lpg_apply_lut_control()
445 regmap_bulk_write(lpg->map, chan->base + LPG_RAMP_DURATION_REG, &step, sizeof(step)); in lpg_apply_lut_control()
446 regmap_write(lpg->map, chan->base + LPG_HI_PAUSE_REG, hi_pause); in lpg_apply_lut_control()
447 regmap_write(lpg->map, chan->base + LPG_LO_PAUSE_REG, lo_pause); in lpg_apply_lut_control()
458 struct lpg *lpg = chan->lpg; in lpg_apply_control() local
470 regmap_write(lpg->map, chan->base + PWM_ENABLE_CONTROL_REG, ctrl); in lpg_apply_control()
484 struct lpg *lpg = chan->lpg; in lpg_apply_sync() local
486 regmap_write(lpg->map, chan->base + PWM_SYNC_REG, LPG_SYNC_PWM); in lpg_apply_sync()
489 static int lpg_parse_dtest(struct lpg *lpg) in lpg_parse_dtest() argument
492 struct device_node *np = lpg->dev->of_node; in lpg_parse_dtest()
503 } else if (count != lpg->data->num_channels * 2) { in lpg_parse_dtest()
504 dev_err(lpg->dev, "qcom,dtest needs to be %d items\n", in lpg_parse_dtest()
505 lpg->data->num_channels * 2); in lpg_parse_dtest()
509 for (i = 0; i < lpg->data->num_channels; i++) { in lpg_parse_dtest()
510 chan = &lpg->channels[i]; in lpg_parse_dtest()
526 dev_err(lpg->dev, "malformed qcom,dtest\n"); in lpg_parse_dtest()
532 struct lpg *lpg = chan->lpg; in lpg_apply_dtest() local
537 regmap_write(lpg->map, chan->base + PWM_SEC_ACCESS_REG, 0xa5); in lpg_apply_dtest()
538 regmap_write(lpg->map, chan->base + PWM_DTEST_REG(chan->dtest_line), in lpg_apply_dtest()
562 struct lpg *lpg = led->lpg; in lpg_brightness_set() local
598 triled_set(lpg, triled_mask, triled_enabled); in lpg_brightness_set()
602 lpg_lut_sync(lpg, lut_mask); in lpg_brightness_set()
611 mutex_lock(&led->lpg->lock); in lpg_brightness_single_set()
616 mutex_unlock(&led->lpg->lock); in lpg_brightness_single_set()
627 mutex_lock(&led->lpg->lock); in lpg_brightness_mc_set()
632 mutex_unlock(&led->lpg->lock); in lpg_brightness_mc_set()
643 struct lpg *lpg = led->lpg; in lpg_blink_set() local
670 triled_set(lpg, triled_mask, triled_mask); in lpg_blink_set()
686 mutex_lock(&led->lpg->lock); in lpg_blink_single_set()
690 mutex_unlock(&led->lpg->lock); in lpg_blink_single_set()
702 mutex_lock(&led->lpg->lock); in lpg_blink_mc_set()
706 mutex_unlock(&led->lpg->lock); in lpg_blink_mc_set()
715 struct lpg *lpg = led->lpg; in lpg_pattern_set() local
831 mutex_lock(&lpg->lock); in lpg_pattern_set()
832 ret = lpg_lut_store(lpg, pattern, actual_len, &lo_idx, &hi_idx); in lpg_pattern_set()
851 mutex_unlock(&lpg->lock); in lpg_pattern_set()
895 struct lpg *lpg = led->lpg; in lpg_pattern_clear() local
898 mutex_lock(&lpg->lock); in lpg_pattern_clear()
901 lpg_lut_free(lpg, chan->pattern_lo_idx, chan->pattern_hi_idx); in lpg_pattern_clear()
909 mutex_unlock(&lpg->lock); in lpg_pattern_clear()
931 struct lpg *lpg = container_of(chip, struct lpg, pwm); in lpg_pwm_request() local
932 struct lpg_channel *chan = &lpg->channels[pwm->hwpwm]; in lpg_pwm_request()
947 struct lpg *lpg = container_of(chip, struct lpg, pwm); in lpg_pwm_apply() local
948 struct lpg_channel *chan = &lpg->channels[pwm->hwpwm]; in lpg_pwm_apply()
954 mutex_lock(&lpg->lock); in lpg_pwm_apply()
967 triled_set(lpg, chan->triled_mask, chan->enabled ? chan->triled_mask : 0); in lpg_pwm_apply()
970 mutex_unlock(&lpg->lock); in lpg_pwm_apply()
978 struct lpg *lpg = container_of(chip, struct lpg, pwm); in lpg_pwm_get_state() local
979 struct lpg_channel *chan = &lpg->channels[pwm->hwpwm]; in lpg_pwm_get_state()
987 ret = regmap_read(lpg->map, chan->base + LPG_SIZE_CLK_REG, &val); in lpg_pwm_get_state()
993 ret = regmap_read(lpg->map, chan->base + LPG_PREDIV_CLK_REG, &val); in lpg_pwm_get_state()
1000 ret = regmap_bulk_read(lpg->map, chan->base + PWM_VALUE_REG, &pwm_value, sizeof(pwm_value)); in lpg_pwm_get_state()
1011 ret = regmap_read(lpg->map, chan->base + PWM_ENABLE_CONTROL_REG, &val); in lpg_pwm_get_state()
1031 static int lpg_add_pwm(struct lpg *lpg) in lpg_add_pwm() argument
1035 lpg->pwm.base = -1; in lpg_add_pwm()
1036 lpg->pwm.dev = lpg->dev; in lpg_add_pwm()
1037 lpg->pwm.npwm = lpg->num_channels; in lpg_add_pwm()
1038 lpg->pwm.ops = &lpg_pwm_ops; in lpg_add_pwm()
1040 ret = pwmchip_add(&lpg->pwm); in lpg_add_pwm()
1042 dev_err(lpg->dev, "failed to add PWM chip: ret %d\n", ret); in lpg_add_pwm()
1047 static int lpg_parse_channel(struct lpg *lpg, struct device_node *np, in lpg_parse_channel() argument
1056 if (ret || !reg || reg > lpg->num_channels) { in lpg_parse_channel()
1057 dev_err(lpg->dev, "invalid \"reg\" of %pOFn\n", np); in lpg_parse_channel()
1061 chan = &lpg->channels[reg - 1]; in lpg_parse_channel()
1066 dev_err(lpg->dev, "failed to parse \"color\" of %pOF\n", np); in lpg_parse_channel()
1077 static int lpg_add_led(struct lpg *lpg, struct device_node *np) in lpg_add_led() argument
1092 dev_err(lpg->dev, "failed to parse \"color\" of %pOF\n", np); in lpg_add_led()
1101 led = devm_kzalloc(lpg->dev, struct_size(led, channels, num_channels), GFP_KERNEL); in lpg_add_led()
1105 led->lpg = lpg; in lpg_add_led()
1109 info = devm_kcalloc(lpg->dev, num_channels, sizeof(*info), GFP_KERNEL); in lpg_add_led()
1114 ret = lpg_parse_channel(lpg, child, &led->channels[i]); in lpg_add_led()
1131 if (lpg->lut_base) { in lpg_add_led()
1136 ret = lpg_parse_channel(lpg, np, &led->channels[0]); in lpg_add_led()
1145 if (lpg->lut_base) { in lpg_add_led()
1165 ret = devm_led_classdev_multicolor_register_ext(lpg->dev, &led->mcdev, &init_data); in lpg_add_led()
1167 ret = devm_led_classdev_register_ext(lpg->dev, &led->cdev, &init_data); in lpg_add_led()
1169 dev_err(lpg->dev, "unable to register %s\n", cdev->name); in lpg_add_led()
1174 static int lpg_init_channels(struct lpg *lpg) in lpg_init_channels() argument
1176 const struct lpg_data *data = lpg->data; in lpg_init_channels()
1180 lpg->num_channels = data->num_channels; in lpg_init_channels()
1181 lpg->channels = devm_kcalloc(lpg->dev, data->num_channels, in lpg_init_channels()
1183 if (!lpg->channels) in lpg_init_channels()
1187 chan = &lpg->channels[i]; in lpg_init_channels()
1189 chan->lpg = lpg; in lpg_init_channels()
1194 regmap_read(lpg->map, chan->base + LPG_SUBTYPE_REG, &chan->subtype); in lpg_init_channels()
1200 static int lpg_init_triled(struct lpg *lpg) in lpg_init_triled() argument
1202 struct device_node *np = lpg->dev->of_node; in lpg_init_triled()
1206 if (!lpg->data->triled_base) in lpg_init_triled()
1209 lpg->triled_base = lpg->data->triled_base; in lpg_init_triled()
1210 lpg->triled_has_atc_ctl = lpg->data->triled_has_atc_ctl; in lpg_init_triled()
1211 lpg->triled_has_src_sel = lpg->data->triled_has_src_sel; in lpg_init_triled()
1213 if (lpg->triled_has_src_sel) { in lpg_init_triled()
1214 ret = of_property_read_u32(np, "qcom,power-source", &lpg->triled_src); in lpg_init_triled()
1215 if (ret || lpg->triled_src == 2 || lpg->triled_src > 3) { in lpg_init_triled()
1216 dev_err(lpg->dev, "invalid power source\n"); in lpg_init_triled()
1222 if (lpg->triled_has_atc_ctl) in lpg_init_triled()
1223 regmap_write(lpg->map, lpg->triled_base + TRI_LED_ATC_CTL, 0); in lpg_init_triled()
1226 if (lpg->triled_has_src_sel) in lpg_init_triled()
1227 regmap_write(lpg->map, lpg->triled_base + TRI_LED_SRC_SEL, lpg->triled_src); in lpg_init_triled()
1230 regmap_write(lpg->map, lpg->triled_base + TRI_LED_EN_CTL, 0); in lpg_init_triled()
1235 static int lpg_init_lut(struct lpg *lpg) in lpg_init_lut() argument
1237 const struct lpg_data *data = lpg->data; in lpg_init_lut()
1242 lpg->lut_base = data->lut_base; in lpg_init_lut()
1243 lpg->lut_size = data->lut_size; in lpg_init_lut()
1245 lpg->lut_bitmap = devm_bitmap_zalloc(lpg->dev, lpg->lut_size, GFP_KERNEL); in lpg_init_lut()
1246 if (!lpg->lut_bitmap) in lpg_init_lut()
1255 struct lpg *lpg; in lpg_probe() local
1259 lpg = devm_kzalloc(&pdev->dev, sizeof(*lpg), GFP_KERNEL); in lpg_probe()
1260 if (!lpg) in lpg_probe()
1263 lpg->data = of_device_get_match_data(&pdev->dev); in lpg_probe()
1264 if (!lpg->data) in lpg_probe()
1267 platform_set_drvdata(pdev, lpg); in lpg_probe()
1269 lpg->dev = &pdev->dev; in lpg_probe()
1270 mutex_init(&lpg->lock); in lpg_probe()
1272 lpg->map = dev_get_regmap(pdev->dev.parent, NULL); in lpg_probe()
1273 if (!lpg->map) in lpg_probe()
1276 ret = lpg_init_channels(lpg); in lpg_probe()
1280 ret = lpg_parse_dtest(lpg); in lpg_probe()
1284 ret = lpg_init_triled(lpg); in lpg_probe()
1288 ret = lpg_init_lut(lpg); in lpg_probe()
1293 ret = lpg_add_led(lpg, np); in lpg_probe()
1298 for (i = 0; i < lpg->num_channels; i++) in lpg_probe()
1299 lpg_apply_dtest(&lpg->channels[i]); in lpg_probe()
1301 return lpg_add_pwm(lpg); in lpg_probe()
1306 struct lpg *lpg = platform_get_drvdata(pdev); in lpg_remove() local
1308 pwmchip_remove(&lpg->pwm); in lpg_remove()