Skip to content

Commit 7f32d37

Browse files
committed
pinctrl: lynxpoint: Add pin control operations
Add implementation for: - pin control, group information retrieval: count, name and pins - pin muxing: - function information (count, name and groups) - mux setting - GPIO control (enable, disable, set direction) - pin configuration: - pull disable, up and down - any other option is treated as not supported. Reviewed-by: Linus Walleij <[email protected]> Signed-off-by: Andy Shevchenko <[email protected]> Acked-by: Mika Westerberg <[email protected]>
1 parent 18213ad commit 7f32d37

File tree

1 file changed

+314
-1
lines changed

1 file changed

+314
-1
lines changed

drivers/pinctrl/intel/pinctrl-lynxpoint.c

Lines changed: 314 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ static const struct intel_pinctrl_soc_data lptlp_soc_data = {
146146

147147
/* Bitmapped register offsets */
148148
#define LP_ACPI_OWNED 0x00 /* Bitmap, set by bios, 0: pin reserved for ACPI */
149+
#define LP_IRQ2IOXAPIC 0x10 /* Bitmap, set by bios, 1: pin routed to IOxAPIC */
149150
#define LP_GC 0x7C /* set APIC IRQ to IRQ14 or IRQ15 for all pins */
150151
#define LP_INT_STAT 0x80
151152
#define LP_INT_ENABLE 0x90
@@ -166,7 +167,10 @@ static const struct intel_pinctrl_soc_data lptlp_soc_data = {
166167

167168
/* LP_CONFIG2 reg bits */
168169
#define GPINDIS_BIT BIT(2) /* disable input sensing */
169-
#define GPIWP_BIT (BIT(0) | BIT(1)) /* weak pull options */
170+
#define GPIWP_MASK GENMASK(1, 0) /* weak pull options */
171+
#define GPIWP_NONE 0 /* none */
172+
#define GPIWP_DOWN 1 /* weak pull down */
173+
#define GPIWP_UP 2 /* weak pull up */
170174

171175
/*
172176
* Lynxpoint gpios are controlled through both bitmapped registers and
@@ -195,6 +199,8 @@ static const struct intel_pinctrl_soc_data lptlp_soc_data = {
195199
* ...
196200
* LP94_CONFIG1 (gpio 94) ...
197201
* LP94_CONFIG2 (gpio 94) ...
202+
*
203+
* IOxAPIC redirection map applies only for gpio 8-10, 13-14, 45-55.
198204
*/
199205

200206
static struct intel_community *lp_get_community(struct intel_pinctrl *lg,
@@ -246,6 +252,308 @@ static bool lp_gpio_acpi_use(struct intel_pinctrl *lg, unsigned int pin)
246252
return !(ioread32(acpi_use) & BIT(pin % 32));
247253
}
248254

255+
static bool lp_gpio_ioxapic_use(struct gpio_chip *chip, unsigned int offset)
256+
{
257+
void __iomem *ioxapic_use = lp_gpio_reg(chip, offset, LP_IRQ2IOXAPIC);
258+
u32 value;
259+
260+
value = ioread32(ioxapic_use);
261+
262+
if (offset >= 8 && offset <= 10)
263+
return !!(value & BIT(offset - 8 + 0));
264+
if (offset >= 13 && offset <= 14)
265+
return !!(value & BIT(offset - 13 + 3));
266+
if (offset >= 45 && offset <= 55)
267+
return !!(value & BIT(offset - 45 + 5));
268+
269+
return false;
270+
}
271+
272+
static int lp_get_groups_count(struct pinctrl_dev *pctldev)
273+
{
274+
struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
275+
276+
return lg->soc->ngroups;
277+
}
278+
279+
static const char *lp_get_group_name(struct pinctrl_dev *pctldev,
280+
unsigned int selector)
281+
{
282+
struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
283+
284+
return lg->soc->groups[selector].name;
285+
}
286+
287+
static int lp_get_group_pins(struct pinctrl_dev *pctldev,
288+
unsigned int selector,
289+
const unsigned int **pins,
290+
unsigned int *num_pins)
291+
{
292+
struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
293+
294+
*pins = lg->soc->groups[selector].pins;
295+
*num_pins = lg->soc->groups[selector].npins;
296+
297+
return 0;
298+
}
299+
300+
static const struct pinctrl_ops lptlp_pinctrl_ops = {
301+
.get_groups_count = lp_get_groups_count,
302+
.get_group_name = lp_get_group_name,
303+
.get_group_pins = lp_get_group_pins,
304+
};
305+
306+
static int lp_get_functions_count(struct pinctrl_dev *pctldev)
307+
{
308+
struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
309+
310+
return lg->soc->nfunctions;
311+
}
312+
313+
static const char *lp_get_function_name(struct pinctrl_dev *pctldev,
314+
unsigned int selector)
315+
{
316+
struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
317+
318+
return lg->soc->functions[selector].name;
319+
}
320+
321+
static int lp_get_function_groups(struct pinctrl_dev *pctldev,
322+
unsigned int selector,
323+
const char * const **groups,
324+
unsigned int *num_groups)
325+
{
326+
struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
327+
328+
*groups = lg->soc->functions[selector].groups;
329+
*num_groups = lg->soc->functions[selector].ngroups;
330+
331+
return 0;
332+
}
333+
334+
static int lp_pinmux_set_mux(struct pinctrl_dev *pctldev,
335+
unsigned int function, unsigned int group)
336+
{
337+
struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
338+
const struct intel_pingroup *grp = &lg->soc->groups[group];
339+
unsigned long flags;
340+
int i;
341+
342+
raw_spin_lock_irqsave(&lg->lock, flags);
343+
344+
/* Now enable the mux setting for each pin in the group */
345+
for (i = 0; i < grp->npins; i++) {
346+
void __iomem *reg = lp_gpio_reg(&lg->chip, grp->pins[i], LP_CONFIG1);
347+
u32 value;
348+
349+
value = ioread32(reg);
350+
351+
value &= ~USE_SEL_MASK;
352+
if (grp->modes)
353+
value |= grp->modes[i];
354+
else
355+
value |= grp->mode;
356+
357+
iowrite32(value, reg);
358+
}
359+
360+
raw_spin_unlock_irqrestore(&lg->lock, flags);
361+
362+
return 0;
363+
}
364+
365+
static int lp_gpio_request_enable(struct pinctrl_dev *pctldev,
366+
struct pinctrl_gpio_range *range,
367+
unsigned int pin)
368+
{
369+
struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
370+
void __iomem *reg = lp_gpio_reg(&lg->chip, pin, LP_CONFIG1);
371+
void __iomem *conf2 = lp_gpio_reg(&lg->chip, pin, LP_CONFIG2);
372+
unsigned long flags;
373+
u32 value;
374+
375+
pm_runtime_get(lg->dev);
376+
377+
raw_spin_lock_irqsave(&lg->lock, flags);
378+
379+
/*
380+
* Reconfigure pin to GPIO mode if needed and issue a warning,
381+
* since we expect firmware to configure it properly.
382+
*/
383+
value = ioread32(reg);
384+
if ((value & USE_SEL_MASK) != USE_SEL_GPIO) {
385+
iowrite32((value & USE_SEL_MASK) | USE_SEL_GPIO, reg);
386+
dev_warn(lg->dev, FW_BUG "pin %u forcibly reconfigured as GPIO\n", pin);
387+
}
388+
389+
/* Enable input sensing */
390+
iowrite32(ioread32(conf2) & ~GPINDIS_BIT, conf2);
391+
392+
raw_spin_unlock_irqrestore(&lg->lock, flags);
393+
394+
return 0;
395+
}
396+
397+
static void lp_gpio_disable_free(struct pinctrl_dev *pctldev,
398+
struct pinctrl_gpio_range *range,
399+
unsigned int pin)
400+
{
401+
struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
402+
void __iomem *conf2 = lp_gpio_reg(&lg->chip, pin, LP_CONFIG2);
403+
unsigned long flags;
404+
405+
raw_spin_lock_irqsave(&lg->lock, flags);
406+
407+
/* Disable input sensing */
408+
iowrite32(ioread32(conf2) | GPINDIS_BIT, conf2);
409+
410+
raw_spin_unlock_irqrestore(&lg->lock, flags);
411+
412+
pm_runtime_put(lg->dev);
413+
}
414+
415+
static int lp_gpio_set_direction(struct pinctrl_dev *pctldev,
416+
struct pinctrl_gpio_range *range,
417+
unsigned int pin, bool input)
418+
{
419+
struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
420+
void __iomem *reg = lp_gpio_reg(&lg->chip, pin, LP_CONFIG1);
421+
unsigned long flags;
422+
u32 value;
423+
424+
raw_spin_lock_irqsave(&lg->lock, flags);
425+
426+
value = ioread32(reg);
427+
value &= ~DIR_BIT;
428+
if (input) {
429+
value |= DIR_BIT;
430+
} else {
431+
/*
432+
* Before making any direction modifications, do a check if GPIO
433+
* is set for direct IRQ. On Lynxpoint, setting GPIO to output
434+
* does not make sense, so let's at least warn the caller before
435+
* they shoot themselves in the foot.
436+
*/
437+
WARN(lp_gpio_ioxapic_use(&lg->chip, pin),
438+
"Potential Error: Setting GPIO to output with IOxAPIC redirection");
439+
}
440+
iowrite32(value, reg);
441+
442+
raw_spin_unlock_irqrestore(&lg->lock, flags);
443+
444+
return 0;
445+
}
446+
447+
static const struct pinmux_ops lptlp_pinmux_ops = {
448+
.get_functions_count = lp_get_functions_count,
449+
.get_function_name = lp_get_function_name,
450+
.get_function_groups = lp_get_function_groups,
451+
.set_mux = lp_pinmux_set_mux,
452+
.gpio_request_enable = lp_gpio_request_enable,
453+
.gpio_disable_free = lp_gpio_disable_free,
454+
.gpio_set_direction = lp_gpio_set_direction,
455+
};
456+
457+
static int lp_pin_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
458+
unsigned long *config)
459+
{
460+
struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
461+
void __iomem *conf2 = lp_gpio_reg(&lg->chip, pin, LP_CONFIG2);
462+
enum pin_config_param param = pinconf_to_config_param(*config);
463+
unsigned long flags;
464+
u32 value, pull;
465+
u16 arg = 0;
466+
467+
raw_spin_lock_irqsave(&lg->lock, flags);
468+
value = ioread32(conf2);
469+
raw_spin_unlock_irqrestore(&lg->lock, flags);
470+
471+
pull = value & GPIWP_MASK;
472+
473+
switch (param) {
474+
case PIN_CONFIG_BIAS_DISABLE:
475+
if (pull)
476+
return -EINVAL;
477+
break;
478+
case PIN_CONFIG_BIAS_PULL_DOWN:
479+
if (pull != GPIWP_DOWN)
480+
return -EINVAL;
481+
482+
arg = 1;
483+
break;
484+
case PIN_CONFIG_BIAS_PULL_UP:
485+
if (pull != GPIWP_UP)
486+
return -EINVAL;
487+
488+
arg = 1;
489+
break;
490+
default:
491+
return -ENOTSUPP;
492+
}
493+
494+
*config = pinconf_to_config_packed(param, arg);
495+
496+
return 0;
497+
}
498+
499+
static int lp_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
500+
unsigned long *configs, unsigned int num_configs)
501+
{
502+
struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
503+
void __iomem *conf2 = lp_gpio_reg(&lg->chip, pin, LP_CONFIG2);
504+
enum pin_config_param param;
505+
unsigned long flags;
506+
int i, ret = 0;
507+
u32 value;
508+
509+
raw_spin_lock_irqsave(&lg->lock, flags);
510+
511+
value = ioread32(conf2);
512+
513+
for (i = 0; i < num_configs; i++) {
514+
param = pinconf_to_config_param(configs[i]);
515+
516+
switch (param) {
517+
case PIN_CONFIG_BIAS_DISABLE:
518+
value &= ~GPIWP_MASK;
519+
break;
520+
case PIN_CONFIG_BIAS_PULL_DOWN:
521+
value &= ~GPIWP_MASK;
522+
value |= GPIWP_DOWN;
523+
break;
524+
case PIN_CONFIG_BIAS_PULL_UP:
525+
value &= ~GPIWP_MASK;
526+
value |= GPIWP_UP;
527+
break;
528+
default:
529+
ret = -ENOTSUPP;
530+
}
531+
532+
if (ret)
533+
break;
534+
}
535+
536+
if (!ret)
537+
iowrite32(value, conf2);
538+
539+
raw_spin_unlock_irqrestore(&lg->lock, flags);
540+
541+
return ret;
542+
}
543+
544+
static const struct pinconf_ops lptlp_pinconf_ops = {
545+
.is_generic = true,
546+
.pin_config_get = lp_pin_config_get,
547+
.pin_config_set = lp_pin_config_set,
548+
};
549+
550+
static const struct pinctrl_desc lptlp_pinctrl_desc = {
551+
.pctlops = &lptlp_pinctrl_ops,
552+
.pmxops = &lptlp_pinmux_ops,
553+
.confops = &lptlp_pinconf_ops,
554+
.owner = THIS_MODULE,
555+
};
556+
249557
static int lp_gpio_request(struct gpio_chip *chip, unsigned int offset)
250558
{
251559
struct intel_pinctrl *lg = gpiochip_get_data(chip);
@@ -525,6 +833,11 @@ static int lp_gpio_probe(struct platform_device *pdev)
525833
if (!lg->communities)
526834
return -ENOMEM;
527835

836+
lg->pctldesc = lptlp_pinctrl_desc;
837+
lg->pctldesc.name = dev_name(dev);
838+
lg->pctldesc.pins = lg->soc->pins;
839+
lg->pctldesc.npins = lg->soc->npins;
840+
528841
platform_set_drvdata(pdev, lg);
529842

530843
io_rc = platform_get_resource(pdev, IORESOURCE_IO, 0);

0 commit comments

Comments
 (0)