hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/pinctrl/meson/pinctrl-meson.c
....@@ -1,14 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Pin controller and GPIO driver for Amlogic Meson SoCs
34 *
45 * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
5
- *
6
- * This program is free software; you can redistribute it and/or
7
- * modify it under the terms of the GNU General Public License
8
- * version 2 as published by the Free Software Foundation.
9
- *
10
- * You should have received a copy of the GNU General Public License
11
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
126 */
137
148 /*
....@@ -31,6 +25,9 @@
3125 * In some cases the register ranges for pull enable and pull
3226 * direction are the same and thus there are only 3 register ranges.
3327 *
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
+ *
3431 * For the pull and GPIO configuration every bank uses a contiguous
3532 * set of bits in the register sets described above; the same register
3633 * can be shared by more banks with different offsets.
....@@ -41,7 +38,7 @@
4138 */
4239
4340 #include <linux/device.h>
44
-#include <linux/gpio.h>
41
+#include <linux/gpio/driver.h>
4542 #include <linux/init.h>
4643 #include <linux/io.h>
4744 #include <linux/of.h>
....@@ -58,6 +55,10 @@
5855 #include "../core.h"
5956 #include "../pinctrl-utils.h"
6057 #include "pinctrl-meson.h"
58
+
59
+static const unsigned int meson_bit_strides[] = {
60
+ 1, 1, 1, 1, 1, 2, 1
61
+};
6162
6263 /**
6364 * meson_get_bank() - find the bank containing a given pin
....@@ -99,8 +100,9 @@
99100 {
100101 struct meson_reg_desc *desc = &bank->regs[reg_type];
101102
102
- *reg = desc->reg * 4;
103
- *bit = desc->bit + pin - bank->first;
103
+ *bit = (desc->bit + pin - bank->first) * meson_bit_strides[reg_type];
104
+ *reg = (desc->reg + (*bit / 32)) * 4;
105
+ *bit &= 0x1f;
104106 }
105107
106108 static int meson_get_groups_count(struct pinctrl_dev *pcdev)
....@@ -150,6 +152,7 @@
150152
151153 return pc->data->num_funcs;
152154 }
155
+EXPORT_SYMBOL_GPL(meson_pmx_get_funcs_count);
153156
154157 const char *meson_pmx_get_func_name(struct pinctrl_dev *pcdev,
155158 unsigned selector)
....@@ -158,6 +161,7 @@
158161
159162 return pc->data->funcs[selector].name;
160163 }
164
+EXPORT_SYMBOL_GPL(meson_pmx_get_func_name);
161165
162166 int meson_pmx_get_groups(struct pinctrl_dev *pcdev, unsigned selector,
163167 const char * const **groups,
....@@ -170,69 +174,224 @@
170174
171175 return 0;
172176 }
177
+EXPORT_SYMBOL_GPL(meson_pmx_get_groups);
173178
174
-static int meson_pinconf_set(struct pinctrl_dev *pcdev, unsigned int pin,
175
- unsigned long *configs, unsigned num_configs)
179
+static int meson_pinconf_set_gpio_bit(struct meson_pinctrl *pc,
180
+ unsigned int pin,
181
+ unsigned int reg_type,
182
+ bool arg)
176183 {
177
- struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
178184 struct meson_bank *bank;
179
- enum pin_config_param param;
180185 unsigned int reg, bit;
181
- int i, ret;
186
+ int ret;
182187
183188 ret = meson_get_bank(pc, pin, &bank);
184189 if (ret)
185190 return ret;
186191
192
+ meson_calc_reg_and_bit(bank, pin, reg_type, &reg, &bit);
193
+ return regmap_update_bits(pc->reg_gpio, reg, BIT(bit),
194
+ arg ? BIT(bit) : 0);
195
+}
196
+
197
+static int meson_pinconf_get_gpio_bit(struct meson_pinctrl *pc,
198
+ unsigned int pin,
199
+ unsigned int reg_type)
200
+{
201
+ struct meson_bank *bank;
202
+ unsigned int reg, bit, val;
203
+ int ret;
204
+
205
+ ret = meson_get_bank(pc, pin, &bank);
206
+ if (ret)
207
+ return ret;
208
+
209
+ meson_calc_reg_and_bit(bank, pin, reg_type, &reg, &bit);
210
+ ret = regmap_read(pc->reg_gpio, reg, &val);
211
+ if (ret)
212
+ return ret;
213
+
214
+ return BIT(bit) & val ? 1 : 0;
215
+}
216
+
217
+static int meson_pinconf_set_output(struct meson_pinctrl *pc,
218
+ unsigned int pin,
219
+ bool out)
220
+{
221
+ return meson_pinconf_set_gpio_bit(pc, pin, REG_DIR, !out);
222
+}
223
+
224
+static int meson_pinconf_get_output(struct meson_pinctrl *pc,
225
+ unsigned int pin)
226
+{
227
+ int ret = meson_pinconf_get_gpio_bit(pc, pin, REG_DIR);
228
+
229
+ if (ret < 0)
230
+ return ret;
231
+
232
+ return !ret;
233
+}
234
+
235
+static int meson_pinconf_set_drive(struct meson_pinctrl *pc,
236
+ unsigned int pin,
237
+ bool high)
238
+{
239
+ return meson_pinconf_set_gpio_bit(pc, pin, REG_OUT, high);
240
+}
241
+
242
+static int meson_pinconf_get_drive(struct meson_pinctrl *pc,
243
+ unsigned int pin)
244
+{
245
+ return meson_pinconf_get_gpio_bit(pc, pin, REG_OUT);
246
+}
247
+
248
+static int meson_pinconf_set_output_drive(struct meson_pinctrl *pc,
249
+ unsigned int pin,
250
+ bool high)
251
+{
252
+ int ret;
253
+
254
+ ret = meson_pinconf_set_output(pc, pin, true);
255
+ if (ret)
256
+ return ret;
257
+
258
+ return meson_pinconf_set_drive(pc, pin, high);
259
+}
260
+
261
+static int meson_pinconf_disable_bias(struct meson_pinctrl *pc,
262
+ unsigned int pin)
263
+{
264
+ struct meson_bank *bank;
265
+ unsigned int reg, bit = 0;
266
+ int ret;
267
+
268
+ ret = meson_get_bank(pc, pin, &bank);
269
+ if (ret)
270
+ return ret;
271
+
272
+ meson_calc_reg_and_bit(bank, pin, REG_PULLEN, &reg, &bit);
273
+ ret = regmap_update_bits(pc->reg_pullen, reg, BIT(bit), 0);
274
+ if (ret)
275
+ return ret;
276
+
277
+ return 0;
278
+}
279
+
280
+static int meson_pinconf_enable_bias(struct meson_pinctrl *pc, unsigned int pin,
281
+ bool pull_up)
282
+{
283
+ struct meson_bank *bank;
284
+ unsigned int reg, bit, val = 0;
285
+ int ret;
286
+
287
+ ret = meson_get_bank(pc, pin, &bank);
288
+ if (ret)
289
+ return ret;
290
+
291
+ meson_calc_reg_and_bit(bank, pin, REG_PULL, &reg, &bit);
292
+ if (pull_up)
293
+ val = BIT(bit);
294
+
295
+ ret = regmap_update_bits(pc->reg_pull, reg, BIT(bit), val);
296
+ if (ret)
297
+ return ret;
298
+
299
+ meson_calc_reg_and_bit(bank, pin, REG_PULLEN, &reg, &bit);
300
+ ret = regmap_update_bits(pc->reg_pullen, reg, BIT(bit), BIT(bit));
301
+ if (ret)
302
+ return ret;
303
+
304
+ return 0;
305
+}
306
+
307
+static int meson_pinconf_set_drive_strength(struct meson_pinctrl *pc,
308
+ unsigned int pin,
309
+ u16 drive_strength_ua)
310
+{
311
+ struct meson_bank *bank;
312
+ unsigned int reg, bit, ds_val;
313
+ int ret;
314
+
315
+ if (!pc->reg_ds) {
316
+ dev_err(pc->dev, "drive-strength not supported\n");
317
+ return -ENOTSUPP;
318
+ }
319
+
320
+ ret = meson_get_bank(pc, pin, &bank);
321
+ if (ret)
322
+ return ret;
323
+
324
+ meson_calc_reg_and_bit(bank, pin, REG_DS, &reg, &bit);
325
+
326
+ if (drive_strength_ua <= 500) {
327
+ ds_val = MESON_PINCONF_DRV_500UA;
328
+ } else if (drive_strength_ua <= 2500) {
329
+ ds_val = MESON_PINCONF_DRV_2500UA;
330
+ } else if (drive_strength_ua <= 3000) {
331
+ ds_val = MESON_PINCONF_DRV_3000UA;
332
+ } else if (drive_strength_ua <= 4000) {
333
+ ds_val = MESON_PINCONF_DRV_4000UA;
334
+ } else {
335
+ dev_warn_once(pc->dev,
336
+ "pin %u: invalid drive-strength : %d , default to 4mA\n",
337
+ pin, drive_strength_ua);
338
+ ds_val = MESON_PINCONF_DRV_4000UA;
339
+ }
340
+
341
+ ret = regmap_update_bits(pc->reg_ds, reg, 0x3 << bit, ds_val << bit);
342
+ if (ret)
343
+ return ret;
344
+
345
+ return 0;
346
+}
347
+
348
+static int meson_pinconf_set(struct pinctrl_dev *pcdev, unsigned int pin,
349
+ unsigned long *configs, unsigned num_configs)
350
+{
351
+ struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
352
+ enum pin_config_param param;
353
+ unsigned int arg = 0;
354
+ int i, ret;
355
+
187356 for (i = 0; i < num_configs; i++) {
188357 param = pinconf_to_config_param(configs[i]);
189358
190359 switch (param) {
191
- case PIN_CONFIG_BIAS_DISABLE:
192
- dev_dbg(pc->dev, "pin %u: disable bias\n", pin);
360
+ case PIN_CONFIG_DRIVE_STRENGTH_UA:
361
+ case PIN_CONFIG_OUTPUT_ENABLE:
362
+ case PIN_CONFIG_OUTPUT:
363
+ arg = pinconf_to_config_argument(configs[i]);
364
+ break;
193365
194
- meson_calc_reg_and_bit(bank, pin, REG_PULLEN, &reg,
195
- &bit);
196
- ret = regmap_update_bits(pc->reg_pullen, reg,
197
- BIT(bit), 0);
198
- if (ret)
199
- return ret;
366
+ default:
367
+ break;
368
+ }
369
+
370
+ switch (param) {
371
+ case PIN_CONFIG_BIAS_DISABLE:
372
+ ret = meson_pinconf_disable_bias(pc, pin);
200373 break;
201374 case PIN_CONFIG_BIAS_PULL_UP:
202
- dev_dbg(pc->dev, "pin %u: enable pull-up\n", pin);
203
-
204
- meson_calc_reg_and_bit(bank, pin, REG_PULLEN,
205
- &reg, &bit);
206
- ret = regmap_update_bits(pc->reg_pullen, reg,
207
- BIT(bit), BIT(bit));
208
- if (ret)
209
- return ret;
210
-
211
- meson_calc_reg_and_bit(bank, pin, REG_PULL, &reg, &bit);
212
- ret = regmap_update_bits(pc->reg_pull, reg,
213
- BIT(bit), BIT(bit));
214
- if (ret)
215
- return ret;
375
+ ret = meson_pinconf_enable_bias(pc, pin, true);
216376 break;
217377 case PIN_CONFIG_BIAS_PULL_DOWN:
218
- dev_dbg(pc->dev, "pin %u: enable pull-down\n", pin);
219
-
220
- meson_calc_reg_and_bit(bank, pin, REG_PULLEN,
221
- &reg, &bit);
222
- ret = regmap_update_bits(pc->reg_pullen, reg,
223
- BIT(bit), BIT(bit));
224
- if (ret)
225
- return ret;
226
-
227
- meson_calc_reg_and_bit(bank, pin, REG_PULL, &reg, &bit);
228
- ret = regmap_update_bits(pc->reg_pull, reg,
229
- BIT(bit), 0);
230
- if (ret)
231
- return ret;
378
+ ret = meson_pinconf_enable_bias(pc, pin, false);
379
+ break;
380
+ case PIN_CONFIG_DRIVE_STRENGTH_UA:
381
+ ret = meson_pinconf_set_drive_strength(pc, pin, arg);
382
+ break;
383
+ case PIN_CONFIG_OUTPUT_ENABLE:
384
+ ret = meson_pinconf_set_output(pc, pin, arg);
385
+ break;
386
+ case PIN_CONFIG_OUTPUT:
387
+ ret = meson_pinconf_set_output_drive(pc, pin, arg);
232388 break;
233389 default:
234
- return -ENOTSUPP;
390
+ ret = -ENOTSUPP;
235391 }
392
+
393
+ if (ret)
394
+ return ret;
236395 }
237396
238397 return 0;
....@@ -272,12 +431,55 @@
272431 return conf;
273432 }
274433
434
+static int meson_pinconf_get_drive_strength(struct meson_pinctrl *pc,
435
+ unsigned int pin,
436
+ u16 *drive_strength_ua)
437
+{
438
+ struct meson_bank *bank;
439
+ unsigned int reg, bit;
440
+ unsigned int val;
441
+ int ret;
442
+
443
+ if (!pc->reg_ds)
444
+ return -ENOTSUPP;
445
+
446
+ ret = meson_get_bank(pc, pin, &bank);
447
+ if (ret)
448
+ return ret;
449
+
450
+ meson_calc_reg_and_bit(bank, pin, REG_DS, &reg, &bit);
451
+
452
+ ret = regmap_read(pc->reg_ds, reg, &val);
453
+ if (ret)
454
+ return ret;
455
+
456
+ switch ((val >> bit) & 0x3) {
457
+ case MESON_PINCONF_DRV_500UA:
458
+ *drive_strength_ua = 500;
459
+ break;
460
+ case MESON_PINCONF_DRV_2500UA:
461
+ *drive_strength_ua = 2500;
462
+ break;
463
+ case MESON_PINCONF_DRV_3000UA:
464
+ *drive_strength_ua = 3000;
465
+ break;
466
+ case MESON_PINCONF_DRV_4000UA:
467
+ *drive_strength_ua = 4000;
468
+ break;
469
+ default:
470
+ return -EINVAL;
471
+ }
472
+
473
+ return 0;
474
+}
475
+
275476 static int meson_pinconf_get(struct pinctrl_dev *pcdev, unsigned int pin,
276477 unsigned long *config)
277478 {
278479 struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
279480 enum pin_config_param param = pinconf_to_config_param(*config);
280481 u16 arg;
482
+ int ret;
281483
282484 switch (param) {
283485 case PIN_CONFIG_BIAS_DISABLE:
....@@ -288,6 +490,29 @@
288490 else
289491 return -EINVAL;
290492 break;
493
+ case PIN_CONFIG_DRIVE_STRENGTH_UA:
494
+ ret = meson_pinconf_get_drive_strength(pc, pin, &arg);
495
+ if (ret)
496
+ return ret;
497
+ break;
498
+ case PIN_CONFIG_OUTPUT_ENABLE:
499
+ ret = meson_pinconf_get_output(pc, pin);
500
+ if (ret <= 0)
501
+ return -EINVAL;
502
+ arg = 1;
503
+ break;
504
+ case PIN_CONFIG_OUTPUT:
505
+ ret = meson_pinconf_get_output(pc, pin);
506
+ if (ret <= 0)
507
+ return -EINVAL;
508
+
509
+ ret = meson_pinconf_get_drive(pc, pin);
510
+ if (ret < 0)
511
+ return -EINVAL;
512
+
513
+ arg = ret;
514
+ break;
515
+
291516 default:
292517 return -ENOTSUPP;
293518 }
....@@ -330,58 +555,33 @@
330555 .is_generic = true,
331556 };
332557
333
-static int meson_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
558
+static int meson_gpio_get_direction(struct gpio_chip *chip, unsigned gpio)
334559 {
335560 struct meson_pinctrl *pc = gpiochip_get_data(chip);
336
- unsigned int reg, bit;
337
- struct meson_bank *bank;
338561 int ret;
339562
340
- ret = meson_get_bank(pc, gpio, &bank);
341
- if (ret)
563
+ ret = meson_pinconf_get_output(pc, gpio);
564
+ if (ret < 0)
342565 return ret;
343566
344
- meson_calc_reg_and_bit(bank, gpio, REG_DIR, &reg, &bit);
567
+ return ret ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
568
+}
345569
346
- return regmap_update_bits(pc->reg_gpio, reg, BIT(bit), BIT(bit));
570
+static int meson_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
571
+{
572
+ return meson_pinconf_set_output(gpiochip_get_data(chip), gpio, false);
347573 }
348574
349575 static int meson_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
350576 int value)
351577 {
352
- struct meson_pinctrl *pc = gpiochip_get_data(chip);
353
- unsigned int reg, bit;
354
- struct meson_bank *bank;
355
- int ret;
356
-
357
- ret = meson_get_bank(pc, gpio, &bank);
358
- if (ret)
359
- return ret;
360
-
361
- meson_calc_reg_and_bit(bank, gpio, REG_DIR, &reg, &bit);
362
- ret = regmap_update_bits(pc->reg_gpio, reg, BIT(bit), 0);
363
- if (ret)
364
- return ret;
365
-
366
- meson_calc_reg_and_bit(bank, gpio, REG_OUT, &reg, &bit);
367
- return regmap_update_bits(pc->reg_gpio, reg, BIT(bit),
368
- value ? BIT(bit) : 0);
578
+ return meson_pinconf_set_output_drive(gpiochip_get_data(chip),
579
+ gpio, value);
369580 }
370581
371582 static void meson_gpio_set(struct gpio_chip *chip, unsigned gpio, int value)
372583 {
373
- struct meson_pinctrl *pc = gpiochip_get_data(chip);
374
- unsigned int reg, bit;
375
- struct meson_bank *bank;
376
- int ret;
377
-
378
- ret = meson_get_bank(pc, gpio, &bank);
379
- if (ret)
380
- return;
381
-
382
- meson_calc_reg_and_bit(bank, gpio, REG_OUT, &reg, &bit);
383
- regmap_update_bits(pc->reg_gpio, reg, BIT(bit),
384
- value ? BIT(bit) : 0);
584
+ meson_pinconf_set_drive(gpiochip_get_data(chip), gpio, value);
385585 }
386586
387587 static int meson_gpio_get(struct gpio_chip *chip, unsigned gpio)
....@@ -409,6 +609,8 @@
409609 pc->chip.parent = pc->dev;
410610 pc->chip.request = gpiochip_generic_request;
411611 pc->chip.free = gpiochip_generic_free;
612
+ pc->chip.set_config = gpiochip_generic_config;
613
+ pc->chip.get_direction = meson_gpio_get_direction;
412614 pc->chip.direction_input = meson_gpio_direction_input;
413615 pc->chip.direction_output = meson_gpio_direction_output;
414616 pc->chip.get = meson_gpio_get;
....@@ -444,7 +646,7 @@
444646
445647 i = of_property_match_string(node, "reg-names", name);
446648 if (of_address_to_resource(node, i, &res))
447
- return ERR_PTR(-ENOENT);
649
+ return NULL;
448650
449651 base = devm_ioremap_resource(pc->dev, &res);
450652 if (IS_ERR(base))
....@@ -452,7 +654,7 @@
452654
453655 meson_regmap_config.max_register = resource_size(&res) - 4;
454656 meson_regmap_config.name = devm_kasprintf(pc->dev, GFP_KERNEL,
455
- "%s-%s", node->name,
657
+ "%pOFn-%s", node,
456658 name);
457659 if (!meson_regmap_config.name)
458660 return ERR_PTR(-ENOMEM);
....@@ -470,6 +672,7 @@
470672 continue;
471673 if (gpio_np) {
472674 dev_err(pc->dev, "multiple gpio nodes\n");
675
+ of_node_put(np);
473676 return -EINVAL;
474677 }
475678 gpio_np = np;
....@@ -483,30 +686,57 @@
483686 pc->of_node = gpio_np;
484687
485688 pc->reg_mux = meson_map_resource(pc, gpio_np, "mux");
486
- if (IS_ERR(pc->reg_mux)) {
689
+ if (IS_ERR_OR_NULL(pc->reg_mux)) {
487690 dev_err(pc->dev, "mux registers not found\n");
488
- return PTR_ERR(pc->reg_mux);
691
+ return pc->reg_mux ? PTR_ERR(pc->reg_mux) : -ENOENT;
692
+ }
693
+
694
+ pc->reg_gpio = meson_map_resource(pc, gpio_np, "gpio");
695
+ if (IS_ERR_OR_NULL(pc->reg_gpio)) {
696
+ dev_err(pc->dev, "gpio registers not found\n");
697
+ return pc->reg_gpio ? PTR_ERR(pc->reg_gpio) : -ENOENT;
489698 }
490699
491700 pc->reg_pull = meson_map_resource(pc, gpio_np, "pull");
492
- if (IS_ERR(pc->reg_pull)) {
493
- dev_err(pc->dev, "pull registers not found\n");
494
- return PTR_ERR(pc->reg_pull);
495
- }
701
+ if (IS_ERR(pc->reg_pull))
702
+ pc->reg_pull = NULL;
496703
497704 pc->reg_pullen = meson_map_resource(pc, gpio_np, "pull-enable");
498
- /* Use pull region if pull-enable one is not present */
499705 if (IS_ERR(pc->reg_pullen))
500
- pc->reg_pullen = pc->reg_pull;
706
+ pc->reg_pullen = NULL;
501707
502
- pc->reg_gpio = meson_map_resource(pc, gpio_np, "gpio");
503
- if (IS_ERR(pc->reg_gpio)) {
504
- dev_err(pc->dev, "gpio registers not found\n");
505
- return PTR_ERR(pc->reg_gpio);
708
+ pc->reg_ds = meson_map_resource(pc, gpio_np, "ds");
709
+ if (IS_ERR(pc->reg_ds)) {
710
+ dev_dbg(pc->dev, "ds registers not found - skipping\n");
711
+ pc->reg_ds = NULL;
506712 }
713
+
714
+ if (pc->data->parse_dt)
715
+ return pc->data->parse_dt(pc);
507716
508717 return 0;
509718 }
719
+
720
+int meson8_aobus_parse_dt_extra(struct meson_pinctrl *pc)
721
+{
722
+ if (!pc->reg_pull)
723
+ return -EINVAL;
724
+
725
+ pc->reg_pullen = pc->reg_pull;
726
+
727
+ return 0;
728
+}
729
+EXPORT_SYMBOL_GPL(meson8_aobus_parse_dt_extra);
730
+
731
+int meson_a1_parse_dt_extra(struct meson_pinctrl *pc)
732
+{
733
+ pc->reg_pull = pc->reg_gpio;
734
+ pc->reg_pullen = pc->reg_gpio;
735
+ pc->reg_ds = pc->reg_gpio;
736
+
737
+ return 0;
738
+}
739
+EXPORT_SYMBOL_GPL(meson_a1_parse_dt_extra);
510740
511741 int meson_pinctrl_probe(struct platform_device *pdev)
512742 {
....@@ -541,3 +771,6 @@
541771
542772 return meson_gpiolib_register(pc);
543773 }
774
+EXPORT_SYMBOL_GPL(meson_pinctrl_probe);
775
+
776
+MODULE_LICENSE("GPL v2");