aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pinctrl/pinctrl-sunxi.c134
-rw-r--r--drivers/pinctrl/pinctrl-sunxi.h25
2 files changed, 156 insertions, 3 deletions
diff --git a/drivers/pinctrl/pinctrl-sunxi.c b/drivers/pinctrl/pinctrl-sunxi.c
index 6f02e3422af9..fb000b00c6d3 100644
--- a/drivers/pinctrl/pinctrl-sunxi.c
+++ b/drivers/pinctrl/pinctrl-sunxi.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/io.h> 13#include <linux/io.h>
14#include <linux/gpio.h>
14#include <linux/module.h> 15#include <linux/module.h>
15#include <linux/of.h> 16#include <linux/of.h>
16#include <linux/of_address.h> 17#include <linux/of_address.h>
@@ -609,11 +610,53 @@ static int sunxi_pmx_enable(struct pinctrl_dev *pctldev,
609 return 0; 610 return 0;
610} 611}
611 612
613static int
614sunxi_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
615 struct pinctrl_gpio_range *range,
616 unsigned offset,
617 bool input)
618{
619 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
620 struct sunxi_desc_function *desc;
621 char pin_name[SUNXI_PIN_NAME_MAX_LEN];
622 const char *func;
623 u8 bank, pin;
624 int ret;
625
626 bank = (offset) / PINS_PER_BANK;
627 pin = (offset) % PINS_PER_BANK;
628
629 ret = sprintf(pin_name, "P%c%d", 'A' + bank, pin);
630 if (!ret)
631 goto error;
632
633 if (input)
634 func = "gpio_in";
635 else
636 func = "gpio_out";
637
638 desc = sunxi_pinctrl_desc_find_function_by_name(pctl,
639 pin_name,
640 func);
641 if (!desc) {
642 ret = -EINVAL;
643 goto error;
644 }
645
646 sunxi_pmx_set(pctldev, offset, desc->muxval);
647
648 ret = 0;
649
650error:
651 return ret;
652}
653
612static struct pinmux_ops sunxi_pmx_ops = { 654static struct pinmux_ops sunxi_pmx_ops = {
613 .get_functions_count = sunxi_pmx_get_funcs_cnt, 655 .get_functions_count = sunxi_pmx_get_funcs_cnt,
614 .get_function_name = sunxi_pmx_get_func_name, 656 .get_function_name = sunxi_pmx_get_func_name,
615 .get_function_groups = sunxi_pmx_get_func_groups, 657 .get_function_groups = sunxi_pmx_get_func_groups,
616 .enable = sunxi_pmx_enable, 658 .enable = sunxi_pmx_enable,
659 .gpio_set_direction = sunxi_pmx_gpio_set_direction,
617}; 660};
618 661
619static struct pinctrl_desc sunxi_pctrl_desc = { 662static struct pinctrl_desc sunxi_pctrl_desc = {
@@ -622,6 +665,60 @@ static struct pinctrl_desc sunxi_pctrl_desc = {
622 .pmxops = &sunxi_pmx_ops, 665 .pmxops = &sunxi_pmx_ops,
623}; 666};
624 667
668static int sunxi_pinctrl_gpio_request(struct gpio_chip *chip, unsigned offset)
669{
670 return pinctrl_request_gpio(chip->base + offset);
671}
672
673static void sunxi_pinctrl_gpio_free(struct gpio_chip *chip, unsigned offset)
674{
675 pinctrl_free_gpio(chip->base + offset);
676}
677
678static int sunxi_pinctrl_gpio_direction_input(struct gpio_chip *chip,
679 unsigned offset)
680{
681 return pinctrl_gpio_direction_input(chip->base + offset);
682}
683
684static int sunxi_pinctrl_gpio_get(struct gpio_chip *chip, unsigned offset)
685{
686 struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev);
687
688 u32 reg = sunxi_data_reg(offset);
689 u8 index = sunxi_data_offset(offset);
690 u32 val = (readl(pctl->membase + reg) >> index) & DATA_PINS_MASK;
691
692 return val;
693}
694
695static int sunxi_pinctrl_gpio_direction_output(struct gpio_chip *chip,
696 unsigned offset, int value)
697{
698 return pinctrl_gpio_direction_output(chip->base + offset);
699}
700
701static void sunxi_pinctrl_gpio_set(struct gpio_chip *chip,
702 unsigned offset, int value)
703{
704 struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev);
705 u32 reg = sunxi_data_reg(offset);
706 u8 index = sunxi_data_offset(offset);
707
708 writel((value & DATA_PINS_MASK) << index, pctl->membase + reg);
709}
710
711static struct gpio_chip sunxi_pinctrl_gpio_chip = {
712 .owner = THIS_MODULE,
713 .request = sunxi_pinctrl_gpio_request,
714 .free = sunxi_pinctrl_gpio_free,
715 .direction_input = sunxi_pinctrl_gpio_direction_input,
716 .direction_output = sunxi_pinctrl_gpio_direction_output,
717 .get = sunxi_pinctrl_gpio_get,
718 .set = sunxi_pinctrl_gpio_set,
719 .can_sleep = 0,
720};
721
625static struct of_device_id sunxi_pinctrl_match[] = { 722static struct of_device_id sunxi_pinctrl_match[] = {
626 { .compatible = "allwinner,sun5i-a13-pinctrl", .data = (void *)&sun5i_a13_pinctrl_data }, 723 { .compatible = "allwinner,sun5i-a13-pinctrl", .data = (void *)&sun5i_a13_pinctrl_data },
627 {} 724 {}
@@ -737,7 +834,7 @@ static int sunxi_pinctrl_probe(struct platform_device *pdev)
737 const struct of_device_id *device; 834 const struct of_device_id *device;
738 struct pinctrl_pin_desc *pins; 835 struct pinctrl_pin_desc *pins;
739 struct sunxi_pinctrl *pctl; 836 struct sunxi_pinctrl *pctl;
740 int i, ret; 837 int i, ret, last_pin;
741 838
742 pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL); 839 pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
743 if (!pctl) 840 if (!pctl)
@@ -781,9 +878,42 @@ static int sunxi_pinctrl_probe(struct platform_device *pdev)
781 return -EINVAL; 878 return -EINVAL;
782 } 879 }
783 880
784 dev_info(&pdev->dev, "initialized sunXi pin control driver\n"); 881 pctl->chip = devm_kzalloc(&pdev->dev, sizeof(*pctl->chip), GFP_KERNEL);
882 if (!pctl->chip) {
883 ret = -ENOMEM;
884 goto pinctrl_error;
885 }
886
887 last_pin = pctl->desc->pins[pctl->desc->npins - 1].pin.number;
888 pctl->chip = &sunxi_pinctrl_gpio_chip;
889 pctl->chip->ngpio = round_up(last_pin, PINS_PER_BANK);
890 pctl->chip->label = dev_name(&pdev->dev);
891 pctl->chip->dev = &pdev->dev;
892 pctl->chip->base = 0;
893
894 ret = gpiochip_add(pctl->chip);
895 if (ret)
896 goto pinctrl_error;
897
898 for (i = 0; i < pctl->desc->npins; i++) {
899 const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
900
901 ret = gpiochip_add_pin_range(pctl->chip, dev_name(&pdev->dev),
902 pin->pin.number,
903 pin->pin.number, 1);
904 if (ret)
905 goto gpiochip_error;
906 }
907
908 dev_info(&pdev->dev, "initialized sunXi PIO driver\n");
785 909
786 return 0; 910 return 0;
911
912gpiochip_error:
913 ret = gpiochip_remove(pctl->chip);
914pinctrl_error:
915 pinctrl_unregister(pctl->pctl_dev);
916 return ret;
787} 917}
788 918
789static struct platform_driver sunxi_pinctrl_driver = { 919static struct platform_driver sunxi_pinctrl_driver = {
diff --git a/drivers/pinctrl/pinctrl-sunxi.h b/drivers/pinctrl/pinctrl-sunxi.h
index 0dc3b9d5321b..1ee35c03eef1 100644
--- a/drivers/pinctrl/pinctrl-sunxi.h
+++ b/drivers/pinctrl/pinctrl-sunxi.h
@@ -254,8 +254,11 @@
254#define SUNXI_PINCTRL_PIN_PG30 PINCTRL_PIN(PG_BASE + 30, "PG30") 254#define SUNXI_PINCTRL_PIN_PG30 PINCTRL_PIN(PG_BASE + 30, "PG30")
255#define SUNXI_PINCTRL_PIN_PG31 PINCTRL_PIN(PG_BASE + 31, "PG31") 255#define SUNXI_PINCTRL_PIN_PG31 PINCTRL_PIN(PG_BASE + 31, "PG31")
256 256
257#define SUNXI_PIN_NAME_MAX_LEN 5
258
257#define BANK_MEM_SIZE 0x24 259#define BANK_MEM_SIZE 0x24
258#define MUX_REGS_OFFSET 0x0 260#define MUX_REGS_OFFSET 0x0
261#define DATA_REGS_OFFSET 0x10
259#define DLEVEL_REGS_OFFSET 0x14 262#define DLEVEL_REGS_OFFSET 0x14
260#define PULL_REGS_OFFSET 0x1c 263#define PULL_REGS_OFFSET 0x1c
261 264
@@ -263,6 +266,9 @@
263#define MUX_PINS_PER_REG 8 266#define MUX_PINS_PER_REG 8
264#define MUX_PINS_BITS 4 267#define MUX_PINS_BITS 4
265#define MUX_PINS_MASK 0x0f 268#define MUX_PINS_MASK 0x0f
269#define DATA_PINS_PER_REG 32
270#define DATA_PINS_BITS 1
271#define DATA_PINS_MASK 0x01
266#define DLEVEL_PINS_PER_REG 16 272#define DLEVEL_PINS_PER_REG 16
267#define DLEVEL_PINS_BITS 2 273#define DLEVEL_PINS_BITS 2
268#define DLEVEL_PINS_MASK 0x03 274#define DLEVEL_PINS_MASK 0x03
@@ -283,6 +289,8 @@ struct sunxi_desc_pin {
283struct sunxi_pinctrl_desc { 289struct sunxi_pinctrl_desc {
284 const struct sunxi_desc_pin *pins; 290 const struct sunxi_desc_pin *pins;
285 int npins; 291 int npins;
292 struct pinctrl_gpio_range *ranges;
293 int nranges;
286}; 294};
287 295
288struct sunxi_pinctrl_function { 296struct sunxi_pinctrl_function {
@@ -299,6 +307,7 @@ struct sunxi_pinctrl_group {
299 307
300struct sunxi_pinctrl { 308struct sunxi_pinctrl {
301 void __iomem *membase; 309 void __iomem *membase;
310 struct gpio_chip *chip;
302 struct sunxi_pinctrl_desc *desc; 311 struct sunxi_pinctrl_desc *desc;
303 struct device *dev; 312 struct device *dev;
304 struct sunxi_pinctrl_function *functions; 313 struct sunxi_pinctrl_function *functions;
@@ -321,7 +330,6 @@ struct sunxi_pinctrl {
321 .muxval = _val, \ 330 .muxval = _val, \
322 } 331 }
323 332
324
325/* 333/*
326 * The sunXi PIO registers are organized as is: 334 * The sunXi PIO registers are organized as is:
327 * 0x00 - 0x0c Muxing values. 335 * 0x00 - 0x0c Muxing values.
@@ -354,6 +362,21 @@ static inline u32 sunxi_mux_offset(u16 pin)
354 return pin_num * MUX_PINS_BITS; 362 return pin_num * MUX_PINS_BITS;
355} 363}
356 364
365static inline u32 sunxi_data_reg(u16 pin)
366{
367 u8 bank = pin / PINS_PER_BANK;
368 u32 offset = bank * BANK_MEM_SIZE;
369 offset += DATA_REGS_OFFSET;
370 offset += pin % PINS_PER_BANK / DATA_PINS_PER_REG * 0x04;
371 return round_down(offset, 4);
372}
373
374static inline u32 sunxi_data_offset(u16 pin)
375{
376 u32 pin_num = pin % DATA_PINS_PER_REG;
377 return pin_num * DATA_PINS_BITS;
378}
379
357static inline u32 sunxi_dlevel_reg(u16 pin) 380static inline u32 sunxi_dlevel_reg(u16 pin)
358{ 381{
359 u8 bank = pin / PINS_PER_BANK; 382 u8 bank = pin / PINS_PER_BANK;