Lines Matching +full:lgm +full:- +full:clk
1 // SPDX-License-Identifier: GPL-2.0
9 #include <linux/clk.h>
23 #define SSO_DEV_NAME "lgm-sso"
55 #define DATA_CLK_EDGE 0 /* 0-rising, 1-falling */
63 * SW - Software has to update the SWU bit
64 * GPTC - General Purpose timer is used as clock source
65 * FPID - Divided FSC clock (FPID) is used as clock source
149 if (rate <= priv->freq[i]) in sso_get_blink_rate_idx()
153 return -1; in sso_get_blink_rate_idx()
179 return pin - LED_GRP1_PIN_MAX; in sso_led_pin_blink_off()
181 return pin - LED_GRP0_PIN_MAX; in sso_led_pin_blink_off()
182 else /* led 0 - 23 in led 32 location */ in sso_led_pin_blink_off()
183 return SSO_LED_MAX_NUM - LED_GRP1_PIN_MAX; in sso_led_pin_blink_off()
213 val_freq = freq_idx - 1; in sso_led_freq_set()
215 val_freq = freq_idx - MAX_FPID_FREQ_RANK; in sso_led_freq_set()
222 regmap_update_bits(priv->mmap, reg, GENMASK(high, low), val); in sso_led_freq_set()
229 regmap_update_bits(priv->mmap, reg, GENMASK(high, low), val); in sso_led_freq_set()
241 priv = led->priv; in sso_led_brightness_set()
242 desc = &led->desc; in sso_led_brightness_set()
244 desc->brightness = brightness; in sso_led_brightness_set()
245 regmap_write(priv->mmap, DUTY_CYCLE(desc->pin), brightness); in sso_led_brightness_set()
253 if (desc->hw_blink && !val && desc->blinking) { in sso_led_brightness_set()
254 desc->blinking = 0; in sso_led_brightness_set()
255 regmap_update_bits(priv->mmap, SSO_CON2, BIT(desc->pin), 0); in sso_led_brightness_set()
256 } else if (desc->hw_blink && val && !desc->blinking) { in sso_led_brightness_set()
257 desc->blinking = 1; in sso_led_brightness_set()
258 regmap_update_bits(priv->mmap, SSO_CON2, BIT(desc->pin), in sso_led_brightness_set()
259 1 << desc->pin); in sso_led_brightness_set()
262 if (!desc->hw_trig) in sso_led_brightness_set()
263 gpiod_set_value(led->gpiod, val); in sso_led_brightness_set()
270 return (enum led_brightness)led->desc.brightness; in sso_led_brightness_get()
277 struct sso_led_priv *priv = led->priv; in delay_to_freq_idx()
283 *delay_on = *delay_off = (1000 / priv->freq[0]) / 2; in delay_to_freq_idx()
291 if (freq_idx == -1) in delay_to_freq_idx()
292 freq_idx = MAX_FREQ_RANK - 1; in delay_to_freq_idx()
294 delay = 1000 / priv->freq[freq_idx]; in delay_to_freq_idx()
312 priv = led->priv; in sso_led_blink_set()
315 sso_led_freq_set(priv, led->desc.pin, freq_idx); in sso_led_blink_set()
316 regmap_update_bits(priv->mmap, SSO_CON2, BIT(led->desc.pin), in sso_led_blink_set()
317 1 << led->desc.pin); in sso_led_blink_set()
318 led->desc.freq_idx = freq_idx; in sso_led_blink_set()
319 led->desc.blink_rate = priv->freq[freq_idx]; in sso_led_blink_set()
320 led->desc.blinking = 1; in sso_led_blink_set()
327 struct sso_led_desc *desc = &led->desc; in sso_led_hw_cfg()
330 if (desc->hw_blink) { in sso_led_hw_cfg()
331 sso_led_freq_set(priv, desc->pin, desc->freq_idx); in sso_led_hw_cfg()
332 regmap_update_bits(priv->mmap, SSO_CON2, BIT(desc->pin), in sso_led_hw_cfg()
333 1 << desc->pin); in sso_led_hw_cfg()
336 if (desc->hw_trig) in sso_led_hw_cfg()
337 regmap_update_bits(priv->mmap, SSO_CON3, BIT(desc->pin), in sso_led_hw_cfg()
338 1 << desc->pin); in sso_led_hw_cfg()
341 regmap_write(priv->mmap, DUTY_CYCLE(desc->pin), desc->brightness); in sso_led_hw_cfg()
344 if (!desc->hw_trig && desc->brightness) in sso_led_hw_cfg()
345 gpiod_set_value(led->gpiod, 1); in sso_led_hw_cfg()
351 struct sso_led_desc *desc = &led->desc; in sso_create_led()
359 led->cdev.default_trigger = desc->default_trigger; in sso_create_led()
360 led->cdev.brightness_set = sso_led_brightness_set; in sso_create_led()
361 led->cdev.brightness_get = sso_led_brightness_get; in sso_create_led()
362 led->cdev.brightness = desc->brightness; in sso_create_led()
363 led->cdev.max_brightness = LED_FULL; in sso_create_led()
365 if (desc->retain_state_shutdown) in sso_create_led()
366 led->cdev.flags |= LED_RETAIN_AT_SHUTDOWN; in sso_create_led()
367 if (desc->retain_state_suspended) in sso_create_led()
368 led->cdev.flags |= LED_CORE_SUSPENDRESUME; in sso_create_led()
369 if (desc->panic_indicator) in sso_create_led()
370 led->cdev.flags |= LED_PANIC_INDICATOR; in sso_create_led()
372 if (desc->hw_blink) in sso_create_led()
373 led->cdev.blink_set = sso_led_blink_set; in sso_create_led()
377 err = devm_led_classdev_register_ext(priv->dev, &led->cdev, &init_data); in sso_create_led()
381 list_add(&led->list, &priv->led_list); in sso_create_led()
390 priv->freq[0] = 0; in sso_init_freq()
393 priv->freq[i] = priv->fpid_clkrate / freq_div_tbl[i - 1]; in sso_init_freq()
395 priv->freq[i] = priv->gptc_clkrate / in sso_init_freq()
396 freq_div_tbl[i - MAX_FPID_FREQ_RANK]; in sso_init_freq()
398 priv->freq[i] = priv->gptc_clkrate; in sso_init_freq()
407 if (priv->gpio.alloc_bitmap & BIT(offset)) in sso_gpio_request()
408 return -EINVAL; in sso_gpio_request()
410 priv->gpio.alloc_bitmap |= BIT(offset); in sso_gpio_request()
411 regmap_write(priv->mmap, DUTY_CYCLE(offset), 0xFF); in sso_gpio_request()
420 priv->gpio.alloc_bitmap &= ~BIT(offset); in sso_gpio_free()
421 regmap_write(priv->mmap, DUTY_CYCLE(offset), 0x0); in sso_gpio_free()
435 regmap_update_bits(priv->mmap, SSO_CPU, BIT(offset), bit << offset); in sso_gpio_dir_out()
436 if (!priv->gpio.freq) in sso_gpio_dir_out()
437 regmap_update_bits(priv->mmap, SSO_CON0, SSO_CON0_SWU, in sso_gpio_dir_out()
448 regmap_read(priv->mmap, SSO_CPU, ®_val); in sso_gpio_get()
457 regmap_update_bits(priv->mmap, SSO_CPU, BIT(offset), value << offset); in sso_gpio_set()
458 if (!priv->gpio.freq) in sso_gpio_set()
459 regmap_update_bits(priv->mmap, SSO_CON0, SSO_CON0_SWU, in sso_gpio_set()
465 struct gpio_chip *gc = &priv->gpio.chip; in sso_gpio_gc_init()
467 gc->request = sso_gpio_request; in sso_gpio_gc_init()
468 gc->free = sso_gpio_free; in sso_gpio_gc_init()
469 gc->get_direction = sso_gpio_get_dir; in sso_gpio_gc_init()
470 gc->direction_output = sso_gpio_dir_out; in sso_gpio_gc_init()
471 gc->get = sso_gpio_get; in sso_gpio_gc_init()
472 gc->set = sso_gpio_set; in sso_gpio_gc_init()
474 gc->label = "lgm-sso"; in sso_gpio_gc_init()
475 gc->base = -1; in sso_gpio_gc_init()
476 /* To exclude pins from control, use "gpio-reserved-ranges" */ in sso_gpio_gc_init()
477 gc->ngpio = priv->gpio.pins; in sso_gpio_gc_init()
478 gc->parent = dev; in sso_gpio_gc_init()
479 gc->owner = THIS_MODULE; in sso_gpio_gc_init()
493 return -1; in sso_gpio_get_freq_idx()
502 if (shift_clk_freq_tbl[idx] <= priv->gpio.shift_clk_freq) { in sso_register_shift_clk()
509 dev_warn(priv->dev, "%s: Invalid freq %d\n", in sso_register_shift_clk()
510 __func__, priv->gpio.shift_clk_freq); in sso_register_shift_clk()
512 regmap_update_bits(priv->mmap, SSO_CON1, SSO_CON1_FCDSC, in sso_register_shift_clk()
521 freq_idx = sso_gpio_get_freq_idx(priv->gpio.freq); in sso_gpio_freq_set()
522 if (freq_idx == -1) in sso_gpio_freq_set()
523 freq_idx = ARRAY_SIZE(freq_tbl) - 1; in sso_gpio_freq_set()
527 if (!priv->gpio.freq) { in sso_gpio_freq_set()
528 regmap_update_bits(priv->mmap, SSO_CON0, SSO_CON0_BLINK_R, 0); in sso_gpio_freq_set()
529 regmap_update_bits(priv->mmap, SSO_CON1, SSO_CON1_US, in sso_gpio_freq_set()
532 regmap_update_bits(priv->mmap, SSO_CON0, SSO_CON0_BLINK_R, in sso_gpio_freq_set()
534 regmap_update_bits(priv->mmap, SSO_CON1, SSO_CON1_US, in sso_gpio_freq_set()
536 regmap_update_bits(priv->mmap, SSO_CON1, SSO_CON1_FPID, in sso_gpio_freq_set()
539 regmap_update_bits(priv->mmap, SSO_CON0, SSO_CON0_BLINK_R, in sso_gpio_freq_set()
541 regmap_update_bits(priv->mmap, SSO_CON1, SSO_CON1_US, in sso_gpio_freq_set()
543 regmap_update_bits(priv->mmap, SSO_CON1, SSO_CON1_GPTD, in sso_gpio_freq_set()
556 for (i = 0; i < priv->gpio.pins; i++) { in sso_gpio_hw_init()
557 err = regmap_write(priv->mmap, DUTY_CYCLE(i), 0); in sso_gpio_hw_init()
564 activate = !!(i * PINS_PER_GROUP <= priv->gpio.pins || in sso_gpio_hw_init()
565 priv->gpio.pins > (i - 1) * PINS_PER_GROUP); in sso_gpio_hw_init()
566 err = regmap_update_bits(priv->mmap, SSO_CON1, BIT(i - 1), in sso_gpio_hw_init()
567 activate << (i - 1)); in sso_gpio_hw_init()
573 err = regmap_write(priv->mmap, SSO_CON3, 0); in sso_gpio_hw_init()
578 err = regmap_write(priv->mmap, SSO_CON2, 0); in sso_gpio_hw_init()
583 err = regmap_write(priv->mmap, SSO_CPU, 0); in sso_gpio_hw_init()
588 err = regmap_update_bits(priv->mmap, SSO_CON0, SSO_CON0_RZFL, in sso_gpio_hw_init()
589 FIELD_PREP(SSO_CON0_RZFL, priv->gpio.edge)); in sso_gpio_hw_init()
604 struct sso_led_priv *priv = led->priv; in sso_led_shutdown()
607 devm_led_classdev_unregister(priv->dev, &led->cdev); in sso_led_shutdown()
610 if (led->desc.hw_trig) in sso_led_shutdown()
611 regmap_update_bits(priv->mmap, SSO_CON3, BIT(led->desc.pin), 0); in sso_led_shutdown()
613 led->priv = NULL; in sso_led_shutdown()
620 struct device *dev = priv->dev; in __sso_led_dt_parse()
630 ret = -ENOMEM; in __sso_led_dt_parse()
634 INIT_LIST_HEAD(&led->list); in __sso_led_dt_parse()
635 led->priv = priv; in __sso_led_dt_parse()
636 desc = &led->desc; in __sso_led_dt_parse()
638 led->gpiod = devm_fwnode_gpiod_get(dev, fwnode_child, NULL, in __sso_led_dt_parse()
640 if (IS_ERR(led->gpiod)) { in __sso_led_dt_parse()
641 ret = dev_err_probe(dev, PTR_ERR(led->gpiod), "led: get gpio fail!\n"); in __sso_led_dt_parse()
646 "linux,default-trigger", in __sso_led_dt_parse()
647 &desc->default_trigger); in __sso_led_dt_parse()
650 "retain-state-suspended")) in __sso_led_dt_parse()
651 desc->retain_state_suspended = 1; in __sso_led_dt_parse()
654 "retain-state-shutdown")) in __sso_led_dt_parse()
655 desc->retain_state_shutdown = 1; in __sso_led_dt_parse()
657 if (fwnode_property_present(fwnode_child, "panic-indicator")) in __sso_led_dt_parse()
658 desc->panic_indicator = 1; in __sso_led_dt_parse()
665 ret = -EINVAL; in __sso_led_dt_parse()
668 desc->pin = prop; in __sso_led_dt_parse()
670 if (fwnode_property_present(fwnode_child, "intel,sso-hw-blink")) in __sso_led_dt_parse()
671 desc->hw_blink = 1; in __sso_led_dt_parse()
673 desc->hw_trig = fwnode_property_read_bool(fwnode_child, in __sso_led_dt_parse()
674 "intel,sso-hw-trigger"); in __sso_led_dt_parse()
675 if (desc->hw_trig) { in __sso_led_dt_parse()
676 desc->default_trigger = NULL; in __sso_led_dt_parse()
677 desc->retain_state_shutdown = 0; in __sso_led_dt_parse()
678 desc->retain_state_suspended = 0; in __sso_led_dt_parse()
679 desc->panic_indicator = 0; in __sso_led_dt_parse()
680 desc->hw_blink = 0; in __sso_led_dt_parse()
684 "intel,sso-blink-rate-hz", &prop)) { in __sso_led_dt_parse()
686 desc->freq_idx = 0; in __sso_led_dt_parse()
687 desc->blink_rate = priv->freq[desc->freq_idx]; in __sso_led_dt_parse()
689 desc->freq_idx = sso_get_blink_rate_idx(priv, prop); in __sso_led_dt_parse()
690 if (desc->freq_idx == -1) in __sso_led_dt_parse()
691 desc->freq_idx = MAX_FREQ_RANK - 1; in __sso_led_dt_parse()
693 desc->blink_rate = priv->freq[desc->freq_idx]; in __sso_led_dt_parse()
696 if (!fwnode_property_read_string(fwnode_child, "default-state", &tmp)) { in __sso_led_dt_parse()
698 desc->brightness = LED_FULL; in __sso_led_dt_parse()
711 list_for_each_entry(led, &priv->led_list, list) in __sso_led_dt_parse()
719 struct fwnode_handle *fwnode = dev_fwnode(priv->dev); in sso_led_dt_parse()
721 struct device *dev = priv->dev; in sso_led_dt_parse()
742 struct device *dev = priv->dev; in sso_probe_gpios()
745 if (device_property_read_u32(dev, "ngpios", &priv->gpio.pins)) in sso_probe_gpios()
746 priv->gpio.pins = MAX_PIN_NUM_PER_BANK; in sso_probe_gpios()
748 if (priv->gpio.pins > MAX_PIN_NUM_PER_BANK) in sso_probe_gpios()
749 return -EINVAL; in sso_probe_gpios()
751 if (device_property_read_u32(dev, "intel,sso-update-rate-hz", in sso_probe_gpios()
752 &priv->gpio.freq)) in sso_probe_gpios()
753 priv->gpio.freq = 0; in sso_probe_gpios()
755 priv->gpio.edge = DATA_CLK_EDGE; in sso_probe_gpios()
756 priv->gpio.shift_clk_freq = -1; in sso_probe_gpios()
769 clk_bulk_disable_unprepare(ARRAY_SIZE(priv->clocks), priv->clocks); in sso_clock_disable_unprepare()
774 struct device *dev = &pdev->dev; in intel_sso_led_probe()
780 return -ENOMEM; in intel_sso_led_probe()
782 priv->pdev = pdev; in intel_sso_led_probe()
783 priv->dev = dev; in intel_sso_led_probe()
786 priv->clocks[0].id = "sso"; in intel_sso_led_probe()
789 priv->clocks[1].id = "fpid"; in intel_sso_led_probe()
791 ret = devm_clk_bulk_get(dev, ARRAY_SIZE(priv->clocks), priv->clocks); in intel_sso_led_probe()
797 ret = clk_bulk_prepare_enable(ARRAY_SIZE(priv->clocks), priv->clocks); in intel_sso_led_probe()
807 priv->fpid_clkrate = clk_get_rate(priv->clocks[1].clk); in intel_sso_led_probe()
809 priv->mmap = syscon_node_to_regmap(dev->of_node); in intel_sso_led_probe()
811 priv->mmap = syscon_node_to_regmap(dev->of_node); in intel_sso_led_probe()
812 if (IS_ERR(priv->mmap)) { in intel_sso_led_probe()
814 return PTR_ERR(priv->mmap); in intel_sso_led_probe()
819 regmap_exit(priv->mmap); in intel_sso_led_probe()
823 INIT_LIST_HEAD(&priv->led_list); in intel_sso_led_probe()
828 priv->gptc_clkrate = DEF_GPTC_CLK_RATE; in intel_sso_led_probe()
832 regmap_exit(priv->mmap); in intel_sso_led_probe()
835 dev_info(priv->dev, "sso LED init success!\n"); in intel_sso_led_probe()
847 list_for_each_entry_safe(led, n, &priv->led_list, list) { in intel_sso_led_remove()
848 list_del(&led->list); in intel_sso_led_remove()
852 regmap_exit(priv->mmap); in intel_sso_led_remove()
856 { .compatible = "intel,lgm-ssoled" },
866 .name = "lgm-ssoled",