summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/meson
diff options
context:
space:
mode:
authorJerome Brunet <jbrunet@baylibre.com>2019-05-16 11:13:39 -0400
committerLinus Walleij <linus.walleij@linaro.org>2019-05-24 07:49:32 -0400
commitb22a7f85443e579367dfc2d7f4cb6aa863c3a709 (patch)
treeaa61635273dd93517d74a1b92ac12b644af1b03e /drivers/pinctrl/meson
parent1254db248fce4e2cf05a01c1c8df3b79745424c0 (diff)
pinctrl: meson: add output support in pinconf
Add pinconf support for PIN_CONFIG_OUTPUT_ENABLE and PIN_CONFIG_OUTPUT in the meson pinctrl driver. Signed-off-by: Jerome Brunet <jbrunet@baylibre.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/meson')
-rw-r--r--drivers/pinctrl/meson/pinctrl-meson.c182
1 files changed, 127 insertions, 55 deletions
diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c
index 33b4b141baac..410eb7559016 100644
--- a/drivers/pinctrl/meson/pinctrl-meson.c
+++ b/drivers/pinctrl/meson/pinctrl-meson.c
@@ -174,6 +174,88 @@ int meson_pmx_get_groups(struct pinctrl_dev *pcdev, unsigned selector,
174 return 0; 174 return 0;
175} 175}
176 176
177static int meson_pinconf_set_gpio_bit(struct meson_pinctrl *pc,
178 unsigned int pin,
179 unsigned int reg_type,
180 bool arg)
181{
182 struct meson_bank *bank;
183 unsigned int reg, bit;
184 int ret;
185
186 ret = meson_get_bank(pc, pin, &bank);
187 if (ret)
188 return ret;
189
190 meson_calc_reg_and_bit(bank, pin, reg_type, &reg, &bit);
191 return regmap_update_bits(pc->reg_gpio, reg, BIT(bit),
192 arg ? BIT(bit) : 0);
193}
194
195static int meson_pinconf_get_gpio_bit(struct meson_pinctrl *pc,
196 unsigned int pin,
197 unsigned int reg_type)
198{
199 struct meson_bank *bank;
200 unsigned int reg, bit, val;
201 int ret;
202
203 ret = meson_get_bank(pc, pin, &bank);
204 if (ret)
205 return ret;
206
207 meson_calc_reg_and_bit(bank, pin, reg_type, &reg, &bit);
208 ret = regmap_read(pc->reg_gpio, reg, &val);
209 if (ret)
210 return ret;
211
212 return BIT(bit) & val ? 1 : 0;
213}
214
215static int meson_pinconf_set_output(struct meson_pinctrl *pc,
216 unsigned int pin,
217 bool out)
218{
219 return meson_pinconf_set_gpio_bit(pc, pin, REG_DIR, !out);
220}
221
222static int meson_pinconf_get_output(struct meson_pinctrl *pc,
223 unsigned int pin)
224{
225 int ret = meson_pinconf_get_gpio_bit(pc, pin, REG_DIR);
226
227 if (ret < 0)
228 return ret;
229
230 return !ret;
231}
232
233static int meson_pinconf_set_drive(struct meson_pinctrl *pc,
234 unsigned int pin,
235 bool high)
236{
237 return meson_pinconf_set_gpio_bit(pc, pin, REG_OUT, high);
238}
239
240static int meson_pinconf_get_drive(struct meson_pinctrl *pc,
241 unsigned int pin)
242{
243 return meson_pinconf_get_gpio_bit(pc, pin, REG_OUT);
244}
245
246static int meson_pinconf_set_output_drive(struct meson_pinctrl *pc,
247 unsigned int pin,
248 bool high)
249{
250 int ret;
251
252 ret = meson_pinconf_set_output(pc, pin, true);
253 if (ret)
254 return ret;
255
256 return meson_pinconf_set_drive(pc, pin, high);
257}
258
177static int meson_pinconf_disable_bias(struct meson_pinctrl *pc, 259static int meson_pinconf_disable_bias(struct meson_pinctrl *pc,
178 unsigned int pin) 260 unsigned int pin)
179{ 261{
@@ -267,39 +349,48 @@ static int meson_pinconf_set(struct pinctrl_dev *pcdev, unsigned int pin,
267{ 349{
268 struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev); 350 struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
269 enum pin_config_param param; 351 enum pin_config_param param;
270 unsigned int drive_strength_ua; 352 unsigned int arg = 0;
271 int i, ret; 353 int i, ret;
272 354
273 for (i = 0; i < num_configs; i++) { 355 for (i = 0; i < num_configs; i++) {
274 param = pinconf_to_config_param(configs[i]); 356 param = pinconf_to_config_param(configs[i]);
275 357
276 switch (param) { 358 switch (param) {
359 case PIN_CONFIG_DRIVE_STRENGTH_UA:
360 case PIN_CONFIG_OUTPUT_ENABLE:
361 case PIN_CONFIG_OUTPUT:
362 arg = pinconf_to_config_argument(configs[i]);
363 break;
364
365 default:
366 break;
367 }
368
369 switch (param) {
277 case PIN_CONFIG_BIAS_DISABLE: 370 case PIN_CONFIG_BIAS_DISABLE:
278 ret = meson_pinconf_disable_bias(pc, pin); 371 ret = meson_pinconf_disable_bias(pc, pin);
279 if (ret)
280 return ret;
281 break; 372 break;
282 case PIN_CONFIG_BIAS_PULL_UP: 373 case PIN_CONFIG_BIAS_PULL_UP:
283 ret = meson_pinconf_enable_bias(pc, pin, true); 374 ret = meson_pinconf_enable_bias(pc, pin, true);
284 if (ret)
285 return ret;
286 break; 375 break;
287 case PIN_CONFIG_BIAS_PULL_DOWN: 376 case PIN_CONFIG_BIAS_PULL_DOWN:
288 ret = meson_pinconf_enable_bias(pc, pin, false); 377 ret = meson_pinconf_enable_bias(pc, pin, false);
289 if (ret)
290 return ret;
291 break; 378 break;
292 case PIN_CONFIG_DRIVE_STRENGTH_UA: 379 case PIN_CONFIG_DRIVE_STRENGTH_UA:
293 drive_strength_ua = 380 ret = meson_pinconf_set_drive_strength(pc, pin, arg);
294 pinconf_to_config_argument(configs[i]); 381 break;
295 ret = meson_pinconf_set_drive_strength 382 case PIN_CONFIG_OUTPUT_ENABLE:
296 (pc, pin, drive_strength_ua); 383 ret = meson_pinconf_set_output(pc, pin, arg);
297 if (ret) 384 break;
298 return ret; 385 case PIN_CONFIG_OUTPUT:
386 ret = meson_pinconf_set_output_drive(pc, pin, arg);
299 break; 387 break;
300 default: 388 default:
301 return -ENOTSUPP; 389 ret = -ENOTSUPP;
302 } 390 }
391
392 if (ret)
393 return ret;
303 } 394 }
304 395
305 return 0; 396 return 0;
@@ -403,6 +494,24 @@ static int meson_pinconf_get(struct pinctrl_dev *pcdev, unsigned int pin,
403 if (ret) 494 if (ret)
404 return ret; 495 return ret;
405 break; 496 break;
497 case PIN_CONFIG_OUTPUT_ENABLE:
498 ret = meson_pinconf_get_output(pc, pin);
499 if (ret <= 0)
500 return -EINVAL;
501 arg = 1;
502 break;
503 case PIN_CONFIG_OUTPUT:
504 ret = meson_pinconf_get_output(pc, pin);
505 if (ret <= 0)
506 return -EINVAL;
507
508 ret = meson_pinconf_get_drive(pc, pin);
509 if (ret < 0)
510 return -EINVAL;
511
512 arg = ret;
513 break;
514
406 default: 515 default:
407 return -ENOTSUPP; 516 return -ENOTSUPP;
408 } 517 }
@@ -447,56 +556,19 @@ static const struct pinconf_ops meson_pinconf_ops = {
447 556
448static int meson_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) 557static int meson_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
449{ 558{
450 struct meson_pinctrl *pc = gpiochip_get_data(chip); 559 return meson_pinconf_set_output(gpiochip_get_data(chip), gpio, false);
451 unsigned int reg, bit;
452 struct meson_bank *bank;
453 int ret;
454
455 ret = meson_get_bank(pc, gpio, &bank);
456 if (ret)
457 return ret;
458
459 meson_calc_reg_and_bit(bank, gpio, REG_DIR, &reg, &bit);
460
461 return regmap_update_bits(pc->reg_gpio, reg, BIT(bit), BIT(bit));
462} 560}
463 561
464static int meson_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, 562static int meson_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
465 int value) 563 int value)
466{ 564{
467 struct meson_pinctrl *pc = gpiochip_get_data(chip); 565 return meson_pinconf_set_output_drive(gpiochip_get_data(chip),
468 unsigned int reg, bit; 566 gpio, value);
469 struct meson_bank *bank;
470 int ret;
471
472 ret = meson_get_bank(pc, gpio, &bank);
473 if (ret)
474 return ret;
475
476 meson_calc_reg_and_bit(bank, gpio, REG_DIR, &reg, &bit);
477 ret = regmap_update_bits(pc->reg_gpio, reg, BIT(bit), 0);
478 if (ret)
479 return ret;
480
481 meson_calc_reg_and_bit(bank, gpio, REG_OUT, &reg, &bit);
482 return regmap_update_bits(pc->reg_gpio, reg, BIT(bit),
483 value ? BIT(bit) : 0);
484} 567}
485 568
486static void meson_gpio_set(struct gpio_chip *chip, unsigned gpio, int value) 569static void meson_gpio_set(struct gpio_chip *chip, unsigned gpio, int value)
487{ 570{
488 struct meson_pinctrl *pc = gpiochip_get_data(chip); 571 meson_pinconf_set_drive(gpiochip_get_data(chip), gpio, value);
489 unsigned int reg, bit;
490 struct meson_bank *bank;
491 int ret;
492
493 ret = meson_get_bank(pc, gpio, &bank);
494 if (ret)
495 return;
496
497 meson_calc_reg_and_bit(bank, gpio, REG_OUT, &reg, &bit);
498 regmap_update_bits(pc->reg_gpio, reg, BIT(bit),
499 value ? BIT(bit) : 0);
500} 572}
501 573
502static int meson_gpio_get(struct gpio_chip *chip, unsigned gpio) 574static int meson_gpio_get(struct gpio_chip *chip, unsigned gpio)