aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/pinctrl-tz1090.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl/pinctrl-tz1090.c')
-rw-r--r--drivers/pinctrl/pinctrl-tz1090.c140
1 files changed, 80 insertions, 60 deletions
diff --git a/drivers/pinctrl/pinctrl-tz1090.c b/drivers/pinctrl/pinctrl-tz1090.c
index 72d955252e41..bc9cd7a7602e 100644
--- a/drivers/pinctrl/pinctrl-tz1090.c
+++ b/drivers/pinctrl/pinctrl-tz1090.c
@@ -1762,39 +1762,46 @@ static int tz1090_pinconf_get(struct pinctrl_dev *pctldev,
1762} 1762}
1763 1763
1764static int tz1090_pinconf_set(struct pinctrl_dev *pctldev, 1764static int tz1090_pinconf_set(struct pinctrl_dev *pctldev,
1765 unsigned int pin, unsigned long config) 1765 unsigned int pin, unsigned long *configs,
1766 unsigned num_configs)
1766{ 1767{
1767 struct tz1090_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 1768 struct tz1090_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
1768 enum pin_config_param param = pinconf_to_config_param(config); 1769 enum pin_config_param param;
1769 unsigned int arg = pinconf_to_config_argument(config); 1770 unsigned int arg;
1770 int ret; 1771 int ret;
1771 u32 reg, width, mask, shift, val, tmp; 1772 u32 reg, width, mask, shift, val, tmp;
1772 unsigned long flags; 1773 unsigned long flags;
1774 int i;
1773 1775
1774 dev_dbg(pctldev->dev, "%s(pin=%s, config=%#lx)\n", 1776 for (i = 0; i < num_configs; i++) {
1775 __func__, tz1090_pins[pin].name, config); 1777 param = pinconf_to_config_param(configs[i]);
1778 arg = pinconf_to_config_argument(configs[i]);
1776 1779
1777 /* Get register information */ 1780 dev_dbg(pctldev->dev, "%s(pin=%s, config=%#lx)\n",
1778 ret = tz1090_pinconf_reg(pctldev, pin, param, true, 1781 __func__, tz1090_pins[pin].name, configs[i]);
1779 &reg, &width, &mask, &shift, &val);
1780 if (ret < 0)
1781 return ret;
1782 1782
1783 /* Unpack argument and range check it */ 1783 /* Get register information */
1784 if (arg > 1) { 1784 ret = tz1090_pinconf_reg(pctldev, pin, param, true,
1785 dev_dbg(pctldev->dev, "%s: arg %u out of range\n", 1785 &reg, &width, &mask, &shift, &val);
1786 __func__, arg); 1786 if (ret < 0)
1787 return -EINVAL; 1787 return ret;
1788 }
1789 1788
1790 /* Write register field */ 1789 /* Unpack argument and range check it */
1791 __global_lock2(flags); 1790 if (arg > 1) {
1792 tmp = pmx_read(pmx, reg); 1791 dev_dbg(pctldev->dev, "%s: arg %u out of range\n",
1793 tmp &= ~mask; 1792 __func__, arg);
1794 if (arg) 1793 return -EINVAL;
1795 tmp |= val << shift; 1794 }
1796 pmx_write(pmx, tmp, reg); 1795
1797 __global_unlock2(flags); 1796 /* Write register field */
1797 __global_lock2(flags);
1798 tmp = pmx_read(pmx, reg);
1799 tmp &= ~mask;
1800 if (arg)
1801 tmp |= val << shift;
1802 pmx_write(pmx, tmp, reg);
1803 __global_unlock2(flags);
1804 } /* for each config */
1798 1805
1799 return 0; 1806 return 0;
1800} 1807}
@@ -1894,68 +1901,81 @@ static int tz1090_pinconf_group_get(struct pinctrl_dev *pctldev,
1894} 1901}
1895 1902
1896static int tz1090_pinconf_group_set(struct pinctrl_dev *pctldev, 1903static int tz1090_pinconf_group_set(struct pinctrl_dev *pctldev,
1897 unsigned int group, unsigned long config) 1904 unsigned int group, unsigned long *configs,
1905 unsigned num_configs)
1898{ 1906{
1899 struct tz1090_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 1907 struct tz1090_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
1900 const struct tz1090_pingroup *g; 1908 const struct tz1090_pingroup *g;
1901 enum pin_config_param param = pinconf_to_config_param(config); 1909 enum pin_config_param param;
1902 unsigned int arg, pin, i; 1910 unsigned int arg, pin, i;
1903 const unsigned int *pit; 1911 const unsigned int *pit;
1904 int ret; 1912 int ret;
1905 u32 reg, width, mask, shift, val; 1913 u32 reg, width, mask, shift, val;
1906 unsigned long flags; 1914 unsigned long flags;
1907 const int *map; 1915 const int *map;
1916 int j;
1908 1917
1909 if (group >= ARRAY_SIZE(tz1090_groups)) { 1918 if (group >= ARRAY_SIZE(tz1090_groups)) {
1910 pin = group - ARRAY_SIZE(tz1090_groups); 1919 pin = group - ARRAY_SIZE(tz1090_groups);
1911 return tz1090_pinconf_set(pctldev, pin, config); 1920 return tz1090_pinconf_set(pctldev, pin, configs, num_configs);
1912 } 1921 }
1913 1922
1914 g = &tz1090_groups[group]; 1923 g = &tz1090_groups[group];
1915 if (g->npins == 1) { 1924 if (g->npins == 1) {
1916 pin = g->pins[0]; 1925 pin = g->pins[0];
1917 ret = tz1090_pinconf_set(pctldev, pin, config); 1926 ret = tz1090_pinconf_set(pctldev, pin, configs, num_configs);
1918 if (ret != -ENOTSUPP) 1927 if (ret != -ENOTSUPP)
1919 return ret; 1928 return ret;
1920 } 1929 }
1921 1930
1922 dev_dbg(pctldev->dev, "%s(group=%s, config=%#lx)\n", 1931 for (j = 0; j < num_configs; j++) {
1923 __func__, g->name, config); 1932 param = pinconf_to_config_param(configs[j]);
1924 1933
1925 /* Get register information */ 1934 dev_dbg(pctldev->dev, "%s(group=%s, config=%#lx)\n",
1926 ret = tz1090_pinconf_group_reg(pctldev, g, param, true, 1935 __func__, g->name, configs[j]);
1927 &reg, &width, &mask, &shift, &map);
1928 if (ret < 0) {
1929 /*
1930 * Maybe we're trying to set a per-pin configuration of a group,
1931 * so do the pins one by one. This is mainly as a convenience.
1932 */
1933 for (i = 0, pit = g->pins; i < g->npins; ++i, ++pit) {
1934 ret = tz1090_pinconf_set(pctldev, *pit, config);
1935 if (ret)
1936 return ret;
1937 }
1938 return 0;
1939 }
1940 1936
1941 /* Unpack argument and map it to register value */ 1937 /* Get register information */
1942 arg = pinconf_to_config_argument(config); 1938 ret = tz1090_pinconf_group_reg(pctldev, g, param, true, &reg,
1943 for (i = 0; i < BIT(width); ++i) { 1939 &width, &mask, &shift, &map);
1944 if (map[i] == arg || (map[i] == -EINVAL && !arg)) { 1940 if (ret < 0) {
1945 /* Write register field */ 1941 /*
1946 __global_lock2(flags); 1942 * Maybe we're trying to set a per-pin configuration
1947 val = pmx_read(pmx, reg); 1943 * of a group, so do the pins one by one. This is
1948 val &= ~mask; 1944 * mainly as a convenience.
1949 val |= i << shift; 1945 */
1950 pmx_write(pmx, val, reg); 1946 for (i = 0, pit = g->pins; i < g->npins; ++i, ++pit) {
1951 __global_unlock2(flags); 1947 ret = tz1090_pinconf_set(pctldev, *pit, configs,
1948 num_configs);
1949 if (ret)
1950 return ret;
1951 }
1952 return 0; 1952 return 0;
1953 } 1953 }
1954 }
1955 1954
1956 dev_dbg(pctldev->dev, "%s: arg %u not supported\n", 1955 /* Unpack argument and map it to register value */
1957 __func__, arg); 1956 arg = pinconf_to_config_argument(configs[j]);
1958 return -EINVAL; 1957 for (i = 0; i < BIT(width); ++i) {
1958 if (map[i] == arg || (map[i] == -EINVAL && !arg)) {
1959 /* Write register field */
1960 __global_lock2(flags);
1961 val = pmx_read(pmx, reg);
1962 val &= ~mask;
1963 val |= i << shift;
1964 pmx_write(pmx, val, reg);
1965 __global_unlock2(flags);
1966 goto next_config;
1967 }
1968 }
1969
1970 dev_dbg(pctldev->dev, "%s: arg %u not supported\n",
1971 __func__, arg);
1972 return -EINVAL;
1973
1974next_config:
1975 ;
1976 } /* for each config */
1977
1978 return 0;
1959} 1979}
1960 1980
1961static struct pinconf_ops tz1090_pinconf_ops = { 1981static struct pinconf_ops tz1090_pinconf_ops = {