From: tony@atomide.com (Tony Lindgren)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v5 05/10] pinctrl: single: support pinconf generic
Date: Fri, 16 Nov 2012 16:43:13 -0800 [thread overview]
Message-ID: <20121117004313.GN6801@atomide.com> (raw)
In-Reply-To: <1352968600-15345-6-git-send-email-haojian.zhuang@gmail.com>
Hi,
> static int pcs_pinconf_get(struct pinctrl_dev *pctldev,
> unsigned pin, unsigned long *config)
> {
> - return -ENOTSUPP;
> + struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
> + enum pin_config_param config_param = pinconf_to_config_param(*config);
> + union pcs_pinconf_argument_t arg;
> + u32 offset;
> + unsigned data;
> + int ret;
> +
> + if (!pcs->conf.nconfs)
> + return -ENOTSUPP;
> +
> + ret = pcs_pinconf_get_config(pctldev, pin, config_param);
> + if (ret < 0)
> + return ret;
> +
> + offset = pin * (pcs->width / BITS_PER_BYTE);
> + data = pcs->read(pcs->base + offset);
> +
> + arg.data = pinconf_to_config_argument(ret);
> + data = (data >> arg.bits.shift) & arg.bits.mask;
Shouldn't you just return data here?
*config = data;
return 0;
> + arg.bits.value = data;
> + *config = pinconf_to_config_packed(config_param, arg.data);
> + return 0;
Instead of these? Or how else is the consumer driver supposed
to use the value?
> }
>
> static int pcs_pinconf_set(struct pinctrl_dev *pctldev,
> unsigned pin, unsigned long config)
> {
> - return -ENOTSUPP;
> + struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
> + enum pin_config_param config_param = pinconf_to_config_param(config);
> + union pcs_pinconf_argument_t arg;
> + u32 offset;
> + unsigned data;
> + int ret;
> +
> + if (!pcs->conf.nconfs)
> + return -ENOTSUPP;
> +
> + ret = pcs_pinconf_get_config(pctldev, pin, config_param);
> + if (ret < 0)
> + return ret;
> +
> + offset = pin * (pcs->width / BITS_PER_BYTE);
> + data = pcs->read(pcs->base + offset);
> +
> + arg.data = pinconf_to_config_argument(config);
> + data = (data >> arg.bits.shift) & arg.bits.mask;
> + arg.bits.value = data;
> + data = pinconf_to_config_packed(config_param, arg.data);
> + pcs->write(data, pcs->base + offset);
> + return 0;
> }
I need to look at this more to understand how this actually relates
to what gets written to the register with my test case :)
> @@ -765,12 +958,82 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
> if (res < 0)
> goto free_function;
>
> - (*map)->type = PIN_MAP_TYPE_MUX_GROUP;
> - (*map)->data.mux.group = np->name;
> - (*map)->data.mux.function = np->name;
> + m->type = PIN_MAP_TYPE_MUX_GROUP;
> + m->data.mux.group = np->name;
> + m->data.mux.function = np->name;
> +
> + if (!nconfs)
> + return 0;
> +
> + conf = devm_kzalloc(pcs->dev, sizeof(*conf) * nconfs, GFP_KERNEL);
> + if (!conf) {
> + res = -ENOMEM;
> + goto free_pingroup;
> + }
> + i = 0;
> + if (!of_property_read_u32_array(np, "pinctrl-single,bias",
> + value, 5)) {
> + /* array: bias value, mask, disable, pull down, pull up */
> + data = value[0] & value[1];
> + arg.bits.shift = ffs(value[1]) - 1;
> + arg.bits.mask = value[1] >> arg.bits.shift;
> + if (pcs_config_match(data, value[2])) {
> + arg.bits.value = value[2] >> arg.bits.shift;
> + conf[i++] = PIN_CONF_PACKED(PIN_CONFIG_BIAS_DISABLE,
> + arg.data);
> + }
> + if (pcs_config_match(data, value[3])) {
> + arg.bits.value = value[3] >> arg.bits.shift;
> + conf[i++] = PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_DOWN,
> + arg.data);
> + }
> + if (pcs_config_match(data, value[4])) {
> + arg.bits.value = value[4] >> arg.bits.shift;
> + conf[i++] = PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_UP,
> + arg.data);
> + }
> + }
Doesn't this mean you only get one of the above working? What happens
if you initially need to set BIAS_DISABLE, but then the consumer driver
wants to set BIAS_PULL_DOWN or something?
Maybe we need separate pinctrl-single,bias-disable, pinctrl-single,bias-pull-down
and pinctrl-single,bias-pull-up?
> + if (!of_property_read_u32_array(np, "pinctrl-single,power-source",
> + value, 2)) {
> + /* array: power source value, mask */
> + data = value[0] & value[1];
> + arg.bits.shift = ffs(value[1]) - 1;
> + arg.bits.mask = value[1] >> arg.bits.shift;
> + arg.bits.value = data >> arg.bits.shift;
> + conf[i++] = PIN_CONF_PACKED(PIN_CONFIG_POWER_SOURCE, arg.data);
> + }
> + if (!of_property_read_u32_array(np, "pinctrl-single,input-schmitt",
> + value, 3)) {
> + /* array: input schmitt value, mask, disable */
> + data = value[0] & value[1];
> + arg.bits.shift = ffs(value[1]) - 1;
> + arg.bits.mask = value[1] >> arg.bits.shift;
> + if (pcs_config_match(data, value[2])) {
> + arg.bits.value = value[2] >> arg.bits.shift;
> + conf[i++] = PIN_CONF_PACKED(PIN_CONFIG_INPUT_SCHMITT_DISABLE,
> + arg.data);
> + } else {
> + arg.bits.value = data >> arg.bits.shift;
> + conf[i++] = PIN_CONF_PACKED(PIN_CONFIG_INPUT_SCHMITT,
> + arg.data);
> + }
> + }
And I think this has a similar problem? What if the consumer driver wants
to set INPUT_SCHMITT with pin_config_set() and the initial value is
SCHMITT_DISABLE? Doesn't the consumer driver get -ENOTSUPP in that case?
I'll look at this more early next week and try to get my testcase working
with it.
Regards,
Tony
next prev parent reply other threads:[~2012-11-17 0:43 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-11-15 8:36 [PATCH v5 0/10] use pinctrl-single in arch mmp Haojian Zhuang
2012-11-15 8:36 ` [PATCH v5 01/10] ARM: mmp: select pinctrl driver Haojian Zhuang
2012-11-15 8:36 ` [PATCH v5 02/10] pinctrl: single: support gpio request and free Haojian Zhuang
2012-11-17 0:44 ` Tony Lindgren
2012-11-20 14:44 ` Linus Walleij
2012-11-15 8:36 ` [PATCH v5 03/10] pinctrl: append method of lookup pinctrl map Haojian Zhuang
2012-11-17 0:46 ` Tony Lindgren
2012-11-17 15:17 ` Haojian Zhuang
2012-11-15 8:36 ` [PATCH v5 04/10] pinctrl: generic: add input schmitt disable parameter Haojian Zhuang
2012-11-20 14:42 ` Linus Walleij
2012-11-15 8:36 ` [PATCH v5 05/10] pinctrl: single: support pinconf generic Haojian Zhuang
2012-11-17 0:43 ` Tony Lindgren [this message]
2012-11-18 4:51 ` Haojian Zhuang
2012-11-18 14:23 ` Haojian Zhuang
2012-11-22 0:08 ` Tony Lindgren
2012-11-22 0:08 ` Tony Lindgren
2012-11-15 8:36 ` [PATCH v5 06/10] ARM: dts: support pinctrl single in pxa910 Haojian Zhuang
2012-11-15 8:36 ` [PATCH v5 07/10] document: devicetree: bind pinconf with pin single Haojian Zhuang
2012-11-26 19:08 ` Stephen Warren
2012-11-15 8:36 ` [PATCH v5 08/10] tty: pxa: configure pin Haojian Zhuang
2012-11-15 8:36 ` [PATCH v5 09/10] i2c: pxa: use devm_kzalloc Haojian Zhuang
2012-11-15 8:36 ` [PATCH v5 10/10] i2c: pxa: configure pinmux Haojian Zhuang
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=20121117004313.GN6801@atomide.com \
--to=tony@atomide.com \
--cc=linux-arm-kernel@lists.infradead.org \
/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
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).