File Index
Files and directories
Sign in
FILE

pinctrl-meson.c

File preview with syntax highlighting.

linux-6.19.14/drivers/pinctrl/meson/pinctrl-meson.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Pin controller and GPIO driver for Amlogic Meson SoCs
  4 *
  5 * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
  6 */
  7
  8/*
  9 * The available pins are organized in banks (A,B,C,D,E,X,Y,Z,AO,
 10 * BOOT,CARD for meson6, X,Y,DV,H,Z,AO,BOOT,CARD for meson8 and
 11 * X,Y,DV,H,AO,BOOT,CARD,DIF for meson8b) and each bank has a
 12 * variable number of pins.
 13 *
 14 * The AO bank is special because it belongs to the Always-On power
 15 * domain which can't be powered off; the bank also uses a set of
 16 * registers different from the other banks.
 17 *
 18 * For each pin controller there are 4 different register ranges that
 19 * control the following properties of the pins:
 20 *  1) pin muxing
 21 *  2) pull enable/disable
 22 *  3) pull up/down
 23 *  4) GPIO direction, output value, input value
 24 *
 25 * In some cases the register ranges for pull enable and pull
 26 * direction are the same and thus there are only 3 register ranges.
 27 *
 28 * Since Meson G12A SoC, the ao register ranges for gpio, pull enable
 29 * and pull direction are the same, so there are only 2 register ranges.
 30 *
 31 * For the pull and GPIO configuration every bank uses a contiguous
 32 * set of bits in the register sets described above; the same register
 33 * can be shared by more banks with different offsets.
 34 *
 35 * In addition to this there are some registers shared between all
 36 * banks that control the IRQ functionality. This feature is not
 37 * supported at the moment by the driver.
 38 */
 39
 40#include <linux/device.h>
 41#include <linux/gpio/driver.h>
 42#include <linux/init.h>
 43#include <linux/io.h>
 44#include <linux/of.h>
 45#include <linux/of_address.h>
 46#include <linux/pinctrl/pinconf-generic.h>
 47#include <linux/pinctrl/pinconf.h>
 48#include <linux/pinctrl/pinctrl.h>
 49#include <linux/pinctrl/pinmux.h>
 50#include <linux/platform_device.h>
 51#include <linux/property.h>
 52#include <linux/regmap.h>
 53#include <linux/seq_file.h>
 54
 55#include "../core.h"
 56#include "../pinctrl-utils.h"
 57#include "pinctrl-meson.h"
 58
 59static const unsigned int meson_bit_strides[] = {
 60	1, 1, 1, 1, 1, 2, 1
 61};
 62
 63/**
 64 * meson_get_bank() - find the bank containing a given pin
 65 *
 66 * @pc:		the pinctrl instance
 67 * @pin:	the pin number
 68 * @bank:	the found bank
 69 *
 70 * Return:	0 on success, a negative value on error
 71 */
 72static int meson_get_bank(struct meson_pinctrl *pc, unsigned int pin,
 73			  const struct meson_bank **bank)
 74{
 75	int i;
 76
 77	for (i = 0; i < pc->data->num_banks; i++) {
 78		if (pin >= pc->data->banks[i].first &&
 79		    pin <= pc->data->banks[i].last) {
 80			*bank = &pc->data->banks[i];
 81			return 0;
 82		}
 83	}
 84
 85	return -EINVAL;
 86}
 87
 88/**
 89 * meson_calc_reg_and_bit() - calculate register and bit for a pin
 90 *
 91 * @bank:	the bank containing the pin
 92 * @pin:	the pin number
 93 * @reg_type:	the type of register needed (pull-enable, pull, etc...)
 94 * @reg:	the computed register offset
 95 * @bit:	the computed bit
 96 */
 97static void meson_calc_reg_and_bit(const struct meson_bank *bank,
 98				   unsigned int pin,
 99				   enum meson_reg_type reg_type,
100				   unsigned int *reg, unsigned int *bit)
101{
102	const struct meson_reg_desc *desc = &bank->regs[reg_type];
103
104	*bit = (desc->bit + pin - bank->first) * meson_bit_strides[reg_type];
105	*reg = (desc->reg + (*bit / 32)) * 4;
106	*bit &= 0x1f;
107}
108
109static int meson_get_groups_count(struct pinctrl_dev *pcdev)
110{
111	struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
112
113	return pc->data->num_groups;
114}
115
116static const char *meson_get_group_name(struct pinctrl_dev *pcdev,
117					unsigned selector)
118{
119	struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
120
121	return pc->data->groups[selector].name;
122}
123
124static int meson_get_group_pins(struct pinctrl_dev *pcdev, unsigned selector,
125				const unsigned **pins, unsigned *num_pins)
126{
127	struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
128
129	*pins = pc->data->groups[selector].pins;
130	*num_pins = pc->data->groups[selector].num_pins;
131
132	return 0;
133}
134
135static void meson_pin_dbg_show(struct pinctrl_dev *pcdev, struct seq_file *s,
136			       unsigned offset)
137{
138	seq_printf(s, " %s", dev_name(pcdev->dev));
139}
140
141static const struct pinctrl_ops meson_pctrl_ops = {
142	.get_groups_count	= meson_get_groups_count,
143	.get_group_name		= meson_get_group_name,
144	.get_group_pins		= meson_get_group_pins,
145	.dt_node_to_map		= pinconf_generic_dt_node_to_map_all,
146	.dt_free_map		= pinctrl_utils_free_map,
147	.pin_dbg_show		= meson_pin_dbg_show,
148};
149
150int meson_pmx_get_funcs_count(struct pinctrl_dev *pcdev)
151{
152	struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
153
154	return pc->data->num_funcs;
155}
156EXPORT_SYMBOL_GPL(meson_pmx_get_funcs_count);
157
158const char *meson_pmx_get_func_name(struct pinctrl_dev *pcdev,
159				    unsigned selector)
160{
161	struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
162
163	return pc->data->funcs[selector].name;
164}
165EXPORT_SYMBOL_GPL(meson_pmx_get_func_name);
166
167int meson_pmx_get_groups(struct pinctrl_dev *pcdev, unsigned selector,
168			 const char * const **groups,
169			 unsigned * const num_groups)
170{
171	struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
172
173	*groups = pc->data->funcs[selector].groups;
174	*num_groups = pc->data->funcs[selector].num_groups;
175
176	return 0;
177}
178EXPORT_SYMBOL_GPL(meson_pmx_get_groups);
179
180static int meson_pinconf_set_gpio_bit(struct meson_pinctrl *pc,
181				      unsigned int pin,
182				      unsigned int reg_type,
183				      bool arg)
184{
185	const struct meson_bank *bank;
186	unsigned int reg, bit;
187	int ret;
188
189	ret = meson_get_bank(pc, pin, &bank);
190	if (ret)
191		return ret;
192
193	meson_calc_reg_and_bit(bank, pin, reg_type, &reg, &bit);
194	return regmap_update_bits(pc->reg_gpio, reg, BIT(bit),
195				  arg ? BIT(bit) : 0);
196}
197
198static int meson_pinconf_get_gpio_bit(struct meson_pinctrl *pc,
199				      unsigned int pin,
200				      unsigned int reg_type)
201{
202	const struct meson_bank *bank;
203	unsigned int reg, bit, val;
204	int ret;
205
206	ret = meson_get_bank(pc, pin, &bank);
207	if (ret)
208		return ret;
209
210	meson_calc_reg_and_bit(bank, pin, reg_type, &reg, &bit);
211	ret = regmap_read(pc->reg_gpio, reg, &val);
212	if (ret)
213		return ret;
214
215	return BIT(bit) & val ? 1 : 0;
216}
217
218static int meson_pinconf_set_output(struct meson_pinctrl *pc,
219				    unsigned int pin,
220				    bool out)
221{
222	return meson_pinconf_set_gpio_bit(pc, pin, MESON_REG_DIR, !out);
223}
224
225static int meson_pinconf_get_output(struct meson_pinctrl *pc,
226				    unsigned int pin)
227{
228	int ret = meson_pinconf_get_gpio_bit(pc, pin, MESON_REG_DIR);
229
230	if (ret < 0)
231		return ret;
232
233	return !ret;
234}
235
236static int meson_pinconf_set_drive(struct meson_pinctrl *pc,
237				   unsigned int pin,
238				   bool high)
239{
240	return meson_pinconf_set_gpio_bit(pc, pin, MESON_REG_OUT, high);
241}
242
243static int meson_pinconf_get_drive(struct meson_pinctrl *pc,
244				   unsigned int pin)
245{
246	return meson_pinconf_get_gpio_bit(pc, pin, MESON_REG_OUT);
247}
248
249static int meson_pinconf_set_output_drive(struct meson_pinctrl *pc,
250					  unsigned int pin,
251					  bool high)
252{
253	int ret;
254
255	ret = meson_pinconf_set_output(pc, pin, true);
256	if (ret)
257		return ret;
258
259	return meson_pinconf_set_drive(pc, pin, high);
260}
261
262static int meson_pinconf_disable_bias(struct meson_pinctrl *pc,
263				      unsigned int pin)
264{
265	const struct meson_bank *bank;
266	unsigned int reg, bit = 0;
267	int ret;
268
269	ret = meson_get_bank(pc, pin, &bank);
270	if (ret)
271		return ret;
272
273	meson_calc_reg_and_bit(bank, pin, MESON_REG_PULLEN, &reg, &bit);
274	ret = regmap_update_bits(pc->reg_pullen, reg, BIT(bit), 0);
275	if (ret)
276		return ret;
277
278	return 0;
279}
280
281static int meson_pinconf_enable_bias(struct meson_pinctrl *pc, unsigned int pin,
282				     bool pull_up)
283{
284	const struct meson_bank *bank;
285	unsigned int reg, bit, val = 0;
286	int ret;
287
288	ret = meson_get_bank(pc, pin, &bank);
289	if (ret)
290		return ret;
291
292	meson_calc_reg_and_bit(bank, pin, MESON_REG_PULL, &reg, &bit);
293	if (pull_up)
294		val = BIT(bit);
295
296	ret = regmap_update_bits(pc->reg_pull, reg, BIT(bit), val);
297	if (ret)
298		return ret;
299
300	meson_calc_reg_and_bit(bank, pin, MESON_REG_PULLEN, &reg, &bit);
301	ret = regmap_update_bits(pc->reg_pullen, reg, BIT(bit),	BIT(bit));
302	if (ret)
303		return ret;
304
305	return 0;
306}
307
308static int meson_pinconf_set_drive_strength(struct meson_pinctrl *pc,
309					    unsigned int pin,
310					    u16 drive_strength_ua)
311{
312	const struct meson_bank *bank;
313	unsigned int reg, bit, ds_val;
314	int ret;
315
316	if (!pc->reg_ds) {
317		dev_err(pc->dev, "drive-strength not supported\n");
318		return -ENOTSUPP;
319	}
320
321	ret = meson_get_bank(pc, pin, &bank);
322	if (ret)
323		return ret;
324
325	meson_calc_reg_and_bit(bank, pin, MESON_REG_DS, &reg, &bit);
326
327	if (drive_strength_ua <= 500) {
328		ds_val = MESON_PINCONF_DRV_500UA;
329	} else if (drive_strength_ua <= 2500) {
330		ds_val = MESON_PINCONF_DRV_2500UA;
331	} else if (drive_strength_ua <= 3000) {
332		ds_val = MESON_PINCONF_DRV_3000UA;
333	} else if (drive_strength_ua <= 4000) {
334		ds_val = MESON_PINCONF_DRV_4000UA;
335	} else {
336		dev_warn_once(pc->dev,
337			      "pin %u: invalid drive-strength : %d , default to 4mA\n",
338			      pin, drive_strength_ua);
339		ds_val = MESON_PINCONF_DRV_4000UA;
340	}
341
342	ret = regmap_update_bits(pc->reg_ds, reg, 0x3 << bit, ds_val << bit);
343	if (ret)
344		return ret;
345
346	return 0;
347}
348
349static int meson_pinconf_set(struct pinctrl_dev *pcdev, unsigned int pin,
350			     unsigned long *configs, unsigned num_configs)
351{
352	struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
353	enum pin_config_param param;
354	unsigned int arg = 0;
355	int i, ret;
356
357	for (i = 0; i < num_configs; i++) {
358		param = pinconf_to_config_param(configs[i]);
359
360		switch (param) {
361		case PIN_CONFIG_DRIVE_STRENGTH_UA:
362		case PIN_CONFIG_OUTPUT_ENABLE:
363		case PIN_CONFIG_LEVEL:
364			arg = pinconf_to_config_argument(configs[i]);
365			break;
366
367		default:
368			break;
369		}
370
371		switch (param) {
372		case PIN_CONFIG_BIAS_DISABLE:
373			ret = meson_pinconf_disable_bias(pc, pin);
374			break;
375		case PIN_CONFIG_BIAS_PULL_UP:
376			ret = meson_pinconf_enable_bias(pc, pin, true);
377			break;
378		case PIN_CONFIG_BIAS_PULL_DOWN:
379			ret = meson_pinconf_enable_bias(pc, pin, false);
380			break;
381		case PIN_CONFIG_DRIVE_STRENGTH_UA:
382			ret = meson_pinconf_set_drive_strength(pc, pin, arg);
383			break;
384		case PIN_CONFIG_OUTPUT_ENABLE:
385			ret = meson_pinconf_set_output(pc, pin, arg);
386			break;
387		case PIN_CONFIG_LEVEL:
388			ret = meson_pinconf_set_output_drive(pc, pin, arg);
389			break;
390		default:
391			ret = -ENOTSUPP;
392		}
393
394		if (ret)
395			return ret;
396	}
397
398	return 0;
399}
400
401static int meson_pinconf_get_pull(struct meson_pinctrl *pc, unsigned int pin)
402{
403	const struct meson_bank *bank;
404	unsigned int reg, bit, val;
405	int ret, conf;
406
407	ret = meson_get_bank(pc, pin, &bank);
408	if (ret)
409		return ret;
410
411	meson_calc_reg_and_bit(bank, pin, MESON_REG_PULLEN, &reg, &bit);
412
413	ret = regmap_read(pc->reg_pullen, reg, &val);
414	if (ret)
415		return ret;
416
417	if (!(val & BIT(bit))) {
418		conf = PIN_CONFIG_BIAS_DISABLE;
419	} else {
420		meson_calc_reg_and_bit(bank, pin, MESON_REG_PULL, &reg, &bit);
421
422		ret = regmap_read(pc->reg_pull, reg, &val);
423		if (ret)
424			return ret;
425
426		if (val & BIT(bit))
427			conf = PIN_CONFIG_BIAS_PULL_UP;
428		else
429			conf = PIN_CONFIG_BIAS_PULL_DOWN;
430	}
431
432	return conf;
433}
434
435static int meson_pinconf_get_drive_strength(struct meson_pinctrl *pc,
436					    unsigned int pin,
437					    u16 *drive_strength_ua)
438{
439	const struct meson_bank *bank;
440	unsigned int reg, bit;
441	unsigned int val;
442	int ret;
443
444	if (!pc->reg_ds)
445		return -ENOTSUPP;
446
447	ret = meson_get_bank(pc, pin, &bank);
448	if (ret)
449		return ret;
450
451	meson_calc_reg_and_bit(bank, pin, MESON_REG_DS, &reg, &bit);
452
453	ret = regmap_read(pc->reg_ds, reg, &val);
454	if (ret)
455		return ret;
456
457	switch ((val >> bit) & 0x3) {
458	case MESON_PINCONF_DRV_500UA:
459		*drive_strength_ua = 500;
460		break;
461	case MESON_PINCONF_DRV_2500UA:
462		*drive_strength_ua = 2500;
463		break;
464	case MESON_PINCONF_DRV_3000UA:
465		*drive_strength_ua = 3000;
466		break;
467	case MESON_PINCONF_DRV_4000UA:
468		*drive_strength_ua = 4000;
469		break;
470	default:
471		return -EINVAL;
472	}
473
474	return 0;
475}
476
477static int meson_pinconf_get(struct pinctrl_dev *pcdev, unsigned int pin,
478			     unsigned long *config)
479{
480	struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
481	enum pin_config_param param = pinconf_to_config_param(*config);
482	u16 arg;
483	int ret;
484
485	switch (param) {
486	case PIN_CONFIG_BIAS_DISABLE:
487	case PIN_CONFIG_BIAS_PULL_DOWN:
488	case PIN_CONFIG_BIAS_PULL_UP:
489		if (meson_pinconf_get_pull(pc, pin) == param)
490			arg = 60000;
491		else
492			return -EINVAL;
493		break;
494	case PIN_CONFIG_DRIVE_STRENGTH_UA:
495		ret = meson_pinconf_get_drive_strength(pc, pin, &arg);
496		if (ret)
497			return ret;
498		break;
499	case PIN_CONFIG_OUTPUT_ENABLE:
500		ret = meson_pinconf_get_output(pc, pin);
501		if (ret <= 0)
502			return -EINVAL;
503		arg = 1;
504		break;
505	case PIN_CONFIG_LEVEL:
506		ret = meson_pinconf_get_output(pc, pin);
507		if (ret <= 0)
508			return -EINVAL;
509
510		ret = meson_pinconf_get_drive(pc, pin);
511		if (ret < 0)
512			return -EINVAL;
513
514		arg = ret;
515		break;
516
517	default:
518		return -ENOTSUPP;
519	}
520
521	*config = pinconf_to_config_packed(param, arg);
522	dev_dbg(pc->dev, "pinconf for pin %u is %lu\n", pin, *config);
523
524	return 0;
525}
526
527static int meson_pinconf_group_set(struct pinctrl_dev *pcdev,
528				   unsigned int num_group,
529				   unsigned long *configs, unsigned num_configs)
530{
531	struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
532	const struct meson_pmx_group *group = &pc->data->groups[num_group];
533	int i;
534
535	dev_dbg(pc->dev, "set pinconf for group %s\n", group->name);
536
537	for (i = 0; i < group->num_pins; i++) {
538		meson_pinconf_set(pcdev, group->pins[i], configs,
539				  num_configs);
540	}
541
542	return 0;
543}
544
545static int meson_pinconf_group_get(struct pinctrl_dev *pcdev,
546				   unsigned int group, unsigned long *config)
547{
548	return -ENOTSUPP;
549}
550
551static const struct pinconf_ops meson_pinconf_ops = {
552	.pin_config_get		= meson_pinconf_get,
553	.pin_config_set		= meson_pinconf_set,
554	.pin_config_group_get	= meson_pinconf_group_get,
555	.pin_config_group_set	= meson_pinconf_group_set,
556	.is_generic		= true,
557};
558
559static int meson_gpio_get_direction(struct gpio_chip *chip, unsigned gpio)
560{
561	struct meson_pinctrl *pc = gpiochip_get_data(chip);
562	int ret;
563
564	ret = meson_pinconf_get_output(pc, gpio);
565	if (ret < 0)
566		return ret;
567
568	return ret ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
569}
570
571static int meson_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
572{
573	return meson_pinconf_set_output(gpiochip_get_data(chip), gpio, false);
574}
575
576static int meson_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
577				       int value)
578{
579	return meson_pinconf_set_output_drive(gpiochip_get_data(chip),
580					      gpio, value);
581}
582
583static int meson_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)
584{
585	return meson_pinconf_set_drive(gpiochip_get_data(chip), gpio, value);
586}
587
588static int meson_gpio_get(struct gpio_chip *chip, unsigned gpio)
589{
590	struct meson_pinctrl *pc = gpiochip_get_data(chip);
591	const struct meson_bank *bank;
592	unsigned int reg, bit, val;
593	int ret;
594
595	ret = meson_get_bank(pc, gpio, &bank);
596	if (ret)
597		return ret;
598
599	meson_calc_reg_and_bit(bank, gpio, MESON_REG_IN, &reg, &bit);
600	regmap_read(pc->reg_gpio, reg, &val);
601
602	return !!(val & BIT(bit));
603}
604
605static int meson_gpiolib_register(struct meson_pinctrl *pc)
606{
607	int ret;
608
609	pc->chip.label = pc->data->name;
610	pc->chip.parent = pc->dev;
611	pc->chip.fwnode = pc->fwnode;
612	pc->chip.request = gpiochip_generic_request;
613	pc->chip.free = gpiochip_generic_free;
614	pc->chip.set_config = gpiochip_generic_config;
615	pc->chip.get_direction = meson_gpio_get_direction;
616	pc->chip.direction_input = meson_gpio_direction_input;
617	pc->chip.direction_output = meson_gpio_direction_output;
618	pc->chip.get = meson_gpio_get;
619	pc->chip.set = meson_gpio_set;
620	pc->chip.base = -1;
621	pc->chip.ngpio = pc->data->num_pins;
622	pc->chip.can_sleep = true;
623
624	ret = gpiochip_add_data(&pc->chip, pc);
625	if (ret) {
626		dev_err(pc->dev, "can't add gpio chip %s\n",
627			pc->data->name);
628		return ret;
629	}
630
631	return 0;
632}
633
634static struct regmap_config meson_regmap_config = {
635	.reg_bits = 32,
636	.val_bits = 32,
637	.reg_stride = 4,
638};
639
640static struct regmap *meson_map_resource(struct meson_pinctrl *pc,
641					 struct device_node *node, char *name)
642{
643	struct resource res;
644	void __iomem *base;
645	int i;
646
647	i = of_property_match_string(node, "reg-names", name);
648	if (of_address_to_resource(node, i, &res))
649		return NULL;
650
651	base = devm_ioremap_resource(pc->dev, &res);
652	if (IS_ERR(base))
653		return ERR_CAST(base);
654
655	meson_regmap_config.max_register = resource_size(&res) - 4;
656	meson_regmap_config.name = devm_kasprintf(pc->dev, GFP_KERNEL,
657						  "%pOFn-%s", node,
658						  name);
659	if (!meson_regmap_config.name)
660		return ERR_PTR(-ENOMEM);
661
662	return devm_regmap_init_mmio(pc->dev, base, &meson_regmap_config);
663}
664
665static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc)
666{
667	struct device_node *gpio_np;
668	unsigned int chips;
669
670	chips = gpiochip_node_count(pc->dev);
671	if (!chips) {
672		dev_err(pc->dev, "no gpio node found\n");
673		return -EINVAL;
674	}
675	if (chips > 1) {
676		dev_err(pc->dev, "multiple gpio nodes\n");
677		return -EINVAL;
678	}
679
680	pc->fwnode = gpiochip_node_get_first(pc->dev);
681	gpio_np = to_of_node(pc->fwnode);
682
683	pc->reg_mux = meson_map_resource(pc, gpio_np, "mux");
684	if (IS_ERR_OR_NULL(pc->reg_mux)) {
685		dev_err(pc->dev, "mux registers not found\n");
686		return pc->reg_mux ? PTR_ERR(pc->reg_mux) : -ENOENT;
687	}
688
689	pc->reg_gpio = meson_map_resource(pc, gpio_np, "gpio");
690	if (IS_ERR_OR_NULL(pc->reg_gpio)) {
691		dev_err(pc->dev, "gpio registers not found\n");
692		return pc->reg_gpio ? PTR_ERR(pc->reg_gpio) : -ENOENT;
693	}
694
695	pc->reg_pull = meson_map_resource(pc, gpio_np, "pull");
696	if (IS_ERR(pc->reg_pull))
697		pc->reg_pull = NULL;
698
699	pc->reg_pullen = meson_map_resource(pc, gpio_np, "pull-enable");
700	if (IS_ERR(pc->reg_pullen))
701		pc->reg_pullen = NULL;
702
703	pc->reg_ds = meson_map_resource(pc, gpio_np, "ds");
704	if (IS_ERR(pc->reg_ds)) {
705		dev_dbg(pc->dev, "ds registers not found - skipping\n");
706		pc->reg_ds = NULL;
707	}
708
709	if (pc->data->parse_dt)
710		return pc->data->parse_dt(pc);
711
712	return 0;
713}
714
715int meson8_aobus_parse_dt_extra(struct meson_pinctrl *pc)
716{
717	if (!pc->reg_pull)
718		return -EINVAL;
719
720	pc->reg_pullen = pc->reg_pull;
721
722	return 0;
723}
724EXPORT_SYMBOL_GPL(meson8_aobus_parse_dt_extra);
725
726int meson_a1_parse_dt_extra(struct meson_pinctrl *pc)
727{
728	pc->reg_pull = pc->reg_gpio;
729	pc->reg_pullen = pc->reg_gpio;
730	pc->reg_ds = pc->reg_gpio;
731
732	return 0;
733}
734EXPORT_SYMBOL_GPL(meson_a1_parse_dt_extra);
735
736int meson_pinctrl_probe(struct platform_device *pdev)
737{
738	struct device *dev = &pdev->dev;
739	struct meson_pinctrl *pc;
740	int ret;
741
742	pc = devm_kzalloc(dev, sizeof(struct meson_pinctrl), GFP_KERNEL);
743	if (!pc)
744		return -ENOMEM;
745
746	pc->dev = dev;
747	pc->data = (struct meson_pinctrl_data *) of_device_get_match_data(dev);
748
749	ret = meson_pinctrl_parse_dt(pc);
750	if (ret)
751		return ret;
752
753	pc->desc.name		= "pinctrl-meson";
754	pc->desc.owner		= THIS_MODULE;
755	pc->desc.pctlops	= &meson_pctrl_ops;
756	pc->desc.pmxops		= pc->data->pmx_ops;
757	pc->desc.confops	= &meson_pinconf_ops;
758	pc->desc.pins		= pc->data->pins;
759	pc->desc.npins		= pc->data->num_pins;
760
761	pc->pcdev = devm_pinctrl_register(pc->dev, &pc->desc, pc);
762	if (IS_ERR(pc->pcdev)) {
763		dev_err(pc->dev, "can't register pinctrl device");
764		return PTR_ERR(pc->pcdev);
765	}
766
767	return meson_gpiolib_register(pc);
768}
769EXPORT_SYMBOL_GPL(meson_pinctrl_probe);
770
771MODULE_DESCRIPTION("Amlogic Meson SoCs core pinctrl driver");
772MODULE_LICENSE("GPL v2");
~/ Read-only file preview.