1*79433559SRaag Jadav // SPDX-License-Identifier: GPL-2.0-only
2*79433559SRaag Jadav /*
3*79433559SRaag Jadav * Intel Tangier pinctrl driver
4*79433559SRaag Jadav *
5*79433559SRaag Jadav * Copyright (C) 2016, 2023 Intel Corporation
6*79433559SRaag Jadav *
7*79433559SRaag Jadav * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
8*79433559SRaag Jadav * Raag Jadav <raag.jadav@intel.com>
9*79433559SRaag Jadav */
10*79433559SRaag Jadav
11*79433559SRaag Jadav #include <linux/bits.h>
12*79433559SRaag Jadav #include <linux/device.h>
13*79433559SRaag Jadav #include <linux/err.h>
14*79433559SRaag Jadav #include <linux/errno.h>
15*79433559SRaag Jadav #include <linux/export.h>
16*79433559SRaag Jadav #include <linux/io.h>
17*79433559SRaag Jadav #include <linux/module.h>
18*79433559SRaag Jadav #include <linux/overflow.h>
19*79433559SRaag Jadav #include <linux/platform_device.h>
20*79433559SRaag Jadav #include <linux/property.h>
21*79433559SRaag Jadav #include <linux/seq_file.h>
22*79433559SRaag Jadav #include <linux/spinlock.h>
23*79433559SRaag Jadav #include <linux/types.h>
24*79433559SRaag Jadav
25*79433559SRaag Jadav #include <linux/pinctrl/pinconf-generic.h>
26*79433559SRaag Jadav #include <linux/pinctrl/pinconf.h>
27*79433559SRaag Jadav #include <linux/pinctrl/pinctrl.h>
28*79433559SRaag Jadav #include <linux/pinctrl/pinmux.h>
29*79433559SRaag Jadav
30*79433559SRaag Jadav #include "../core.h"
31*79433559SRaag Jadav #include "pinctrl-intel.h"
32*79433559SRaag Jadav #include "pinctrl-tangier.h"
33*79433559SRaag Jadav
34*79433559SRaag Jadav #define SLEW_OFFSET 0x000
35*79433559SRaag Jadav #define BUFCFG_OFFSET 0x100
36*79433559SRaag Jadav #define MISC_OFFSET 0x300
37*79433559SRaag Jadav
38*79433559SRaag Jadav #define BUFCFG_PINMODE_SHIFT 0
39*79433559SRaag Jadav #define BUFCFG_PINMODE_MASK GENMASK(2, 0)
40*79433559SRaag Jadav #define BUFCFG_PINMODE_GPIO 0
41*79433559SRaag Jadav #define BUFCFG_PUPD_VAL_SHIFT 4
42*79433559SRaag Jadav #define BUFCFG_PUPD_VAL_MASK GENMASK(5, 4)
43*79433559SRaag Jadav #define BUFCFG_PUPD_VAL_2K 0
44*79433559SRaag Jadav #define BUFCFG_PUPD_VAL_20K 1
45*79433559SRaag Jadav #define BUFCFG_PUPD_VAL_50K 2
46*79433559SRaag Jadav #define BUFCFG_PUPD_VAL_910 3
47*79433559SRaag Jadav #define BUFCFG_PU_EN BIT(8)
48*79433559SRaag Jadav #define BUFCFG_PD_EN BIT(9)
49*79433559SRaag Jadav #define BUFCFG_Px_EN_MASK GENMASK(9, 8)
50*79433559SRaag Jadav #define BUFCFG_SLEWSEL BIT(10)
51*79433559SRaag Jadav #define BUFCFG_OVINEN BIT(12)
52*79433559SRaag Jadav #define BUFCFG_OVINEN_EN BIT(13)
53*79433559SRaag Jadav #define BUFCFG_OVINEN_MASK GENMASK(13, 12)
54*79433559SRaag Jadav #define BUFCFG_OVOUTEN BIT(14)
55*79433559SRaag Jadav #define BUFCFG_OVOUTEN_EN BIT(15)
56*79433559SRaag Jadav #define BUFCFG_OVOUTEN_MASK GENMASK(15, 14)
57*79433559SRaag Jadav #define BUFCFG_INDATAOV_VAL BIT(16)
58*79433559SRaag Jadav #define BUFCFG_INDATAOV_EN BIT(17)
59*79433559SRaag Jadav #define BUFCFG_INDATAOV_MASK GENMASK(17, 16)
60*79433559SRaag Jadav #define BUFCFG_OUTDATAOV_VAL BIT(18)
61*79433559SRaag Jadav #define BUFCFG_OUTDATAOV_EN BIT(19)
62*79433559SRaag Jadav #define BUFCFG_OUTDATAOV_MASK GENMASK(19, 18)
63*79433559SRaag Jadav #define BUFCFG_OD_EN BIT(21)
64*79433559SRaag Jadav
65*79433559SRaag Jadav #define pin_to_bufno(f, p) ((p) - (f)->pin_base)
66*79433559SRaag Jadav
tng_get_family(struct tng_pinctrl * tp,unsigned int pin)67*79433559SRaag Jadav static const struct tng_family *tng_get_family(struct tng_pinctrl *tp,
68*79433559SRaag Jadav unsigned int pin)
69*79433559SRaag Jadav {
70*79433559SRaag Jadav const struct tng_family *family;
71*79433559SRaag Jadav unsigned int i;
72*79433559SRaag Jadav
73*79433559SRaag Jadav for (i = 0; i < tp->nfamilies; i++) {
74*79433559SRaag Jadav family = &tp->families[i];
75*79433559SRaag Jadav if (pin >= family->pin_base &&
76*79433559SRaag Jadav pin < family->pin_base + family->npins)
77*79433559SRaag Jadav return family;
78*79433559SRaag Jadav }
79*79433559SRaag Jadav
80*79433559SRaag Jadav dev_warn(tp->dev, "failed to find family for pin %u\n", pin);
81*79433559SRaag Jadav return NULL;
82*79433559SRaag Jadav }
83*79433559SRaag Jadav
tng_buf_available(struct tng_pinctrl * tp,unsigned int pin)84*79433559SRaag Jadav static bool tng_buf_available(struct tng_pinctrl *tp, unsigned int pin)
85*79433559SRaag Jadav {
86*79433559SRaag Jadav const struct tng_family *family;
87*79433559SRaag Jadav
88*79433559SRaag Jadav family = tng_get_family(tp, pin);
89*79433559SRaag Jadav if (!family)
90*79433559SRaag Jadav return false;
91*79433559SRaag Jadav
92*79433559SRaag Jadav return !family->protected;
93*79433559SRaag Jadav }
94*79433559SRaag Jadav
tng_get_bufcfg(struct tng_pinctrl * tp,unsigned int pin)95*79433559SRaag Jadav static void __iomem *tng_get_bufcfg(struct tng_pinctrl *tp, unsigned int pin)
96*79433559SRaag Jadav {
97*79433559SRaag Jadav const struct tng_family *family;
98*79433559SRaag Jadav unsigned int bufno;
99*79433559SRaag Jadav
100*79433559SRaag Jadav family = tng_get_family(tp, pin);
101*79433559SRaag Jadav if (!family)
102*79433559SRaag Jadav return NULL;
103*79433559SRaag Jadav
104*79433559SRaag Jadav bufno = pin_to_bufno(family, pin);
105*79433559SRaag Jadav return family->regs + BUFCFG_OFFSET + bufno * 4;
106*79433559SRaag Jadav }
107*79433559SRaag Jadav
tng_read_bufcfg(struct tng_pinctrl * tp,unsigned int pin,u32 * value)108*79433559SRaag Jadav static int tng_read_bufcfg(struct tng_pinctrl *tp, unsigned int pin, u32 *value)
109*79433559SRaag Jadav {
110*79433559SRaag Jadav void __iomem *bufcfg;
111*79433559SRaag Jadav
112*79433559SRaag Jadav if (!tng_buf_available(tp, pin))
113*79433559SRaag Jadav return -EBUSY;
114*79433559SRaag Jadav
115*79433559SRaag Jadav bufcfg = tng_get_bufcfg(tp, pin);
116*79433559SRaag Jadav *value = readl(bufcfg);
117*79433559SRaag Jadav
118*79433559SRaag Jadav return 0;
119*79433559SRaag Jadav }
120*79433559SRaag Jadav
tng_update_bufcfg(struct tng_pinctrl * tp,unsigned int pin,u32 bits,u32 mask)121*79433559SRaag Jadav static void tng_update_bufcfg(struct tng_pinctrl *tp, unsigned int pin,
122*79433559SRaag Jadav u32 bits, u32 mask)
123*79433559SRaag Jadav {
124*79433559SRaag Jadav void __iomem *bufcfg;
125*79433559SRaag Jadav u32 value;
126*79433559SRaag Jadav
127*79433559SRaag Jadav bufcfg = tng_get_bufcfg(tp, pin);
128*79433559SRaag Jadav
129*79433559SRaag Jadav value = readl(bufcfg);
130*79433559SRaag Jadav value = (value & ~mask) | (bits & mask);
131*79433559SRaag Jadav writel(value, bufcfg);
132*79433559SRaag Jadav }
133*79433559SRaag Jadav
tng_get_groups_count(struct pinctrl_dev * pctldev)134*79433559SRaag Jadav static int tng_get_groups_count(struct pinctrl_dev *pctldev)
135*79433559SRaag Jadav {
136*79433559SRaag Jadav struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);
137*79433559SRaag Jadav
138*79433559SRaag Jadav return tp->ngroups;
139*79433559SRaag Jadav }
140*79433559SRaag Jadav
tng_get_group_name(struct pinctrl_dev * pctldev,unsigned int group)141*79433559SRaag Jadav static const char *tng_get_group_name(struct pinctrl_dev *pctldev,
142*79433559SRaag Jadav unsigned int group)
143*79433559SRaag Jadav {
144*79433559SRaag Jadav struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);
145*79433559SRaag Jadav
146*79433559SRaag Jadav return tp->groups[group].grp.name;
147*79433559SRaag Jadav }
148*79433559SRaag Jadav
tng_get_group_pins(struct pinctrl_dev * pctldev,unsigned int group,const unsigned int ** pins,unsigned int * npins)149*79433559SRaag Jadav static int tng_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group,
150*79433559SRaag Jadav const unsigned int **pins, unsigned int *npins)
151*79433559SRaag Jadav {
152*79433559SRaag Jadav struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);
153*79433559SRaag Jadav
154*79433559SRaag Jadav *pins = tp->groups[group].grp.pins;
155*79433559SRaag Jadav *npins = tp->groups[group].grp.npins;
156*79433559SRaag Jadav return 0;
157*79433559SRaag Jadav }
158*79433559SRaag Jadav
tng_pin_dbg_show(struct pinctrl_dev * pctldev,struct seq_file * s,unsigned int pin)159*79433559SRaag Jadav static void tng_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
160*79433559SRaag Jadav unsigned int pin)
161*79433559SRaag Jadav {
162*79433559SRaag Jadav struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);
163*79433559SRaag Jadav u32 value, mode;
164*79433559SRaag Jadav int ret;
165*79433559SRaag Jadav
166*79433559SRaag Jadav ret = tng_read_bufcfg(tp, pin, &value);
167*79433559SRaag Jadav if (ret) {
168*79433559SRaag Jadav seq_puts(s, "not available");
169*79433559SRaag Jadav return;
170*79433559SRaag Jadav }
171*79433559SRaag Jadav
172*79433559SRaag Jadav mode = (value & BUFCFG_PINMODE_MASK) >> BUFCFG_PINMODE_SHIFT;
173*79433559SRaag Jadav if (mode == BUFCFG_PINMODE_GPIO)
174*79433559SRaag Jadav seq_puts(s, "GPIO ");
175*79433559SRaag Jadav else
176*79433559SRaag Jadav seq_printf(s, "mode %d ", mode);
177*79433559SRaag Jadav
178*79433559SRaag Jadav seq_printf(s, "0x%08x", value);
179*79433559SRaag Jadav }
180*79433559SRaag Jadav
181*79433559SRaag Jadav static const struct pinctrl_ops tng_pinctrl_ops = {
182*79433559SRaag Jadav .get_groups_count = tng_get_groups_count,
183*79433559SRaag Jadav .get_group_name = tng_get_group_name,
184*79433559SRaag Jadav .get_group_pins = tng_get_group_pins,
185*79433559SRaag Jadav .pin_dbg_show = tng_pin_dbg_show,
186*79433559SRaag Jadav };
187*79433559SRaag Jadav
tng_get_functions_count(struct pinctrl_dev * pctldev)188*79433559SRaag Jadav static int tng_get_functions_count(struct pinctrl_dev *pctldev)
189*79433559SRaag Jadav {
190*79433559SRaag Jadav struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);
191*79433559SRaag Jadav
192*79433559SRaag Jadav return tp->nfunctions;
193*79433559SRaag Jadav }
194*79433559SRaag Jadav
tng_get_function_name(struct pinctrl_dev * pctldev,unsigned int function)195*79433559SRaag Jadav static const char *tng_get_function_name(struct pinctrl_dev *pctldev,
196*79433559SRaag Jadav unsigned int function)
197*79433559SRaag Jadav {
198*79433559SRaag Jadav struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);
199*79433559SRaag Jadav
200*79433559SRaag Jadav return tp->functions[function].func.name;
201*79433559SRaag Jadav }
202*79433559SRaag Jadav
tng_get_function_groups(struct pinctrl_dev * pctldev,unsigned int function,const char * const ** groups,unsigned int * const ngroups)203*79433559SRaag Jadav static int tng_get_function_groups(struct pinctrl_dev *pctldev,
204*79433559SRaag Jadav unsigned int function,
205*79433559SRaag Jadav const char * const **groups,
206*79433559SRaag Jadav unsigned int * const ngroups)
207*79433559SRaag Jadav {
208*79433559SRaag Jadav struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);
209*79433559SRaag Jadav
210*79433559SRaag Jadav *groups = tp->functions[function].func.groups;
211*79433559SRaag Jadav *ngroups = tp->functions[function].func.ngroups;
212*79433559SRaag Jadav return 0;
213*79433559SRaag Jadav }
214*79433559SRaag Jadav
tng_pinmux_set_mux(struct pinctrl_dev * pctldev,unsigned int function,unsigned int group)215*79433559SRaag Jadav static int tng_pinmux_set_mux(struct pinctrl_dev *pctldev,
216*79433559SRaag Jadav unsigned int function,
217*79433559SRaag Jadav unsigned int group)
218*79433559SRaag Jadav {
219*79433559SRaag Jadav struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);
220*79433559SRaag Jadav const struct intel_pingroup *grp = &tp->groups[group];
221*79433559SRaag Jadav u32 bits = grp->mode << BUFCFG_PINMODE_SHIFT;
222*79433559SRaag Jadav u32 mask = BUFCFG_PINMODE_MASK;
223*79433559SRaag Jadav unsigned long flags;
224*79433559SRaag Jadav unsigned int i;
225*79433559SRaag Jadav
226*79433559SRaag Jadav /*
227*79433559SRaag Jadav * All pins in the groups needs to be accessible and writable
228*79433559SRaag Jadav * before we can enable the mux for this group.
229*79433559SRaag Jadav */
230*79433559SRaag Jadav for (i = 0; i < grp->grp.npins; i++) {
231*79433559SRaag Jadav if (!tng_buf_available(tp, grp->grp.pins[i]))
232*79433559SRaag Jadav return -EBUSY;
233*79433559SRaag Jadav }
234*79433559SRaag Jadav
235*79433559SRaag Jadav /* Now enable the mux setting for each pin in the group */
236*79433559SRaag Jadav raw_spin_lock_irqsave(&tp->lock, flags);
237*79433559SRaag Jadav for (i = 0; i < grp->grp.npins; i++)
238*79433559SRaag Jadav tng_update_bufcfg(tp, grp->grp.pins[i], bits, mask);
239*79433559SRaag Jadav raw_spin_unlock_irqrestore(&tp->lock, flags);
240*79433559SRaag Jadav
241*79433559SRaag Jadav return 0;
242*79433559SRaag Jadav }
243*79433559SRaag Jadav
tng_gpio_request_enable(struct pinctrl_dev * pctldev,struct pinctrl_gpio_range * range,unsigned int pin)244*79433559SRaag Jadav static int tng_gpio_request_enable(struct pinctrl_dev *pctldev,
245*79433559SRaag Jadav struct pinctrl_gpio_range *range,
246*79433559SRaag Jadav unsigned int pin)
247*79433559SRaag Jadav {
248*79433559SRaag Jadav struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);
249*79433559SRaag Jadav u32 bits = BUFCFG_PINMODE_GPIO << BUFCFG_PINMODE_SHIFT;
250*79433559SRaag Jadav u32 mask = BUFCFG_PINMODE_MASK;
251*79433559SRaag Jadav unsigned long flags;
252*79433559SRaag Jadav
253*79433559SRaag Jadav if (!tng_buf_available(tp, pin))
254*79433559SRaag Jadav return -EBUSY;
255*79433559SRaag Jadav
256*79433559SRaag Jadav raw_spin_lock_irqsave(&tp->lock, flags);
257*79433559SRaag Jadav tng_update_bufcfg(tp, pin, bits, mask);
258*79433559SRaag Jadav raw_spin_unlock_irqrestore(&tp->lock, flags);
259*79433559SRaag Jadav
260*79433559SRaag Jadav return 0;
261*79433559SRaag Jadav }
262*79433559SRaag Jadav
263*79433559SRaag Jadav static const struct pinmux_ops tng_pinmux_ops = {
264*79433559SRaag Jadav .get_functions_count = tng_get_functions_count,
265*79433559SRaag Jadav .get_function_name = tng_get_function_name,
266*79433559SRaag Jadav .get_function_groups = tng_get_function_groups,
267*79433559SRaag Jadav .set_mux = tng_pinmux_set_mux,
268*79433559SRaag Jadav .gpio_request_enable = tng_gpio_request_enable,
269*79433559SRaag Jadav };
270*79433559SRaag Jadav
tng_config_get(struct pinctrl_dev * pctldev,unsigned int pin,unsigned long * config)271*79433559SRaag Jadav static int tng_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
272*79433559SRaag Jadav unsigned long *config)
273*79433559SRaag Jadav {
274*79433559SRaag Jadav struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);
275*79433559SRaag Jadav enum pin_config_param param = pinconf_to_config_param(*config);
276*79433559SRaag Jadav u32 value, term;
277*79433559SRaag Jadav u16 arg = 0;
278*79433559SRaag Jadav int ret;
279*79433559SRaag Jadav
280*79433559SRaag Jadav ret = tng_read_bufcfg(tp, pin, &value);
281*79433559SRaag Jadav if (ret)
282*79433559SRaag Jadav return -ENOTSUPP;
283*79433559SRaag Jadav
284*79433559SRaag Jadav term = (value & BUFCFG_PUPD_VAL_MASK) >> BUFCFG_PUPD_VAL_SHIFT;
285*79433559SRaag Jadav
286*79433559SRaag Jadav switch (param) {
287*79433559SRaag Jadav case PIN_CONFIG_BIAS_DISABLE:
288*79433559SRaag Jadav if (value & BUFCFG_Px_EN_MASK)
289*79433559SRaag Jadav return -EINVAL;
290*79433559SRaag Jadav break;
291*79433559SRaag Jadav
292*79433559SRaag Jadav case PIN_CONFIG_BIAS_PULL_UP:
293*79433559SRaag Jadav if ((value & BUFCFG_Px_EN_MASK) != BUFCFG_PU_EN)
294*79433559SRaag Jadav return -EINVAL;
295*79433559SRaag Jadav
296*79433559SRaag Jadav switch (term) {
297*79433559SRaag Jadav case BUFCFG_PUPD_VAL_910:
298*79433559SRaag Jadav arg = 910;
299*79433559SRaag Jadav break;
300*79433559SRaag Jadav case BUFCFG_PUPD_VAL_2K:
301*79433559SRaag Jadav arg = 2000;
302*79433559SRaag Jadav break;
303*79433559SRaag Jadav case BUFCFG_PUPD_VAL_20K:
304*79433559SRaag Jadav arg = 20000;
305*79433559SRaag Jadav break;
306*79433559SRaag Jadav case BUFCFG_PUPD_VAL_50K:
307*79433559SRaag Jadav arg = 50000;
308*79433559SRaag Jadav break;
309*79433559SRaag Jadav }
310*79433559SRaag Jadav
311*79433559SRaag Jadav break;
312*79433559SRaag Jadav
313*79433559SRaag Jadav case PIN_CONFIG_BIAS_PULL_DOWN:
314*79433559SRaag Jadav if ((value & BUFCFG_Px_EN_MASK) != BUFCFG_PD_EN)
315*79433559SRaag Jadav return -EINVAL;
316*79433559SRaag Jadav
317*79433559SRaag Jadav switch (term) {
318*79433559SRaag Jadav case BUFCFG_PUPD_VAL_910:
319*79433559SRaag Jadav arg = 910;
320*79433559SRaag Jadav break;
321*79433559SRaag Jadav case BUFCFG_PUPD_VAL_2K:
322*79433559SRaag Jadav arg = 2000;
323*79433559SRaag Jadav break;
324*79433559SRaag Jadav case BUFCFG_PUPD_VAL_20K:
325*79433559SRaag Jadav arg = 20000;
326*79433559SRaag Jadav break;
327*79433559SRaag Jadav case BUFCFG_PUPD_VAL_50K:
328*79433559SRaag Jadav arg = 50000;
329*79433559SRaag Jadav break;
330*79433559SRaag Jadav }
331*79433559SRaag Jadav
332*79433559SRaag Jadav break;
333*79433559SRaag Jadav
334*79433559SRaag Jadav case PIN_CONFIG_DRIVE_PUSH_PULL:
335*79433559SRaag Jadav if (value & BUFCFG_OD_EN)
336*79433559SRaag Jadav return -EINVAL;
337*79433559SRaag Jadav break;
338*79433559SRaag Jadav
339*79433559SRaag Jadav case PIN_CONFIG_DRIVE_OPEN_DRAIN:
340*79433559SRaag Jadav if (!(value & BUFCFG_OD_EN))
341*79433559SRaag Jadav return -EINVAL;
342*79433559SRaag Jadav break;
343*79433559SRaag Jadav
344*79433559SRaag Jadav case PIN_CONFIG_SLEW_RATE:
345*79433559SRaag Jadav if (value & BUFCFG_SLEWSEL)
346*79433559SRaag Jadav arg = 1;
347*79433559SRaag Jadav break;
348*79433559SRaag Jadav
349*79433559SRaag Jadav default:
350*79433559SRaag Jadav return -ENOTSUPP;
351*79433559SRaag Jadav }
352*79433559SRaag Jadav
353*79433559SRaag Jadav *config = pinconf_to_config_packed(param, arg);
354*79433559SRaag Jadav return 0;
355*79433559SRaag Jadav }
356*79433559SRaag Jadav
tng_config_set_pin(struct tng_pinctrl * tp,unsigned int pin,unsigned long config)357*79433559SRaag Jadav static int tng_config_set_pin(struct tng_pinctrl *tp, unsigned int pin,
358*79433559SRaag Jadav unsigned long config)
359*79433559SRaag Jadav {
360*79433559SRaag Jadav unsigned int param = pinconf_to_config_param(config);
361*79433559SRaag Jadav unsigned int arg = pinconf_to_config_argument(config);
362*79433559SRaag Jadav u32 mask, term, value = 0;
363*79433559SRaag Jadav unsigned long flags;
364*79433559SRaag Jadav
365*79433559SRaag Jadav switch (param) {
366*79433559SRaag Jadav case PIN_CONFIG_BIAS_DISABLE:
367*79433559SRaag Jadav mask = BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK;
368*79433559SRaag Jadav break;
369*79433559SRaag Jadav
370*79433559SRaag Jadav case PIN_CONFIG_BIAS_PULL_UP:
371*79433559SRaag Jadav /* Set default strength value in case none is given */
372*79433559SRaag Jadav if (arg == 1)
373*79433559SRaag Jadav arg = 20000;
374*79433559SRaag Jadav
375*79433559SRaag Jadav switch (arg) {
376*79433559SRaag Jadav case 50000:
377*79433559SRaag Jadav term = BUFCFG_PUPD_VAL_50K;
378*79433559SRaag Jadav break;
379*79433559SRaag Jadav case 20000:
380*79433559SRaag Jadav term = BUFCFG_PUPD_VAL_20K;
381*79433559SRaag Jadav break;
382*79433559SRaag Jadav case 2000:
383*79433559SRaag Jadav term = BUFCFG_PUPD_VAL_2K;
384*79433559SRaag Jadav break;
385*79433559SRaag Jadav default:
386*79433559SRaag Jadav return -EINVAL;
387*79433559SRaag Jadav }
388*79433559SRaag Jadav
389*79433559SRaag Jadav mask = BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK;
390*79433559SRaag Jadav value = BUFCFG_PU_EN | (term << BUFCFG_PUPD_VAL_SHIFT);
391*79433559SRaag Jadav break;
392*79433559SRaag Jadav
393*79433559SRaag Jadav case PIN_CONFIG_BIAS_PULL_DOWN:
394*79433559SRaag Jadav /* Set default strength value in case none is given */
395*79433559SRaag Jadav if (arg == 1)
396*79433559SRaag Jadav arg = 20000;
397*79433559SRaag Jadav
398*79433559SRaag Jadav switch (arg) {
399*79433559SRaag Jadav case 50000:
400*79433559SRaag Jadav term = BUFCFG_PUPD_VAL_50K;
401*79433559SRaag Jadav break;
402*79433559SRaag Jadav case 20000:
403*79433559SRaag Jadav term = BUFCFG_PUPD_VAL_20K;
404*79433559SRaag Jadav break;
405*79433559SRaag Jadav case 2000:
406*79433559SRaag Jadav term = BUFCFG_PUPD_VAL_2K;
407*79433559SRaag Jadav break;
408*79433559SRaag Jadav default:
409*79433559SRaag Jadav return -EINVAL;
410*79433559SRaag Jadav }
411*79433559SRaag Jadav
412*79433559SRaag Jadav mask = BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK;
413*79433559SRaag Jadav value = BUFCFG_PD_EN | (term << BUFCFG_PUPD_VAL_SHIFT);
414*79433559SRaag Jadav break;
415*79433559SRaag Jadav
416*79433559SRaag Jadav case PIN_CONFIG_DRIVE_PUSH_PULL:
417*79433559SRaag Jadav mask = BUFCFG_OD_EN;
418*79433559SRaag Jadav break;
419*79433559SRaag Jadav
420*79433559SRaag Jadav case PIN_CONFIG_DRIVE_OPEN_DRAIN:
421*79433559SRaag Jadav mask = BUFCFG_OD_EN;
422*79433559SRaag Jadav value = BUFCFG_OD_EN;
423*79433559SRaag Jadav break;
424*79433559SRaag Jadav
425*79433559SRaag Jadav case PIN_CONFIG_SLEW_RATE:
426*79433559SRaag Jadav mask = BUFCFG_SLEWSEL;
427*79433559SRaag Jadav if (arg)
428*79433559SRaag Jadav value = BUFCFG_SLEWSEL;
429*79433559SRaag Jadav break;
430*79433559SRaag Jadav
431*79433559SRaag Jadav default:
432*79433559SRaag Jadav return -EINVAL;
433*79433559SRaag Jadav }
434*79433559SRaag Jadav
435*79433559SRaag Jadav raw_spin_lock_irqsave(&tp->lock, flags);
436*79433559SRaag Jadav tng_update_bufcfg(tp, pin, value, mask);
437*79433559SRaag Jadav raw_spin_unlock_irqrestore(&tp->lock, flags);
438*79433559SRaag Jadav
439*79433559SRaag Jadav return 0;
440*79433559SRaag Jadav }
441*79433559SRaag Jadav
tng_config_set(struct pinctrl_dev * pctldev,unsigned int pin,unsigned long * configs,unsigned int nconfigs)442*79433559SRaag Jadav static int tng_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
443*79433559SRaag Jadav unsigned long *configs, unsigned int nconfigs)
444*79433559SRaag Jadav {
445*79433559SRaag Jadav struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);
446*79433559SRaag Jadav unsigned int i;
447*79433559SRaag Jadav int ret;
448*79433559SRaag Jadav
449*79433559SRaag Jadav if (!tng_buf_available(tp, pin))
450*79433559SRaag Jadav return -ENOTSUPP;
451*79433559SRaag Jadav
452*79433559SRaag Jadav for (i = 0; i < nconfigs; i++) {
453*79433559SRaag Jadav switch (pinconf_to_config_param(configs[i])) {
454*79433559SRaag Jadav case PIN_CONFIG_BIAS_DISABLE:
455*79433559SRaag Jadav case PIN_CONFIG_BIAS_PULL_UP:
456*79433559SRaag Jadav case PIN_CONFIG_BIAS_PULL_DOWN:
457*79433559SRaag Jadav case PIN_CONFIG_DRIVE_PUSH_PULL:
458*79433559SRaag Jadav case PIN_CONFIG_DRIVE_OPEN_DRAIN:
459*79433559SRaag Jadav case PIN_CONFIG_SLEW_RATE:
460*79433559SRaag Jadav ret = tng_config_set_pin(tp, pin, configs[i]);
461*79433559SRaag Jadav if (ret)
462*79433559SRaag Jadav return ret;
463*79433559SRaag Jadav break;
464*79433559SRaag Jadav
465*79433559SRaag Jadav default:
466*79433559SRaag Jadav return -ENOTSUPP;
467*79433559SRaag Jadav }
468*79433559SRaag Jadav }
469*79433559SRaag Jadav
470*79433559SRaag Jadav return 0;
471*79433559SRaag Jadav }
472*79433559SRaag Jadav
tng_config_group_get(struct pinctrl_dev * pctldev,unsigned int group,unsigned long * config)473*79433559SRaag Jadav static int tng_config_group_get(struct pinctrl_dev *pctldev,
474*79433559SRaag Jadav unsigned int group, unsigned long *config)
475*79433559SRaag Jadav {
476*79433559SRaag Jadav const unsigned int *pins;
477*79433559SRaag Jadav unsigned int npins;
478*79433559SRaag Jadav int ret;
479*79433559SRaag Jadav
480*79433559SRaag Jadav ret = tng_get_group_pins(pctldev, group, &pins, &npins);
481*79433559SRaag Jadav if (ret)
482*79433559SRaag Jadav return ret;
483*79433559SRaag Jadav
484*79433559SRaag Jadav return tng_config_get(pctldev, pins[0], config);
485*79433559SRaag Jadav }
486*79433559SRaag Jadav
tng_config_group_set(struct pinctrl_dev * pctldev,unsigned int group,unsigned long * configs,unsigned int num_configs)487*79433559SRaag Jadav static int tng_config_group_set(struct pinctrl_dev *pctldev,
488*79433559SRaag Jadav unsigned int group, unsigned long *configs,
489*79433559SRaag Jadav unsigned int num_configs)
490*79433559SRaag Jadav {
491*79433559SRaag Jadav const unsigned int *pins;
492*79433559SRaag Jadav unsigned int npins;
493*79433559SRaag Jadav int i, ret;
494*79433559SRaag Jadav
495*79433559SRaag Jadav ret = tng_get_group_pins(pctldev, group, &pins, &npins);
496*79433559SRaag Jadav if (ret)
497*79433559SRaag Jadav return ret;
498*79433559SRaag Jadav
499*79433559SRaag Jadav for (i = 0; i < npins; i++) {
500*79433559SRaag Jadav ret = tng_config_set(pctldev, pins[i], configs, num_configs);
501*79433559SRaag Jadav if (ret)
502*79433559SRaag Jadav return ret;
503*79433559SRaag Jadav }
504*79433559SRaag Jadav
505*79433559SRaag Jadav return 0;
506*79433559SRaag Jadav }
507*79433559SRaag Jadav
508*79433559SRaag Jadav static const struct pinconf_ops tng_pinconf_ops = {
509*79433559SRaag Jadav .is_generic = true,
510*79433559SRaag Jadav .pin_config_get = tng_config_get,
511*79433559SRaag Jadav .pin_config_set = tng_config_set,
512*79433559SRaag Jadav .pin_config_group_get = tng_config_group_get,
513*79433559SRaag Jadav .pin_config_group_set = tng_config_group_set,
514*79433559SRaag Jadav };
515*79433559SRaag Jadav
516*79433559SRaag Jadav static const struct pinctrl_desc tng_pinctrl_desc = {
517*79433559SRaag Jadav .pctlops = &tng_pinctrl_ops,
518*79433559SRaag Jadav .pmxops = &tng_pinmux_ops,
519*79433559SRaag Jadav .confops = &tng_pinconf_ops,
520*79433559SRaag Jadav .owner = THIS_MODULE,
521*79433559SRaag Jadav };
522*79433559SRaag Jadav
tng_pinctrl_probe(struct platform_device * pdev,const struct tng_pinctrl * data)523*79433559SRaag Jadav static int tng_pinctrl_probe(struct platform_device *pdev,
524*79433559SRaag Jadav const struct tng_pinctrl *data)
525*79433559SRaag Jadav {
526*79433559SRaag Jadav struct device *dev = &pdev->dev;
527*79433559SRaag Jadav struct tng_family *families;
528*79433559SRaag Jadav struct tng_pinctrl *tp;
529*79433559SRaag Jadav size_t families_len;
530*79433559SRaag Jadav void __iomem *regs;
531*79433559SRaag Jadav unsigned int i;
532*79433559SRaag Jadav
533*79433559SRaag Jadav tp = devm_kmemdup(dev, data, sizeof(*data), GFP_KERNEL);
534*79433559SRaag Jadav if (!tp)
535*79433559SRaag Jadav return -ENOMEM;
536*79433559SRaag Jadav
537*79433559SRaag Jadav tp->dev = dev;
538*79433559SRaag Jadav raw_spin_lock_init(&tp->lock);
539*79433559SRaag Jadav
540*79433559SRaag Jadav regs = devm_platform_ioremap_resource(pdev, 0);
541*79433559SRaag Jadav if (IS_ERR(regs))
542*79433559SRaag Jadav return PTR_ERR(regs);
543*79433559SRaag Jadav
544*79433559SRaag Jadav /*
545*79433559SRaag Jadav * Make a copy of the families which we can use to hold pointers
546*79433559SRaag Jadav * to the registers.
547*79433559SRaag Jadav */
548*79433559SRaag Jadav families_len = size_mul(sizeof(*families), tp->nfamilies);
549*79433559SRaag Jadav families = devm_kmemdup(dev, tp->families, families_len, GFP_KERNEL);
550*79433559SRaag Jadav if (!families)
551*79433559SRaag Jadav return -ENOMEM;
552*79433559SRaag Jadav
553*79433559SRaag Jadav /* Splice memory resource by chunk per family */
554*79433559SRaag Jadav for (i = 0; i < tp->nfamilies; i++) {
555*79433559SRaag Jadav struct tng_family *family = &families[i];
556*79433559SRaag Jadav
557*79433559SRaag Jadav family->regs = regs + family->barno * TNG_FAMILY_LEN;
558*79433559SRaag Jadav }
559*79433559SRaag Jadav
560*79433559SRaag Jadav tp->families = families;
561*79433559SRaag Jadav tp->pctldesc = tng_pinctrl_desc;
562*79433559SRaag Jadav tp->pctldesc.name = dev_name(dev);
563*79433559SRaag Jadav tp->pctldesc.pins = tp->pins;
564*79433559SRaag Jadav tp->pctldesc.npins = tp->npins;
565*79433559SRaag Jadav
566*79433559SRaag Jadav tp->pctldev = devm_pinctrl_register(dev, &tp->pctldesc, tp);
567*79433559SRaag Jadav if (IS_ERR(tp->pctldev))
568*79433559SRaag Jadav return dev_err_probe(dev, PTR_ERR(tp->pctldev),
569*79433559SRaag Jadav "failed to register pinctrl driver\n");
570*79433559SRaag Jadav
571*79433559SRaag Jadav return 0;
572*79433559SRaag Jadav }
573*79433559SRaag Jadav
devm_tng_pinctrl_probe(struct platform_device * pdev)574*79433559SRaag Jadav int devm_tng_pinctrl_probe(struct platform_device *pdev)
575*79433559SRaag Jadav {
576*79433559SRaag Jadav const struct tng_pinctrl *data;
577*79433559SRaag Jadav
578*79433559SRaag Jadav data = device_get_match_data(&pdev->dev);
579*79433559SRaag Jadav if (!data)
580*79433559SRaag Jadav return -ENODATA;
581*79433559SRaag Jadav
582*79433559SRaag Jadav return tng_pinctrl_probe(pdev, data);
583*79433559SRaag Jadav }
584*79433559SRaag Jadav EXPORT_SYMBOL_NS_GPL(devm_tng_pinctrl_probe, PINCTRL_TANGIER);
585*79433559SRaag Jadav
586*79433559SRaag Jadav MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>");
587*79433559SRaag Jadav MODULE_AUTHOR("Raag Jadav <raag.jadav@intel.com>");
588*79433559SRaag Jadav MODULE_DESCRIPTION("Intel Tangier pinctrl driver");
589*79433559SRaag Jadav MODULE_LICENSE("GPL");
590