From: "Jonathan Neuschäfer" <j.neuschaefer@gmx.net> To: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de> Cc: "Jonathan Neuschäfer" <j.neuschaefer@gmx.net>, linux-kernel@vger.kernel.org, "Alexandre Belloni" <alexandre.belloni@bootlin.com>, "Heiko Stuebner" <heiko@sntech.de>, linux-pwm@vger.kernel.org, "Linus Walleij" <linus.walleij@linaro.org>, "Thierry Reding" <thierry.reding@gmail.com>, "Fabio Estevam" <festevam@gmail.com>, linux-rtc@vger.kernel.org, "Arnd Bergmann" <arnd@arndb.de>, "Mauro Carvalho Chehab" <mchehab+huawei@kernel.org>, "Sam Ravnborg" <sam@ravnborg.org>, "Daniel Palmer" <daniel@0x0f.com>, "Andy Shevchenko" <andy.shevchenko@gmail.com>, "Andreas Kemnade" <andreas@kemnade.info>, "NXP Linux Team" <linux-imx@nxp.com>, devicetree@vger.kernel.org, "Stephan Gerhold" <stephan@gerhold.net>, allen <allen.chen@ite.com.tw>, "Sascha Hauer" <s.hauer@pengutronix.de>, "Lubomir Rintel" <lkundrak@v3.sk>, "Rob Herring" <robh+dt@kernel.org>, "Lee Jones" <lee.jones@linaro.org>, linux-arm-kernel@lists.infradead.org, "Alessandro Zummo" <a.zummo@towertech.it>, "Mark Brown" <broonie@kernel.org>, "Pengutronix Kernel Team" <kernel@pengutronix.de>, "Heiko Stuebner" <heiko.stuebner@theobroma-systems.com>, "Josua Mayer" <josua.mayer@jm0.eu>, "Shawn Guo" <shawnguo@kernel.org>, "David S. Miller" <davem@davemloft.net> Subject: Re: [PATCH v3 4/7] pwm: ntxec: Add driver for PWM function in Netronix EC Date: Sun, 27 Sep 2020 23:10:44 +0200 Message-ID: <20200927211044.GC2510@latitude> (raw) In-Reply-To: <20200925063037.fcrmqvpe5noi3ef4@pengutronix.de> [-- Attachment #1: Type: text/plain, Size: 5793 bytes --] On Fri, Sep 25, 2020 at 08:30:37AM +0200, Uwe Kleine-König wrote: > Hello Jonathan, [...] > > +config PWM_NTXEC > > + tristate "Netronix embedded controller PWM support" > > + depends on MFD_NTXEC > > + help > > + Say yes here if you want to support the PWM output of the embedded > > + controller found in certain e-book readers designed by the ODM > > + Netronix. > > Is it only me who had to look up what ODM means? If not, maybe spell it > out? I'm sure other readers will have the same problem. I'll spell it out. > > +/* > > + * The maximum input value (in nanoseconds) is determined by the time base and > > + * the range of the hardware registers that hold the converted value. > > + * It fits into 32 bits, so we can do our calculations in 32 bits as well. > > + */ > > +#define MAX_PERIOD_NS (TIME_BASE_NS * 0x10000 - 1) > > The maximal configurable period length is 0xffff, so I would have > expected MAX_PERIOD_NS to be 0xffff * TIME_BASE_NS? Due to the division rounding down, TIME_BASE_NS * 0x10000 - 1 would be the highest input that results in a representable value after the division, but I'm not sure it otherwise makes sense. > > > +static int ntxec_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm_dev, > > + const struct pwm_state *state) > > +{ > > + struct ntxec_pwm *pwm = pwmchip_to_pwm(pwm_dev->chip); > > + unsigned int duty = state->duty_cycle; > > + unsigned int period = state->period; > > + int res = 0; > > + > > I assume your device only supports normal polarity? If so, please check > for it here and point out this limitation in the header (in the format > that is for example used in pwm-sifive.c to make it easy to grep for > that). I haven't seen any indication that it supports inverted polarity. I'll point it out in the header comment, and add a check. > > > + if (period > MAX_PERIOD_NS) { > > + dev_warn(pwm->dev, > > + "Period is not representable in 16 bits after division by %u: %u\n", > > + TIME_BASE_NS, period); > > No error messages in .apply() please; this might spam the kernel log. > > Also the expectation when a too big period is requested is to configure > for the biggest possible period. So just do: > > if (period > MAX_PERIOD_NS) { > period = MAX_PERIOD_NS; > > if (duty > period) > duty = period; > } > > (or something equivalent). Okay, I'll adjust it. > > + /* > > + * Writing a duty cycle of zone puts the device into a state where > > What is "zone"? A mixture of zero and one and so approximately 0.5? Oops, that's a typo. I just meant "zero". > > + * writing a higher duty cycle doesn't result in the brightness that it > > + * usually results in. This can be fixed by cycling the ENABLE register. > > + * > > + * As a workaround, write ENABLE=0 when the duty cycle is zero. > > + */ > > + if (state->enabled && duty != 0) { > > + res = regmap_write(pwm->ec->regmap, NTXEC_REG_ENABLE, ntxec_reg8(1)); > > + if (res) > > + return res; > > + > > + /* Disable the auto-off timer */ > > + res = regmap_write(pwm->ec->regmap, NTXEC_REG_AUTO_OFF_HI, ntxec_reg8(0xff)); > > + if (res) > > + return res; > > + > > + return regmap_write(pwm->ec->regmap, NTXEC_REG_AUTO_OFF_LO, ntxec_reg8(0xff)); > > + } else { > > + return regmap_write(pwm->ec->regmap, NTXEC_REG_ENABLE, ntxec_reg8(0)); > > + } > > This code is wrong for state->enabled = false. Why? > How does the PWM behave when .apply is called? Does it complete the > currently running period? Can it happen that when you switch from say > > .duty_cycle = 900 * TIME_BASE_NS (0x384) > .period = 1800 * TIME_BASE_NS (0x708) > > to > > .duty_cycle = 300 * TIME_BASE_NS (0x12c) > .period = 600 * TIME_BASE_NS (0x258) > > that a period with > > .duty_cycle = 388 * TIME_BASE_NS (0x184) > .period = 1800 * TIME_BASE_NS (0x708) > > (because only NTXEC_REG_PERIOD_HIGH was written when the new period > started) or something similar is emitted? Changes take effect after the low byte is written, so a result like 0x184 in the above example should not happen. When the period and duty cycle are both changed, it temporarily results in an inconsistent state: - period = 1800ns, duty cycle = 900ns - period = 600ns, duty cycle = 900ns (!) - period = 600ns, duty cycle = 300ns The inconsistent state of duty cycle > period is handled gracefully by the EC and it outputs a 100% duty cycle, as far as I can tell. I currently don't have a logic analyzer / oscilloscope to measure whether we get full PWM periods, or some kind of glitch when the new period starts in the middle of the last one. > > +} > > + > > +static struct pwm_ops ntxec_pwm_ops = { > > + .apply = ntxec_pwm_apply, > > Please implement a .get_state() callback. And enable PWM_DEBUG during > your tests. The device doesn't support reading back the PWM state. What should a driver do in this case? > > + .owner = THIS_MODULE, > > +}; > > + > > +static int ntxec_pwm_probe(struct platform_device *pdev) > > +{ > > + struct ntxec *ec = dev_get_drvdata(pdev->dev.parent); > > + struct ntxec_pwm *pwm; > > Please don't call this variable pwm. I would expect that a variable with > this name is of type pwm_device. I would have called it "ddata" (and the > type would be named ntxec_pwm_ddata for me); another usual name is "priv". Ok, I'll rename it. > > + chip->npwm = 1; > > + > > + res = pwmchip_add(chip); > > + if (res < 0) > > + return res; > > + > > + platform_set_drvdata(pdev, pwm); > > If you do the platform_set_drvdata earlier you can just do > > return pwmchip_add(chip); Good idea, I'll do that. Thanks, Jonathan Neuschäfer [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --]
next prev parent reply index Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-09-24 19:24 [PATCH v3 0/7] Netronix embedded controller driver for Kobo and Tolino ebook readers Jonathan Neuschäfer 2020-09-24 19:24 ` [PATCH v3 1/7] dt-bindings: Add vendor prefix for Netronix, Inc Jonathan Neuschäfer 2020-10-12 7:19 ` Uwe Kleine-König 2020-10-12 11:48 ` Lee Jones 2020-09-24 19:24 ` [PATCH v3 2/7] dt-bindings: mfd: Add binding for Netronix embedded controller Jonathan Neuschäfer 2020-09-29 18:52 ` Rob Herring 2020-09-24 19:24 ` [PATCH v3 3/7] mfd: Add base driver " Jonathan Neuschäfer 2020-09-25 9:29 ` Andy Shevchenko 2020-09-25 21:32 ` Jonathan Neuschäfer 2020-09-29 16:37 ` Andy Shevchenko 2020-10-02 22:54 ` Jonathan Neuschäfer 2020-09-24 19:24 ` [PATCH v3 4/7] pwm: ntxec: Add driver for PWM function in Netronix EC Jonathan Neuschäfer 2020-09-25 6:30 ` Uwe Kleine-König 2020-09-27 21:10 ` Jonathan Neuschäfer [this message] 2020-09-28 8:35 ` Uwe Kleine-König 2020-10-02 23:36 ` Jonathan Neuschäfer 2020-10-03 8:17 ` Andy Shevchenko 2020-09-24 19:24 ` [PATCH v3 5/7] rtc: New driver for RTC in Netronix embedded controller Jonathan Neuschäfer 2020-09-24 20:40 ` Andreas Kemnade 2020-10-02 23:41 ` Jonathan Neuschäfer 2020-09-25 5:44 ` Uwe Kleine-König 2020-10-04 1:43 ` Jonathan Neuschäfer 2020-10-04 8:42 ` Alexandre Belloni 2020-10-11 19:09 ` Jonathan Neuschäfer 2020-10-05 7:35 ` Uwe Kleine-König 2020-09-25 9:36 ` Alexandre Belloni 2020-09-25 22:00 ` Jonathan Neuschäfer 2020-09-24 19:24 ` [PATCH v3 6/7] MAINTAINERS: Add entry for " Jonathan Neuschäfer 2020-09-25 5:08 ` [PATCH v3 7/7] ARM: dts: imx50-kobo-aura: Add " Jonathan Neuschäfer 2020-10-07 7:46 ` Krzysztof Kozlowski 2020-10-11 19:42 ` Jonathan Neuschäfer
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20200927211044.GC2510@latitude \ --to=j.neuschaefer@gmx.net \ --cc=a.zummo@towertech.it \ --cc=alexandre.belloni@bootlin.com \ --cc=allen.chen@ite.com.tw \ --cc=andreas@kemnade.info \ --cc=andy.shevchenko@gmail.com \ --cc=arnd@arndb.de \ --cc=broonie@kernel.org \ --cc=daniel@0x0f.com \ --cc=davem@davemloft.net \ --cc=devicetree@vger.kernel.org \ --cc=festevam@gmail.com \ --cc=heiko.stuebner@theobroma-systems.com \ --cc=heiko@sntech.de \ --cc=josua.mayer@jm0.eu \ --cc=kernel@pengutronix.de \ --cc=lee.jones@linaro.org \ --cc=linus.walleij@linaro.org \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-imx@nxp.com \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-pwm@vger.kernel.org \ --cc=linux-rtc@vger.kernel.org \ --cc=lkundrak@v3.sk \ --cc=mchehab+huawei@kernel.org \ --cc=robh+dt@kernel.org \ --cc=s.hauer@pengutronix.de \ --cc=sam@ravnborg.org \ --cc=shawnguo@kernel.org \ --cc=stephan@gerhold.net \ --cc=thierry.reding@gmail.com \ --cc=u.kleine-koenig@pengutronix.de \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
LKML Archive on lore.kernel.org Archives are clonable: git clone --mirror https://lore.kernel.org/lkml/0 lkml/git/0.git git clone --mirror https://lore.kernel.org/lkml/1 lkml/git/1.git git clone --mirror https://lore.kernel.org/lkml/2 lkml/git/2.git git clone --mirror https://lore.kernel.org/lkml/3 lkml/git/3.git git clone --mirror https://lore.kernel.org/lkml/4 lkml/git/4.git git clone --mirror https://lore.kernel.org/lkml/5 lkml/git/5.git git clone --mirror https://lore.kernel.org/lkml/6 lkml/git/6.git git clone --mirror https://lore.kernel.org/lkml/7 lkml/git/7.git git clone --mirror https://lore.kernel.org/lkml/8 lkml/git/8.git git clone --mirror https://lore.kernel.org/lkml/9 lkml/git/9.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 lkml lkml/ https://lore.kernel.org/lkml \ linux-kernel@vger.kernel.org public-inbox-index lkml Example config snippet for mirrors Newsgroup available over NNTP: nntp://nntp.lore.kernel.org/org.kernel.vger.linux-kernel AGPL code for this site: git clone https://public-inbox.org/public-inbox.git