linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
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

  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).