tegra20: add pinctrl driver
Subsystems (3)
PATCH 1/2 tegra20: add pinctrl driver
This adds a pinctrl driver for the Tegra 20 line of SoCs. It only supports the three basic pinconfiguration settings function mux, tristate control and pullup/down control.
The driver understands the same devicetree bindings as the Linux one, unimplemented pinconfiguration options will be ignored.
--- arch/arm/dts/tegra20.dtsi | 8 + drivers/pinctrl/Kconfig | 6 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-tegra20.c | 336 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 351 insertions(+) create mode 100644 drivers/pinctrl/pinctrl-tegra20.c
arch/arm/dts/tegra20.dtsi +8 -0
@@ -34,6 +34,14 @@ interrupt-controller; }; + pinmux: pinmux { + compatible = "nvidia,tegra20-pinmux"; + reg = <0x70000014 0x10 /* Tri-state registers */ + 0x70000080 0x20 /* Mux registers */ + 0x700000a0 0x14 /* Pull-up/down registers */ + 0x70000868 0xa8>; /* Pad control registers */ + }; + pmc { compatible = "nvidia,tegra20-pmc"; reg = <0x7000e400 0x400>;
drivers/pinctrl/Kconfig +6 -0
@@ -25,4 +25,10 @@ config PINCTRL_IMX_IOMUX_V3 help This iomux controller is found on i.MX25,35,51,53,6. +config PINCTRL_TEGRA20 + select PINCTRL + bool "Tegra 20 pinmux" + help + The pinmux controller found on the Tegra 20 line of SoCs. + endmenu
drivers/pinctrl/Makefile +1 -0
@@ -2,3 +2,4 @@ obj-$(CONFIG_PINCTRL) += pinctrl.o obj-$(CONFIG_PINCTRL_IMX_IOMUX_V1) += imx-iomux-v1.o obj-$(CONFIG_PINCTRL_IMX_IOMUX_V2) += imx-iomux-v2.o obj-$(CONFIG_PINCTRL_IMX_IOMUX_V3) += imx-iomux-v3.o +obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o
drivers/pinctrl/pinctrl-tegra20.c new file +336 -0
336 lines not on this page · raw message
Signature · 7 lines
1.8.1.4 _______________________________________________ barebox mailing list [email protected] http://lists.infradead.org/mailman/listinfo/barebox
PATCH 2/2 tegra: paz00: import pinconfig from Linux
--- arch/arm/dts/tegra20-paz00.dts | 216 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+)
arch/arm/dts/tegra20-paz00.dts +216 -0
@@ -9,4 +9,220 @@ memory { reg = <0x00000000 0x20000000>; }; + + pinmux { + pinctrl-names = "default"; + pinctrl-0 = <&state_default>; + + state_default: pinmux { + ata { + nvidia,pins = "ata", "atc", "atd", "ate", + "dap2", "gmb", "gmc", "gmd", "spia", + "spib", "spic", "spid", "spie"; + nvidia,function = "gmi"; + }; + atb { + nvidia,pins = "atb", "gma", "gme"; + nvidia,function = "sdio4"; + }; + cdev1 { + nvidia,pins = "cdev1"; + nvidia,function = "plla_out"; + }; + cdev2 { + nvidia,pins = "cdev2"; + nvidia,function = "pllp_out4"; + }; + crtp { + nvidia,pins = "crtp"; + nvidia,function = "crt"; + }; + csus { + nvidia,pins = "csus"; + nvidia,function = "pllc_out1"; + }; + dap1 { + nvidia,pins = "dap1"; + nvidia,function = "dap1"; + }; + dap3 { + nvidia,pins = "dap3"; + nvidia,function = "dap3"; + }; + dap4 { + nvidia,pins = "dap4"; + nvidia,function = "dap4"; + }; + ddc { + nvidia,pins = "ddc"; + nvidia,function = "i2c2"; + }; + dta { + nvidia,pins = "dta", "dtb", "dtc", "dtd", "dte"; + nvidia,function = "rsvd1"; + }; + dtf { + nvidia,pins = "dtf"; + nvidia,function = "i2c3"; + }; + gpu { + nvidia,pins = "gpu", "sdb", "sdd"; + nvidia,function = "pwm"; + }; + gpu7 { + nvidia,pins = "gpu7"; + nvidia,function = "rtck"; + }; + gpv { + nvidia,pins = "gpv", "slxa", "slxk"; + nvidia,function = "pcie"; + }; + hdint { + nvidia,pins = "hdint", "pta"; + nvidia,function = "hdmi"; + }; + i2cp { + nvidia,pins = "i2cp"; + nvidia,function = "i2cp"; + }; + irrx { + nvidia,pins = "irrx", "irtx"; + nvidia,function = "uarta"; + }; + kbca { + nvidia,pins = "kbca", "kbcc", "kbce", "kbcf"; + nvidia,function = "kbc"; + }; + kbcb { + nvidia,pins = "kbcb", "kbcd"; + nvidia,function = "sdio2"; + }; + lcsn { + nvidia,pins = "lcsn", "ld0", "ld1", "ld2", + "ld3", "ld4", "ld5", "ld6", "ld7", + "ld8", "ld9", "ld10", "ld11", "ld12", + "ld13", "ld14", "ld15", "ld16", "ld17", + "ldc", "ldi", "lhp0", "lhp1", "lhp2", + "lhs", "lm0", "lm1", "lpp", "lpw0", + "lpw1", "lpw2", "lsc0", "lsc1", "lsck", + "lsda", "lsdi", "lspi", "lvp0", "lvp1", + "lvs"; + nvidia,function = "displaya"; + }; + owc { + nvidia,pins = "owc"; + nvidia,function = "owr"; + }; + pmc { + nvidia,pins = "pmc"; + nvidia,function = "pwr_on"; + }; + rm { + nvidia,pins = "rm"; + nvidia,function = "i2c1"; + }; + sdc { + nvidia,pins = "sdc"; + nvidia,function = "twc"; + }; + sdio1 { + nvidia,pins = "sdio1"; + nvidia,function = "sdio1"; + }; + slxc { + nvidia,pins = "slxc", "slxd"; + nvidia,function = "spi4"; + }; + spdi { + nvidia,pins = "spdi", "spdo"; + nvidia,function = "rsvd2"; + }; + spif { + nvidia,pins = "spif", "uac"; + nvidia,function = "rsvd4"; + }; + spig { + nvidia,pins = "spig", "spih"; + nvidia,function = "spi2_alt"; + }; + uaa { + nvidia,pins = "uaa", "uab", "uda"; + nvidia,function = "ulpi"; + }; + uad { + nvidia,pins = "uad"; + nvidia,function = "spdif"; + }; + uca { + nvidia,pins = "uca", "ucb"; + nvidia,function = "uartc"; + }; + conf_ata { + nvidia,pins = "ata", "atb", "atc", "atd", "ate", + "cdev1", "cdev2", "dap1", "dap2", "dtf", + "gma", "gmb", "gmc", "gmd", "gme", + "gpu", "gpu7", "gpv", "i2cp", "pta", + "rm", "sdio1", "slxk", "spdo", "uac", + "uda"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + }; + conf_ck32 { + nvidia,pins = "ck32", "ddrc", "pmca", "pmcb", + "pmcc", "pmcd", "pmce", "xm2c", "xm2d"; + nvidia,pull = <0>; + }; + conf_crtp { + nvidia,pins = "crtp", "dap3", "dap4", "dtb", + "dtc", "dte", "slxa", "slxc", "slxd", + "spdi"; + nvidia,pull = <0>; + nvidia,tristate = <1>; + }; + conf_csus { + nvidia,pins = "csus", "spia", "spib", "spid", + "spif"; + nvidia,pull = <1>; + nvidia,tristate = <1>; + }; + conf_ddc { + nvidia,pins = "ddc", "irrx", "irtx", "kbca", + "kbcb", "kbcc", "kbcd", "kbce", "kbcf", + "spic", "spig", "uaa", "uab"; + nvidia,pull = <2>; + nvidia,tristate = <0>; + }; + conf_dta { + nvidia,pins = "dta", "dtd", "owc", "sdc", "sdd", + "spie", "spih", "uad", "uca", "ucb"; + nvidia,pull = <2>; + nvidia,tristate = <1>; + }; + conf_hdint { + nvidia,pins = "hdint", "ld0", "ld1", "ld2", + "ld3", "ld4", "ld5", "ld6", "ld7", + "ld8", "ld9", "ld10", "ld11", "ld12", + "ld13", "ld14", "ld15", "ld16", "ld17", + "ldc", "ldi", "lhs", "lsc0", "lspi", + "lvs", "pmc"; + nvidia,tristate = <0>; + }; + conf_lc { + nvidia,pins = "lc", "ls"; + nvidia,pull = <2>; + }; + conf_lcsn { + nvidia,pins = "lcsn", "lhp0", "lhp1", "lhp2", + "lm0", "lm1", "lpp", "lpw0", "lpw1", + "lpw2", "lsc1", "lsck", "lsda", "lsdi", + "lvp0", "lvp1", "sdb"; + nvidia,tristate = <1>; + }; + conf_ld17_0 { + nvidia,pins = "ld17_0", "ld19_18", "ld21_20", + "ld23_22"; + nvidia,pull = <1>; + }; + }; + }; };
Signature · 7 lines
1.8.1.4 _______________________________________________ barebox mailing list [email protected] http://lists.infradead.org/mailman/listinfo/barebox
Quoted 21 lines · Lucas Stach
This adds a pinctrl driver for the Tegra 20 line of SoCs. It only supports the three basic pinconfiguration settings function mux, tristate control and pullup/down control.
The driver understands the same devicetree bindings as the Linux one, unimplemented pinconfiguration options will be ignored.
Signed-off-by Lucas Stach <[email protected]>--- arch/arm/dts/tegra20.dtsi | 8 + drivers/pinctrl/Kconfig | 6 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-tegra20.c | 336 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 351 insertions(+) create mode 100644 drivers/pinctrl/pinctrl-tegra20.carch/arm/dts/tegra20.dtsi +0
-0
arch/arm/dts/tegra20.dtsi line 42
Quoted 9 lines
arch/arm/dts/tegra20.dtsi +6
-0@@ -34,6 +34,14 @@ interrupt-controller; }; + pinmux: pinmux { + compatible = "nvidia,tegra20-pinmux"; + reg = <0x70000014 0x10 /* Tri-state registers */ + 0x70000080 0x20 /* Mux registers */ + 0x700000a0 0x14 /* Pull-up/down registers */ + 0x70000868 0xa8>; /* Pad control registers */
tab here
Quoted 10 lines
arch/arm/dts/tegra20.dtsi +2
-0+ }; + pmc { compatible = "nvidia,tegra20-pmc"; reg = <0x7000e400 0x400>;drivers/pinctrl/Kconfig +0
-0
drivers/pinctrl/Kconfig config PINCTRL_IMX_IOMUX_V3 · line 32
Quoted 8 lines
drivers/pinctrl/Kconfig +5
-0@@ -25,4 +25,10 @@ config PINCTRL_IMX_IOMUX_V3 help This iomux controller is found on i.MX25,35,51,53,6. +config PINCTRL_TEGRA20 + select PINCTRL + bool "Tegra 20 pinmux" + help + The pinmux controller found on the Tegra 20 line of SoCs.
pinctrl will be mandatory on tegra
Quoted 170 lines
drivers/pinctrl/Kconfig +1
-0+ endmenudrivers/pinctrl/Makefile +1
-0@@ -2,3 +2,4 @@ obj-$(CONFIG_PINCTRL) += pinctrl.o obj-$(CONFIG_PINCTRL_IMX_IOMUX_V1) += imx-iomux-v1.o obj-$(CONFIG_PINCTRL_IMX_IOMUX_V2) += imx-iomux-v2.o obj-$(CONFIG_PINCTRL_IMX_IOMUX_V3) += imx-iomux-v3.o +obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.odrivers/pinctrl/pinctrl-tegra20.c new file +153
-0@@ -0,0 +1,336 @@ +/* +* Copyright (C) 2013 Lucas Stach <[email protected]> +* +* Partly based on code +* Copyright (C) 2011-2012 NVIDIA Corporation <www.nvidia.com> +* Copyright (C) 2010 Google, Inc. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/** +* @file +* @brief Device driver for the Tegra 20 pincontrol hardware module. +*/ + +#include <common.h> +#include <init.h> +#include <io.h> +#include <pinctrl.h> +#include <malloc.h> + +struct pinctrl_tegra20 { +void __iomem *regs[3 ]; +struct pinctrl_device pinctrl; +}; + +struct tegra20_pingroup { +const char *name; +const char *funcs[4 ]; +s16 trictrl_id; +s16 muxctrl_id; +s16 pullctrl_id; +}; + +#define PG (pg_name, f0, f1, f2, f3, tri, mux, pull) \ + { \ + .name = #pg_name, \ + .funcs = { #f0, #f1, #f2, #f3, }, \ + .trictrl_id = tri, \ + .muxctrl_id = mux, \ + .pullctrl_id = pull \ + } + +static const struct tegra20_pingroup tegra20_groups[] = { +/* name, f0, f1, f2, f3, tri, mux, pull */ +PG (ata, ide, nand, gmi, rsvd4,0 ,12 ,0 ), +PG (atb, ide, nand, gmi, sdio4,1 ,8 ,1 ), +PG (atc, ide, nand, gmi, sdio4,2 ,11 ,2 ), +PG (atd, ide, nand, gmi, sdio4,3 ,10 ,3 ), +PG (ate, ide, nand, gmi, rsvd4,57 ,6 ,4 ), +PG (cdev1, osc, plla_out, pllm_out1, audio_sync,4 ,33 ,32 ), +PG (cdev2, osc, ahb_clk, apb_clk, pllp_out4,5 ,34 ,33 ), +PG (crtp, crt, rsvd2, rsvd3, rsvd4,110 ,105 ,28 ), +PG (csus, pllc_out1, pllp_out2, pllp_out3, vi_sensor_clk,6 ,35 ,60 ), +PG (dap1, dap1, rsvd2, gmi, sdio2,7 ,42 ,5 ), +PG (dap2, dap2, twc, rsvd3, gmi,8 ,43 ,6 ), +PG (dap3, dap3, rsvd2, rsvd3, rsvd4,9 ,44 ,7 ), +PG (dap4, dap4, rsvd2, gmi, rsvd4,10 ,45 ,8 ), +PG (ddc, i2c2, rsvd2, rsvd3, rsvd4,63 ,32 ,78 ), +PG (dta, rsvd1, sdio2, vi, rsvd4,11 ,26 ,9 ), +PG (dtb, rsvd1, rsvd2, vi, spi1,12 ,27 ,10 ), +PG (dtc, rsvd1, rsvd2, vi, rsvd4,13 ,29 ,11 ), +PG (dtd, rsvd1, sdio2, vi, rsvd4,14 ,30 ,12 ), +PG (dte, rsvd1, rsvd2, vi, spi1,15 ,31 ,13 ), +PG (dtf, i2c3, rsvd2, vi, rsvd4,108 ,110 ,14 ), +PG (gma, uarte, spi3, gmi, sdio4,28 ,16 ,74 ), +PG (gmb, ide, nand, gmi, gmi_int,61 ,46 ,75 ), +PG (gmc, uartd, spi4, gmi, sflash,29 ,17 ,76 ), +PG (gmd, rsvd1, nand, gmi, sflash,62 ,47 ,77 ), +PG (gme, rsvd1, dap5, gmi, sdio4,32 ,48 ,44 ), +PG (gpu, pwm, uarta, gmi, rsvd4,16 ,50 ,26 ), +PG (gpu7, rtck, rsvd2, rsvd3, rsvd4,107 ,109 ,19 ), +PG (gpv, pcie, rsvd2, rsvd3, rsvd4,17 ,49 ,15 ), +PG (hdint, hdmi, rsvd2, rsvd3, rsvd4,87 ,18 ,-1 ), +PG (i2cp, i2cp, rsvd2, rsvd3, rsvd4,18 ,36 ,17 ), +PG (irrx, uarta, uartb, gmi, spi4,20 ,41 ,43 ), +PG (irtx, uarta, uartb, gmi, spi4,19 ,40 ,42 ), +PG (kbca, kbc, nand, sdio2, emc_test0_dll,22 ,37 ,20 ), +PG (kbcb, kbc, nand, sdio2, mio,21 ,38 ,21 ), +PG (kbcc, kbc, nand, trace, emc_test1_dll,58 ,39 ,22 ), +PG (kbcd, kbc, nand, sdio2, mio,106 ,108 ,23 ), +PG (kbce, kbc, nand, owr, rsvd4,26 ,14 ,65 ), +PG (kbcf, kbc, nand, trace, mio,27 ,13 ,64 ), +PG (lcsn, displaya, displayb, spi3, rsvd4,95 ,70 ,-1 ), +PG (ld0, displaya, displayb, xio, rsvd4,64 ,80 ,-1 ), +PG (ld1, displaya, displayb, xio, rsvd4,65 ,81 ,-1 ), +PG (ld2, displaya, displayb, xio, rsvd4,66 ,82 ,-1 ), +PG (ld3, displaya, displayb, xio, rsvd4,67 ,83 ,-1 ), +PG (ld4, displaya, displayb, xio, rsvd4,68 ,84 ,-1 ), +PG (ld5, displaya, displayb, xio, rsvd4,69 ,85 ,-1 ), +PG (ld6, displaya, displayb, xio, rsvd4,70 ,86 ,-1 ), +PG (ld7, displaya, displayb, xio, rsvd4,71 ,87 ,-1 ), +PG (ld8, displaya, displayb, xio, rsvd4,72 ,88 ,-1 ), +PG (ld9, displaya, displayb, xio, rsvd4,73 ,89 ,-1 ), +PG (ld10, displaya, displayb, xio, rsvd4,74 ,90 ,-1 ), +PG (ld11, displaya, displayb, xio, rsvd4,75 ,91 ,-1 ), +PG (ld12, displaya, displayb, xio, rsvd4,76 ,92 ,-1 ), +PG (ld13, displaya, displayb, xio, rsvd4,77 ,93 ,-1 ), +PG (ld14, displaya, displayb, xio, rsvd4,78 ,94 ,-1 ), +PG (ld15, displaya, displayb, xio, rsvd4,79 ,95 ,-1 ), +PG (ld16, displaya, displayb, xio, rsvd4,80 ,96 ,-1 ), +PG (ld17, displaya, displayb, rsvd3, rsvd4,81 ,97 ,-1 ), +PG (ldc, displaya, displayb, rsvd3, rsvd4,94 ,71 ,-1 ), +PG (ldi, displaya, displayb, rsvd3, rsvd4,102 ,104 ,-1 ), +PG (lhp0, displaya, displayb, rsvd3, rsvd4,82 ,101 ,-1 ), +PG (lhp1, displaya, displayb, rsvd3, rsvd4,83 ,98 ,-1 ), +PG (lhp2, displaya, displayb, rsvd3, rsvd4,84 ,99 ,-1 ), +PG (lhs, displaya, displayb, xio, rsvd4,103 ,75 ,-1 ), +PG (lm0, displaya, displayb, spi3, rsvd4,88 ,77 ,-1 ), +PG (lm1, displaya, displayb, rsvd3,CRT ,89 ,78 ,-1 ), +PG (lpp, displaya, displayb, rsvd3, rsvd4,104 ,103 ,-1 ), +PG (lpw0, displaya, displayb, spi3, hdmi,99 ,64 ,-1 ), +PG (lpw1, displaya, displayb, rsvd3, rsvd4,100 ,65 ,-1 ), +PG (lpw2, displaya, displayb, spi3, hdmi,101 ,66 ,-1 ), +PG (lsc0, displaya, displayb, xio, rsvd4,91 ,73 ,-1 ), +PG (lsc1, displaya, displayb, spi3, hdmi,92 ,74 ,-1 ), +PG (lsck, displaya, displayb, spi3, hdmi,93 ,72 ,-1 ), +PG (lsda, displaya, displayb, spi3, hdmi,97 ,68 ,-1 ), +PG (lsdi, displaya, displayb, spi3, rsvd4,98 ,67 ,-1 ), +PG (lspi, displaya, displayb, xio, hdmi,96 ,69 ,-1 ), +PG (lvp0, displaya, displayb, rsvd3, rsvd4,85 ,79 ,-1 ), +PG (lvp1, displaya, displayb, rsvd3, rsvd4,86 ,100 ,-1 ), +PG (lvs, displaya, displayb, xio, rsvd4,90 ,76 ,-1 ), +PG (owc, owr, rsvd2, rsvd3, rsvd4,31 ,20 ,79 ), +PG (pmc, pwr_on, pwr_intr, rsvd3, rsvd4,23 ,105 ,-1 ), +PG (pta, i2c2, hdmi, gmi, rsvd4,24 ,107 ,18 ), +PG (rm, i2c1, rsvd2, rsvd3, rsvd4,25 ,7 ,16 ), +PG (sdb, uarta, pwm, sdio3, spi2,111 ,53 ,-1 ), +PG (sdc, pwm, twc, sdio3, spi3,33 ,54 ,62 ), +PG (sdd, uarta, pwm, sdio3, spi3,34 ,55 ,63 ), +PG (sdio1, sdio1, rsvd2, uarte, uarta,30 ,15 ,73 ), +PG (slxa, pcie, spi4, sdio3, spi2,36 ,19 ,27 ), +PG (slxc, spdif, spi4, sdio3, spi2,37 ,21 ,29 ), +PG (slxd, spdif, spi4, sdio3, spi2,38 ,22 ,30 ), +PG (slxk, pcie, spi4, sdio3, spi2,39 ,23 ,31 ), +PG (spdi, spdif, rsvd2, i2c1, sdio2,40 ,52 ,24 ), +PG (spdo, spdif, rsvd2, i2c1, sdio2,41 ,51 ,25 ), +PG (spia, spi1, spi2, spi3, gmi,42 ,63 ,34 ), +PG (spib, spi1, spi2, spi3, gmi,43 ,62 ,35 ), +PG (spic, spi1, spi2, spi3, gmi,44 ,61 ,36 ), +PG (spid, spi2, spi1, spi2_alt, gmi,45 ,60 ,37 ), +PG (spie, spi2, spi1, spi2_alt, gmi,46 ,59 ,38 ), +PG (spif, spi3, spi1, spi2, rsvd4,47 ,58 ,39 ),
drivers/pinctrl/pinctrl-tegra20.c line 163
Quoted 10 lines
drivers/pinctrl/pinctrl-tegra20.c new file +10
-0+PG (spig, spi3, spi2, spi2_alt, i2c1,48 ,57 ,40 ), +PG (spih, spi3, spi2, spi2_alt, i2c1,49 ,56 ,41 ), +PG (uaa, spi3, mipi_hs, uarta, ulpi,50 ,0 ,48 ), +PG (uab, spi2, mipi_hs, uarta, ulpi,51 ,1 ,49 ), +PG (uac, owr, rsvd2, rsvd3, rsvd4,52 ,2 ,50 ), +PG (uad, irda, spdif, uarta, spi4,53 ,3 ,51 ), +PG (uca, uartc, rsvd2, gmi, rsvd4,54 ,24 ,52 ), +PG (ucb, uartc, pwm, gmi, rsvd4,55 ,25 ,53 ), + PG(uda, spi1, rsvd2, uartd, ulpi, 109, 4, 72 ), +};
really ugly blob but it's like tegra define so not choice
Quoted 121 lines
drivers/pinctrl/pinctrl-tegra20.c new file +121
-0+ +static void pinctrl_tegra20_set_func (struct pinctrl_tegra20 *ctrl, +int muxctrl_id,int func) +{ +u32 *regaddr = ctrl->regs[1 ]; +u32 reg; +int maskbit; + + regaddr += muxctrl_id >>4 ; + maskbit = (muxctrl_id <<1 ) &0x1f ; + + reg =readl (regaddr); + reg &= ~(0x3 << maskbit); + reg |= func << maskbit; +writel (reg, regaddr); +} + +static void pinctrl_tegra20_set_pull (struct pinctrl_tegra20 *ctrl, +int pullctrl_id,int pull) +{ +u32 *regaddr = ctrl->regs[2 ]; +u32 reg; +int maskbit; + + regaddr += pullctrl_id >>4 ; + maskbit = (pullctrl_id <<1 ) &0x1f ; + + reg =readl (regaddr); + reg &= ~(0x3 << maskbit); + reg |= pull << maskbit; +writel (reg, regaddr); +} + +static void pinctrl_tegra20_set_tristate (struct pinctrl_tegra20 *ctrl, +int trictrl_id,int tristate) +{ +u32 *regaddr = ctrl->regs[0 ]; +u32 reg; +int maskbit; + + regaddr += trictrl_id >>5 ; + maskbit = trictrl_id &0x1f ; + + reg =readl (regaddr); + reg &= ~(1 << maskbit); + reg |= tristate << maskbit; +writel (reg, regaddr); +} + +static int pinctrl_tegra20_set_state (struct pinctrl_device *pdev, +struct device_node *np) +{ +struct pinctrl_tegra20 *ctrl = + container_of(pdev, struct pinctrl_tegra20, pinctrl); +struct device_node *childnode; +int pull =-1 , tri =-1 , i, j, k; +const char *pins, *func =NULL ; +const struct tegra20_pingroup *group; + +/* +* At first look if the node we are pointed at has children, +* which we may want to visit. +*/ +list_for_each_entry (childnode, &np->children, parent_list) +pinctrl_tegra20_set_state (pdev, childnode); + +/* read relevant state from devicetree */ +of_property_read_string (np,"nvidia,function" , &func); +of_property_read_u32_array (np,"nvidia,pull" , &pull,1 ); +of_property_read_u32_array (np,"nvidia,tristate" , &tri,1 ); + +/* iterate over all pingroups referenced in the dt node */ +for (i =0 ; ; i++) { +if (of_property_read_string_index (np,"nvidia,pins" , i, &pins)) +break ; + +for (j =0 ; j <ARRAY_SIZE (tegra20_groups); j++) { +if (!strcmp (pins, tegra20_groups[j].name)) { + group = &tegra20_groups[j]; +break ; + } + } +/* if no matching pingroup is found bail out */ +if (j ==ARRAY_SIZE (tegra20_groups)) { +dev_warn (ctrl->pinctrl.dev, +"invalid pingroup %s referenced in node %s\n" , + pins, np->name); +continue ; + } + +if (func) { +for (k =0 ; k <4 ; k++) { +if (!strcmp (func, group->funcs[k])) +break ; + } +if (k <4 ) +pinctrl_tegra20_set_func (ctrl, + group->muxctrl_id, k); +else +dev_warn (ctrl->pinctrl.dev, +"invalid function %s for pingroup %s in node %s\n" , + func, group->name, np->name); + } + +if (pull >=0 ) { +if (group->pullctrl_id >=0 ) +pinctrl_tegra20_set_pull (ctrl, + group->pullctrl_id, + pull); +else +dev_warn (ctrl->pinctrl.dev, +"pingroup %s in node %s doesn't support pull configuration\n" , + group->name, np->name); + } + +if (tri >=0 ) +pinctrl_tegra20_set_tristate (ctrl, + group->trictrl_id, tri); + } + +return 0 ;
drivers/pinctrl/pinctrl-tegra20.c line 294
Quoted 10 lines
drivers/pinctrl/pinctrl-tegra20.c new file +10
-0+} + +static struct pinctrl_ops pinctrl_tegra20_ops = { + .set_state = pinctrl_tegra20_set_state, +}; + +static int pinctrl_tegra20_probe (struct device_d *dev) +{ +struct pinctrl_tegra20 *ctrl; +int i, ret =0 ;
no need the init of ret
drivers/pinctrl/pinctrl-tegra20.c line 306
Quoted 12 lines
drivers/pinctrl/pinctrl-tegra20.c new file +12
-0+ + ctrl =xzalloc (sizeof (*ctrl)); + +/* +* Tegra pincontrol is split out into four independent memory ranges: +* tristate control, function mux, pullup/down control, pad control +* (from lowest to highest hardware address). +* We are only interested in the first three for now. +*/ +for (i =0 ; i <=2 ; i++) { + ctrl->regs[i] =dev_request_mem_region (dev, i); + }
drop {}
but use a specific name will simplify debug
and make the code easier
drivers/pinctrl/pinctrl-tegra20.c line 313
Quoted 7 lines
drivers/pinctrl/pinctrl-tegra20.c new file +7
-0+ + ctrl->pinctrl.dev = dev; + ctrl->pinctrl.ops = &pinctrl_tegra20_ops; + + ret =pinctrl_register (&ctrl->pinctrl); +if (ret) +free (ctrl);
report an error message
drivers/pinctrl/pinctrl-tegra20.c line 314
Quoted 1 line
drivers/pinctrl/pinctrl-tegra20.c new file +1
-0+
we sould handle probe defer too
Quoted 30 lines
drivers/pinctrl/pinctrl-tegra20.c new file +22
-0+return ret; +} + +static __maybe_unused struct of_device_id pinctrl_tegra20_dt_ids[] = { + { + .compatible ="nvidia,tegra20-pinmux" , + }, { +/* sentinel */ + } +}; + +static struct driver_d pinctrl_tegra20_driver = { + .name ="pinctrl-tegra20" , + .probe = pinctrl_tegra20_probe, + .of_compatible =DRV_OF_COMPAT (pinctrl_tegra20_dt_ids), +}; + +static int pinctrl_tegra20_init (void ) +{ +return platform_driver_register (&pinctrl_tegra20_driver); +} +postcore_initcall (pinctrl_tegra20_init);Signature · 7 lines
1.8.1.4 _______________________________________________ barebox mailing list [email protected] http://lists.infradead.org/mailman/listinfo/barebox
_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
Quoted 10 lines · Jean-Christophe PLAGNIOL-VILLARD
drivers/pinctrl/pinctrl-tegra20.c line 294
Quoted 9 lines
drivers/pinctrl/pinctrl-tegra20.c new file +9
-0+ +static struct pinctrl_ops pinctrl_tegra20_ops = { + .set_state = pinctrl_tegra20_set_state, +}; + +static int pinctrl_tegra20_probe (struct device_d *dev) +{ +struct pinctrl_tegra20 *ctrl; +int i, ret =0 ;no need the init of ret
Quoted 11 lines
drivers/pinctrl/pinctrl-tegra20.c line 305
Quoted 11 lines
drivers/pinctrl/pinctrl-tegra20.c new file +11
-0+ + ctrl =xzalloc (sizeof (*ctrl)); + +/* +* Tegra pincontrol is split out into four independent memory ranges: +* tristate control, function mux, pullup/down control, pad control +* (from lowest to highest hardware address). +* We are only interested in the first three for now. +*/ +for (i =0 ; i <=2 ; i++) { + ctrl->regs[i] =dev_request_mem_region (dev, i);
The return values of dev_request_mem_region should be checked for new drivers. I know 98% of the code currently does not do this and it was a mistake. The above may fail if regions overlap or there are other bugs in the devicetree. Having this silently fail means that the actual register accesses do a NULL pointer deref later.
Quoted 4 lines
Review
Quoted 1 line
(quoted diff) +1
-0+ }drop {}
but use a specific name will simplify debug
I don't think this should be mandatory.
Quoted 10 lines
and make the code easier
drivers/pinctrl/pinctrl-tegra20.c line 313
Quoted 7 lines
drivers/pinctrl/pinctrl-tegra20.c new file +7
-0+ + ctrl->pinctrl.dev = dev; + ctrl->pinctrl.ops = &pinctrl_tegra20_ops; + + ret =pinctrl_register (&ctrl->pinctrl); +if (ret) +free (ctrl);report an error message
The core will answer with an error message here. There is no need to litter the code with error messages which only add to the binary size. The above may fail for a developer but really should not fail for a user. A developer has enough information with the probe functions error code.
Sascha
Signature · 9 lines
Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list [email protected] http://lists.infradead.org/mailman/listinfo/barebox
Quoted 20 lines · Sascha Hauer
Quoted 19 lines · Jean-Christophe PLAGNIOL-VILLARD
drivers/pinctrl/pinctrl-tegra20.c line 294
Quoted 9 lines
drivers/pinctrl/pinctrl-tegra20.c new file +9
-0+ +static struct pinctrl_ops pinctrl_tegra20_ops = { + .set_state = pinctrl_tegra20_set_state, +}; + +static int pinctrl_tegra20_probe (struct device_d *dev) +{ +struct pinctrl_tegra20 *ctrl; +int i, ret =0 ;no need the init of ret
Quoted 9 lines
drivers/pinctrl/pinctrl-tegra20.c new file +9
-0+ + ctrl =xzalloc (sizeof (*ctrl)); + +/* +* Tegra pincontrol is split out into four independent memory ranges: +* tristate control, function mux, pullup/down control, pad control +* (from lowest to highest hardware address). +* We are only interested in the first three for now. +*/
Quoted 8 lines
Quoted 2 lines
drivers/pinctrl/pinctrl-tegra20.c line 305
Quoted 2 lines
drivers/pinctrl/pinctrl-tegra20.c new file +2
-0+for (i =0 ; i <=2 ; i++) { + ctrl->regs[i] =dev_request_mem_region (dev, i);The return values of
dev_request_mem_regionshould be checked for new drivers. I know 98% of the code currently does not do this and it was a mistake. The above may fail if regions overlap or there are other bugs in the devicetree. Having this silently fail means that the actual register accesses do a NULL pointer deref later.
why not simply put a BUG in the request_mem
Quoted 7 lines
Quoted 5 lines
Review
Quoted 2 lines
(quoted diff) +1
-0+ }drop {}
but use a specific name will simplify debug
I don't think this should be mandatory.
the issue is that a number can be easly endup to a hiden typo (no compile error) where a ttypo in the name will no compile.
Quoted 12 lines
Quoted 11 lines
and make the code easier
drivers/pinctrl/pinctrl-tegra20.c line 313
Quoted 7 lines
drivers/pinctrl/pinctrl-tegra20.c new file +7
-0+ + ctrl->pinctrl.dev = dev; + ctrl->pinctrl.ops = &pinctrl_tegra20_ops; + + ret =pinctrl_register (&ctrl->pinctrl); +if (ret) +free (ctrl);report an error message
Quoted 4 lines
The core will answer with an error message here. There is no need to litter the code with error messages which only add to the binary size. The above may fail for a developer but really should not fail for a user. A developer has enough information with the probe functions error code.
pinctrl_register print no error message
it's good to known why we failled no just that the probe return -Exxx
and this will not impact the binary size if we put a dev_warn or dev_debug
as we can drop them with the printk level
_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
Quoted 25 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 24 lines · Lucas Stach
This adds a pinctrl driver for the Tegra 20 line of SoCs. It only supports the three basic pinconfiguration settings function mux, tristate control and pullup/down control.
The driver understands the same devicetree bindings as the Linux one, unimplemented pinconfiguration options will be ignored.
Signed-off-by Lucas Stach <[email protected]>--- arch/arm/dts/tegra20.dtsi | 8 + drivers/pinctrl/Kconfig | 6 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-tegra20.c | 336 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 351 insertions(+) create mode 100644 drivers/pinctrl/pinctrl-tegra20.carch/arm/dts/tegra20.dtsi +0
-0@@ -34,6 +34,14 @@ interrupt-controller; };
Quoted 7 lines
arch/arm/dts/tegra20.dtsi line 42
Quoted 6 lines
arch/arm/dts/tegra20.dtsi +6
-0+ pinmux: pinmux { + compatible = "nvidia,tegra20-pinmux"; + reg = <0x70000014 0x10 /* Tri-state registers */ + 0x70000080 0x20 /* Mux registers */ + 0x700000a0 0x14 /* Pull-up/down registers */ + 0x70000868 0xa8>; /* Pad control registers */tab here
This is done to align under the lines above. I wouldn't do it in my code, but it's perfectly fine to do it.
Quoted 13 lines
Quoted 13 lines
arch/arm/dts/tegra20.dtsi +2
-0+ }; + pmc { compatible = "nvidia,tegra20-pmc"; reg = <0x7000e400 0x400>;drivers/pinctrl/Kconfig +0
-0@@ -25,4 +25,10 @@ config PINCTRL_IMX_IOMUX_V3 help This iomux controller is found on i.MX25,35,51,53,6.
Quoted 6 lines
drivers/pinctrl/Kconfig config PINCTRL_IMX_IOMUX_V3 · line 32
Quoted 5 lines
drivers/pinctrl/Kconfig +5
-0+config PINCTRL_TEGRA20 + select PINCTRL + bool "Tegra 20 pinmux" + help + The pinmux controller found on the Tegra 20 line of SoCs.pinctrl will be mandatory on tegra
It will, yes, but no need to do it now. There can well be some time to test the driver before it becomes mandatory.
Sascha
Signature · 9 lines
Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list [email protected] http://lists.infradead.org/mailman/listinfo/barebox