On Fri, Sep 9, 2022 at 12:19 AM TimH <t...@jti.uk.com.invalid> wrote:
> Apologies for the long post, but given the absence of many/any voltage > regulator drivers - especially PMICs - I feel I need to get this all sorted > and agreed. So I have looked long and hard at the Nuttx files and Linux > documentation and to see if I have got it right I would like to see if the > following descriptions of the Nuttx struct fields make sense. > > struct regulator_desc_s > { > const char *name; /* Friendly name that will be used to > get/set/etc a given regulator. For example "VCC" */ > unsigned int n_voltages; /* The number of discrete voltage selector > steps this regulator allows. 0 if linear mapping is to be used instead */ > unsigned int vsel_reg; /* The device-specific regulator > "channel", or GPIO output, or similar, for this regulator */ > unsigned int vsel_mask; /* Mask, if relevant, to use with > vsel_reg*/ > unsigned int enable_reg; /* Device specific enable register, if > relevant, for this regulator */ > unsigned int enable_mask; /* Mask, if relevant, to use with > enable_reg*/ > unsigned int enable_time; /* Time taken for the regulator voltage > output voltage to stabilise after being enabled, in microseconds */ > unsigned int ramp_delay; /* Set the ramp delay for the regulator. > The driver should select ramp delay equal to or less than(closest) > ramp_delay */ > unsigned int uv_step; /* Voltage increase with each selector if > linear mapping. 0 if only selector steps are allowed */ > unsigned int min_uv; /* Smallest voltage consumers may set*/ > unsigned int max_uv; /* Largest voltage consumers may set */ > unsigned int apply_uv; /* ?? SEE BELOW [1] */ > bool boot_on; /* Set if the regulator is enabled when > the system is initially started SEE BELOW [2]. > If the regulator is not enabled by the > hardware or bootloader then it will be enabled when the constraints are > applied */ > }; > > [1] "apply_uv" is a bool in Linux but an int in Nuttx. In Linux it tells > you whether the "constraint" voltage is applied during init. I think it > should be a bool in Nuttx too? With the ACT8945A, for example, REG1-5 power > on by default, whereas REG6 and 7 do not. The REG1-5 will report back "0" > and REG6/6 "1" in boot_on. > > Yes, bool is more suitable than int for apply_uv. > [2] It is not clear, either in Linux or Nuttx, what the "constraint > voltage" that is applied during init will be. Perhaps the NuttX intent is - > or should be - to use an actual value here (hence the int?) which will be > applied during init IF "boot_on" is set on (suggesting it is a parameter > that should be passed TO the regulator register/init function not filled in > BY it? > > boot_on in NuttX is simple, the common code will enable the regulator if boot_on is true otherwise disable it in regulaotr_register. > If this is all (nearly) correct, then I think the call to register a > regulator (from board_bringup, say) needs to initialise the following > variables in the regulator_desc_s struct that's passed: > > - name For example, in my design, REG1 is "VIODDR" > - vsel_reg In my example it is "REG1" and I need to > tell the ACT8945A driver this. > - vsel_mask (if relevant). Not relevant in my case > - enable_reg, if relevant. Not relevant in my case. > - enable_mask, if relevant. Not relevant in my case. > > So we would have (for this i2c device, at least): > > FAR struct regulator_desc_s *act8945a_desc_s; > FAR struct i2c_master_s *act89945a_i2c ; > int ret; > > act89945a_i2c = board_i2c_init(busno); > if (!act8945a_i2c) > { > Blah blah; > } > > act8945a_desc_s->name = "VIODDR"; > act8945a_desc_s->vsel_reg = 1; > > ret = act8945a_device_init(act8945a_desc_s, act8945a_i2c); > if (ret < 0) > { > Blah blah; > } > > The init/register routine will fill in the missing blanks in the structure > and we can go from there to set it up. When needed in the user app, we can > do a "regulator get" to see what we've got and change things as needed. > > Does that sound right or am I way off the mark? > > Yes, I think so. > If I'm nearly right I might add that I believe there are useful members of > the regulator_desc_s structure missing, such as "active_discharge" that's > useful for the ACT8945A. Maybe also "always on" which tells the driver > NEVER to turn this one off - rather important for PMIC devices I would say, > although NuttX apps aren't quite so likely to mess around with regulators > on these custom boards. I can add these to the struct, of course, as I > write my driver. > > The fields in regulator_desc_s are designed for the common regulator framework code, so it's better to put a new field to this struct if the common does the different action based on it. If the new info is only used by a specific driver, regulator_dev_s::priv is a better place. > Final observation - Linux documentation quite clearly states microvolts > for all voltage parameters. That means a simple 3V3 regulator will be set > up with the value 3300000 passed to the functions, so it has to use > uint32_t. Maybe that makes sense for Linux, but perhaps for Nuttx it should > be in millivolts? I see there's a driver for an AXP202 device and that is > clearly assuming millivolts? > > The initial design follows Linux convention, that's why the field ends with _uv not _mv.. uint32_t can hold 4293.967295V with uV which is enough in most case.