I’ve found only polarity examples with additional devices (like fan,backlight,leds). Maybe it is not possible to define inversion directly on pwm controller.
I asked pwm maintainers about dts and set_polarity but i got response that pwm driver needs to be changed first to using apply_state() instead of disable(), enable(), set_polarity() and config().
added pwm-fan-driver to check if i get further with inverted-state in client-driver…here i get a bit further
drivers/pwm/core.c
struct pwm_device *
of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct of_phandle_args *args)
{
struct pwm_device *pwm;
printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__);
/* check, whether the driver supports a third cell for flags */
if (pc->of_pwm_n_cells < 3)
return ERR_PTR(-EINVAL);
printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__);
/* flags in the third cell are optional */
if (args->args_count < 2)
return ERR_PTR(-EINVAL);
first printk is printed, second not, that means that pwm-cells is less than 3…but my pwm-node has setting pwm-cells to 3…
#pwm-cells=<3>;
looks like the of_pwm_n_cells
is not read out of devicetree and needs to be set by driver (done in different drivers…)…it seems to be used only for dtc
my current code return to this:
root@bpi-r64:~# dmesg | grep -i debug
[ 0.000000] Kernel command line: board=bpi-r64 console=ttyS0,115200n1 earlyp2
[ 0.075685] DEBUG: Passed pwm_mediatek_probe 266
[ 1.196472] DEBUG: Passed devm_of_pwm_get 1190
[ 1.201008] DEBUG: Passed devm_of_pwm_get 1194
[ 1.205541] DEBUG: Passed of_pwm_get 816
[ 1.209553] DEBUG: Passed of_pwm_get 822
[ 1.213567] DEBUG: Passed of_pwm_get 829
[ 1.217583] DEBUG: Passed of_pwm_get 838
[ 1.221595] DEBUG: Passed of_pwm_xlate_with_flags 139 3
[ 1.226822] DEBUG: Passed of_pwm_xlate_with_flags 143
[ 1.231960] DEBUG: Passed of_pwm_xlate_with_flags 147
[ 1.237099] DEBUG: Passed of_pwm_xlate_with_flags 150
[ 1.242239] DEBUG: Passed of_pwm_xlate_with_flags 154
[ 1.247380] DEBUG: Passed of_pwm_xlate_with_flags 158 pwm_no: 2,argc:3
[ 1.253995] DEBUG: Passed of_pwm_get 842
[ 1.258013] DEBUG: Passed devm_of_pwm_get 1202
[ 1.262573] DEBUG: Passed pwm_mediatek_apply 243 PWM#2, inv:1==1?
[ 1.268796] DEBUG: Passed pwm_mediatek_apply 243 PWM#2, inv:1==1?
that means revertive-mode is set in driver (inv:1==1), not yet in hardware because set_polarity is not called. i guess it’s because pwm_mediatek_apply is new framework and disables old functions (enable/disable/config and set_polarity)
i guessed right…after removing callback to .apply .set_polarity gets called
[ 1.250669] DEBUG: Passed of_pwm_xlate_with_flags 158 pwm_no: 2,argc:3
[ 1.257285] DEBUG: Passed of_pwm_get 842
[ 1.261302] DEBUG: Passed devm_of_pwm_get 1202
[ 1.265862] DEBUG: Passed pwm_mediatek_set_polarity 222 PWM#2, inv:1
@Mbk_Kamble can you check with 5.7-pwm2 tree if duty-cycle is now right?
checked if the right bits are cleared/set:
[ 1.201763] DEBUG: Passed pwm_mediatek_set_3dclm 205 value:0x400, clear:1 //clear bit10 (begin at 0) for disabling pwm3-base-mode
[ 1.208554] DEBUG: Passed pwm_mediatek_set_3dclm 205 value:0x40000, clear:0 //set bit 18 (pwm_3dclm_3) for aux-mode
[ 1.215517] DEBUG: Passed pwm_mediatek_set_3dclm 205 value:0x4, clear:0 //set bit 2 for invertive-mode => is wrong because bit 0 is 3dclm_enable (needs to be set to) and right bit here is 3 (+1)
i guess 3dclm is not enabled by default, maybe it needs to be set for the other pwm too (base-mode without inversion)
after modification i got 0x40009 (0000 0000 0000 0100 0000 0000 0000 1001) written to the register which should be right value
[ 1.195725] DEBUG: Passed pwm_mediatek_set_polarity 223 PWM#2, inv:1
[ 1.202085] DEBUG: Passed pwm_mediatek_set_3dclm 206 read val: 0x0 value:0x1, clear:0
[ 1.209919] DEBUG: Passed pwm_mediatek_set_3dclm 212 write val: 0x1 value:0x1, clear:0
[ 1.217838] DEBUG: Passed pwm_mediatek_set_3dclm 206 read val: 0x1 value:0x400, clear:1
[ 1.225843] DEBUG: Passed pwm_mediatek_set_3dclm 212 write val: 0x1 value:0x400, clear:1
[ 1.233935] DEBUG: Passed pwm_mediatek_set_3dclm 206 read val: 0x1 value:0x40000, clear:0
[ 1.242114] DEBUG: Passed pwm_mediatek_set_3dclm 212 write val: 0x40001 value:0x40000, clear:0
[ 1.250728] DEBUG: Passed pwm_mediatek_set_3dclm 206 read val: 0x40001 value:0x8, clear:0
[ 1.258907] DEBUG: Passed pwm_mediatek_set_3dclm 212 write val: 0x40009 value:0x8, clear:0
- set 0x1 (bit 0) => enable 3dclm
- clear 0x400 (bit 10) => disable base mode for pwm2
- set 0x40000 (bit 18) => set aux-bit for pwm2
- set 0x8 (bit 3) => set invertive mode for pwm2
this should be right now for pwm2…but i guess i need to set the other pwm too to non-revertive.
@sam33 can you confirm this? maybe i can optimize the code a bit (so not always set/clear bits already set/cleared). i wrote initial value of 1f00 in probe to 3dclm-register and got 0x41b09 as final value which seems to be right (pwm1,2,4,5 in base mode,pwm3 in aux-mode and inverted + 3dclm enabled).
last state: https://github.com/frank-w/BPI-R2-4.14/tree/5.7-pwm2