Lines Matching +full:regulator +full:- +full:fixed +full:- +full:domain

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
45 * voltage-regulators = "name1", "millivolts1",
48 * Each override should be a pair, the first entry is the name of the regulator
49 * the second is the voltage (in millivolts) to set for the given regulator.
89 * Register offsets within a LDO regulator register set
91 #define TWL_VREG_GRP 0x00 /* Regulator GRP register */
216 uint8_t sub_dev; /* TWL sub-device group */
218 uint16_t fixed_voltage; /* the (milli)voltage if LDO is fixed */
232 #define TWL_VREG_XLOCK(_sc) sx_xlock(&(_sc)->sc_sx)
233 #define TWL_VREG_XUNLOCK(_sc) sx_xunlock(&(_sc)->sc_sx)
234 #define TWL_VREG_SLOCK(_sc) sx_slock(&(_sc)->sc_sx)
235 #define TWL_VREG_SUNLOCK(_sc) sx_sunlock(&(_sc)->sc_sx)
236 #define TWL_VREG_LOCK_INIT(_sc) sx_init(&(_sc)->sc_sx, "twl_vreg")
237 #define TWL_VREG_LOCK_DESTROY(_sc) sx_destroy(&(_sc)->sc_sx);
239 #define TWL_VREG_ASSERT_LOCKED(_sc) sx_assert(&(_sc)->sc_sx, SA_LOCKED);
243 while (!sx_try_upgrade(&(_sc)->sc_sx)) \
246 #define TWL_VREG_LOCK_DOWNGRADE(_sc) sx_downgrade(&(_sc)->sc_sx);
249 * twl_vreg_read_1 - read single register from the TWL device
250 * twl_vreg_write_1 - write a single register in the TWL device
260 twl_vreg_read_1(struct twl_vreg_softc *sc, struct twl_regulator_entry *regulator, in twl_vreg_read_1() argument
263 return (twl_read(sc->sc_pdev, regulator->sub_dev, in twl_vreg_read_1()
264 regulator->reg_off + off, val, 1)); in twl_vreg_read_1()
268 twl_vreg_write_1(struct twl_vreg_softc *sc, struct twl_regulator_entry *regulator, in twl_vreg_write_1() argument
271 return (twl_write(sc->sc_pdev, regulator->sub_dev, in twl_vreg_write_1()
272 regulator->reg_off + off, &val, 1)); in twl_vreg_write_1()
276 * twl_millivolt_to_vsel - gets the vsel bit value to write into the register
277 * for a desired voltage and regulator
279 * @regulator: pointer to the regulator device
284 * actual supported voltages for the given regulator. If a match is found
286 * returned. If no voltage match is found the function returns an non-zero
294 struct twl_regulator_entry *regulator, int millivolts, uint8_t *vsel) in twl_vreg_millivolt_to_vsel() argument
301 if (regulator->supp_voltages == NULL) in twl_vreg_millivolt_to_vsel()
307 for (i = 0; i < regulator->num_supp_voltages; i++) { in twl_vreg_millivolt_to_vsel()
309 if (regulator->supp_voltages[i] == UNDF) in twl_vreg_millivolt_to_vsel()
313 delta = millivolts - (int)regulator->supp_voltages[i]; in twl_vreg_millivolt_to_vsel()
331 * twl_vreg_is_regulator_enabled - returns the enabled status of the regulator
333 * @regulator: pointer to the regulator device
334 * @enabled: stores the enabled status, zero disabled, non-zero enabled
346 struct twl_regulator_entry *regulator, int *enabled) in twl_vreg_is_regulator_enabled() argument
358 xlocked = sx_xlocked(&sc->sc_sx); in twl_vreg_is_regulator_enabled()
363 if (twl_is_4030(sc->sc_pdev)) { in twl_vreg_is_regulator_enabled()
364 err = twl_vreg_read_1(sc, regulator, TWL_VREG_GRP, &state); in twl_vreg_is_regulator_enabled()
370 } else if (twl_is_6030(sc->sc_pdev) || twl_is_6025(sc->sc_pdev)) { in twl_vreg_is_regulator_enabled()
371 /* Check the regulator is in the application group */ in twl_vreg_is_regulator_enabled()
372 if (twl_is_6030(sc->sc_pdev)) { in twl_vreg_is_regulator_enabled()
373 err = twl_vreg_read_1(sc, regulator, TWL_VREG_GRP, &grp); in twl_vreg_is_regulator_enabled()
384 err = twl_vreg_read_1(sc, regulator, TWL_VREG_STATE, &state); in twl_vreg_is_regulator_enabled()
402 * twl_vreg_disable_regulator - disables a voltage regulator
404 * @regulator: pointer to the regulator device
406 * Disables the regulator which will stop the output drivers.
418 struct twl_regulator_entry *regulator) in twl_vreg_disable_regulator() argument
426 xlocked = sx_xlocked(&sc->sc_sx); in twl_vreg_disable_regulator()
430 if (twl_is_4030(sc->sc_pdev)) { in twl_vreg_disable_regulator()
431 /* Read the regulator CFG_GRP register */ in twl_vreg_disable_regulator()
432 err = twl_vreg_read_1(sc, regulator, TWL_VREG_GRP, &grp); in twl_vreg_disable_regulator()
436 /* On the TWL4030 we just need to remove the regulator from all the in twl_vreg_disable_regulator()
440 err = twl_vreg_write_1(sc, regulator, TWL_VREG_GRP, grp); in twl_vreg_disable_regulator()
442 } else if (twl_is_6030(sc->sc_pdev) || twl_is_6025(sc->sc_pdev)) { in twl_vreg_disable_regulator()
444 if (twl_is_6030(sc->sc_pdev)) in twl_vreg_disable_regulator()
450 err = twl_vreg_write_1(sc, regulator, TWL_VREG_STATE, (grp << 5)); in twl_vreg_disable_regulator()
461 * twl_vreg_enable_regulator - enables the voltage regulator
463 * @regulator: pointer to the regulator device
465 * Enables the regulator which will enable the voltage out at the currently
479 struct twl_regulator_entry *regulator) in twl_vreg_enable_regulator() argument
487 xlocked = sx_xlocked(&sc->sc_sx); in twl_vreg_enable_regulator()
491 err = twl_vreg_read_1(sc, regulator, TWL_VREG_GRP, &grp); in twl_vreg_enable_regulator()
495 /* Enable the regulator by ensuring it's in the application power group in twl_vreg_enable_regulator()
498 if (twl_is_4030(sc->sc_pdev)) { in twl_vreg_enable_regulator()
499 /* On the TWL4030 we just need to ensure the regulator is in the right in twl_vreg_enable_regulator()
500 * power domain, don't need to turn on explicitly like TWL6030. in twl_vreg_enable_regulator()
503 err = twl_vreg_write_1(sc, regulator, TWL_VREG_GRP, grp); in twl_vreg_enable_regulator()
505 } else if (twl_is_6030(sc->sc_pdev) || twl_is_6025(sc->sc_pdev)) { in twl_vreg_enable_regulator()
506 if (twl_is_6030(sc->sc_pdev) && !(grp & TWL6030_P1_GRP)) { in twl_vreg_enable_regulator()
508 err = twl_vreg_write_1(sc, regulator, TWL_VREG_GRP, grp); in twl_vreg_enable_regulator()
514 err = twl_vreg_write_1(sc, regulator, TWL_VREG_STATE, (grp << 5) | 0x01); in twl_vreg_enable_regulator()
525 * twl_vreg_write_regulator_voltage - sets the voltage level on a regulator
527 * @regulator: pointer to the regulator structure
530 * Sets the voltage output on a given regulator, if the regulator is not
542 struct twl_regulator_entry *regulator, int millivolts) in twl_vreg_write_regulator_voltage() argument
552 return (twl_vreg_disable_regulator(sc, regulator)); in twl_vreg_write_regulator_voltage()
554 /* If the regulator has a fixed voltage then check the setting matches in twl_vreg_write_regulator_voltage()
557 if (regulator->supp_voltages == NULL || regulator->num_supp_voltages == 0) { in twl_vreg_write_regulator_voltage()
558 if (millivolts != regulator->fixed_voltage) in twl_vreg_write_regulator_voltage()
561 return (twl_vreg_enable_regulator(sc, regulator)); in twl_vreg_write_regulator_voltage()
565 err = twl_vreg_millivolt_to_vsel(sc, regulator, millivolts, &vsel); in twl_vreg_write_regulator_voltage()
570 xlocked = sx_xlocked(&sc->sc_sx); in twl_vreg_write_regulator_voltage()
575 err = twl_vreg_write_1(sc, regulator, TWL_VREG_VSEL, (vsel & 0x1f)); in twl_vreg_write_regulator_voltage()
577 err = twl_vreg_enable_regulator(sc, regulator); in twl_vreg_write_regulator_voltage()
584 device_printf(sc->sc_dev, "%s : setting voltage to %dmV (vsel: 0x%x)\n", in twl_vreg_write_regulator_voltage()
585 regulator->name, millivolts, vsel); in twl_vreg_write_regulator_voltage()
591 * twl_vreg_read_regulator_voltage - reads the voltage on a given regulator
593 * @regulator: pointer to the regulator structure
594 * @millivolts: upon return will contain the voltage on the regulator
606 struct twl_regulator_entry *regulator, int *millivolts) in twl_vreg_read_regulator_voltage() argument
618 xlocked = sx_xlocked(&sc->sc_sx); in twl_vreg_read_regulator_voltage()
622 /* Check if the regulator is currently enabled */ in twl_vreg_read_regulator_voltage()
623 err = twl_vreg_is_regulator_enabled(sc, regulator, &en); in twl_vreg_read_regulator_voltage()
632 if (regulator->supp_voltages == NULL || !regulator->num_supp_voltages) { in twl_vreg_read_regulator_voltage()
633 *millivolts = regulator->fixed_voltage; in twl_vreg_read_regulator_voltage()
638 err = twl_vreg_read_1(sc, regulator, TWL_VREG_VSEL, &vsel); in twl_vreg_read_regulator_voltage()
642 vsel &= (regulator->num_supp_voltages - 1); in twl_vreg_read_regulator_voltage()
643 if (regulator->supp_voltages[vsel] == UNDF) { in twl_vreg_read_regulator_voltage()
648 *millivolts = regulator->supp_voltages[vsel]; in twl_vreg_read_regulator_voltage()
655 device_printf(sc->sc_dev, "%s : reading voltage is %dmV (vsel: 0x%x)\n", in twl_vreg_read_regulator_voltage()
656 regulator->name, *millivolts, vsel); in twl_vreg_read_regulator_voltage()
662 * twl_vreg_get_voltage - public interface to read the voltage on a regulator
664 * @name: the name of the regulator to read the voltage of
667 * If the regulator is disabled the function will set the @millivolts to zero.
679 struct twl_regulator_entry *regulator; in twl_vreg_get_voltage() local
689 LIST_FOREACH(regulator, &sc->sc_vreg_list, entries) { in twl_vreg_get_voltage()
690 if (strcmp(regulator->name, name) == 0) { in twl_vreg_get_voltage()
691 err = twl_vreg_read_regulator_voltage(sc, regulator, millivolts); in twl_vreg_get_voltage()
702 * twl_vreg_set_voltage - public interface to write the voltage on a regulator
704 * @name: the name of the regulator to read the voltage of
707 * Sets the output voltage on a given regulator. If the regulator is a fixed
708 * voltage reg then the @millivolts value should match the fixed voltage. If
709 * a variable regulator then the @millivolt value must fit within the max/min
710 * range of the given regulator.
722 struct twl_regulator_entry *regulator; in twl_vreg_set_voltage() local
729 LIST_FOREACH(regulator, &sc->sc_vreg_list, entries) { in twl_vreg_set_voltage()
730 if (strcmp(regulator->name, name) == 0) { in twl_vreg_set_voltage()
731 err = twl_vreg_write_regulator_voltage(sc, regulator, millivolts); in twl_vreg_set_voltage()
742 * twl_sysctl_voltage - reads or writes the voltage for a regulator
745 * Callback for the sysctl entry for the regulator, simply used to return
746 * the voltage on a particular regulator.
758 struct twl_regulator_entry *regulator; in twl_vreg_sysctl_voltage() local
764 /* Find the regulator with the matching name */ in twl_vreg_sysctl_voltage()
765 LIST_FOREACH(regulator, &sc->sc_vreg_list, entries) { in twl_vreg_sysctl_voltage()
766 if (strcmp(regulator->name, oidp->oid_name) == 0) { in twl_vreg_sysctl_voltage()
772 /* Sanity check that we found the regulator */ in twl_vreg_sysctl_voltage()
778 twl_vreg_read_regulator_voltage(sc, regulator, &voltage); in twl_vreg_sysctl_voltage()
786 * twl_add_regulator - adds single voltage regulator sysctls for the device
788 * @name: the name of the regulator
790 * @regbase: the base address of the voltage regulator registers
791 * @fixed_voltage: if a fixed voltage regulator this defines it's voltage
792 * @voltages: if a variable voltage regulator, an array of possible voltages
795 * Adds a voltage regulator to the device and also a sysctl interface for the
796 * regulator.
802 * Pointer to the new regulator entry on success, otherwise on failure NULL.
809 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev); in twl_vreg_add_regulator()
810 struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev); in twl_vreg_add_regulator()
817 strncpy(new->name, name, TWL_VREG_MAX_NAMELEN); in twl_vreg_add_regulator()
818 new->name[TWL_VREG_MAX_NAMELEN - 1] = '\0'; in twl_vreg_add_regulator()
820 new->sub_dev = nsub; in twl_vreg_add_regulator()
821 new->reg_off = regbase; in twl_vreg_add_regulator()
823 new->fixed_voltage = fixed_voltage; in twl_vreg_add_regulator()
825 new->supp_voltages = voltages; in twl_vreg_add_regulator()
826 new->num_supp_voltages = num_voltages; in twl_vreg_add_regulator()
829 new->oid = SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, name, in twl_vreg_add_regulator()
831 twl_vreg_sysctl_voltage, "I", "voltage regulator"); in twl_vreg_add_regulator()
833 /* Finally add the regulator to list of supported regulators */ in twl_vreg_add_regulator()
834 LIST_INSERT_HEAD(&sc->sc_vreg_list, new, entries); in twl_vreg_add_regulator()
840 * twl_vreg_add_regulators - adds any voltage regulators to the device
869 while (walker->name != NULL) { in twl_vreg_add_regulators()
870 /* Add the regulator to the list */ in twl_vreg_add_regulators()
871 entry = twl_vreg_add_regulator(sc, walker->name, walker->subdev, in twl_vreg_add_regulators()
872 walker->regbase, walker->fixedvoltage, in twl_vreg_add_regulators()
873 walker->voltages, walker->num_voltages); in twl_vreg_add_regulators()
881 child = ofw_bus_get_node(sc->sc_pdev); in twl_vreg_add_regulators()
883 prop_len = OF_getprop(child, "voltage-regulators", rnames, sizeof(rnames)); in twl_vreg_add_regulators()
897 LIST_FOREACH(entry, &sc->sc_vreg_list, entries) { in twl_vreg_add_regulators()
898 if (strcmp(entry->name, name) == 0) { in twl_vreg_add_regulators()
907 LIST_FOREACH(entry, &sc->sc_vreg_list, entries) { in twl_vreg_add_regulators()
910 device_printf(sc->sc_dev, "%s : %d mV\n", entry->name, millivolts); in twl_vreg_add_regulators()
918 * twl_vreg_init - initialises the list of regulators
937 if (twl_is_4030(sc->sc_pdev)) in twl_vreg_init()
939 else if (twl_is_6030(sc->sc_pdev) || twl_is_6025(sc->sc_pdev)) in twl_vreg_init()
944 config_intrhook_disestablish(&sc->sc_init_hook); in twl_vreg_init()
967 sc->sc_dev = dev; in twl_vreg_attach()
968 sc->sc_pdev = device_get_parent(dev); in twl_vreg_attach()
972 LIST_INIT(&sc->sc_vreg_list); in twl_vreg_attach()
977 sc->sc_init_hook.ich_func = twl_vreg_init; in twl_vreg_attach()
978 sc->sc_init_hook.ich_arg = dev; in twl_vreg_attach()
980 if (config_intrhook_establish(&sc->sc_init_hook) != 0) in twl_vreg_attach()
990 struct twl_regulator_entry *regulator; in twl_vreg_detach() local
998 LIST_FOREACH_SAFE(regulator, &sc->sc_vreg_list, entries, tmp) { in twl_vreg_detach()
999 LIST_REMOVE(regulator, entries); in twl_vreg_detach()
1000 sysctl_remove_oid(regulator->oid, 1, 0); in twl_vreg_detach()
1001 free(regulator, M_DEVBUF); in twl_vreg_detach()