Commit 8e51c0f254063f4da2e91c2cf47fad37285be73d
dm: gpio: Add DM compatibility to GPIO driver for Davinci
This adds DM_GPIO support for the davinici GPIO driver with DT support. Signed-off-by: Adam Ford <aford173@gmail.com>
Showing 5 changed files with 186 additions and 27 deletions Side-by-side Diff
... | ... | @@ -39,7 +39,7 @@ |
39 | 39 | unsigned int irq_num; |
40 | 40 | unsigned int irq_mask; |
41 | 41 | unsigned long *in_use; |
42 | - unsigned long base; | |
42 | + struct davinci_gpio *base; | |
43 | 43 | }; |
44 | 44 | |
45 | 45 | #define davinci_gpio_bank01 ((struct davinci_gpio *)DAVINCI_GPIO_BANK01) |
46 | 46 | |
... | ... | @@ -48,7 +48,9 @@ |
48 | 48 | #define davinci_gpio_bank67 ((struct davinci_gpio *)DAVINCI_GPIO_BANK67) |
49 | 49 | #define davinci_gpio_bank8 ((struct davinci_gpio *)DAVINCI_GPIO_BANK8) |
50 | 50 | |
51 | +#ifndef CONFIG_DM_GPIO | |
51 | 52 | #define gpio_status() gpio_info() |
53 | +#endif | |
52 | 54 | #define GPIO_NAME_SIZE 20 |
53 | 55 | #if defined(CONFIG_SOC_DM644X) |
54 | 56 | /* GPIO0 to GPIO53, omit the V3.3 volts one */ |
... | ... | @@ -62,6 +64,16 @@ |
62 | 64 | #define GPIO_BIT(gp) ((gp) & 0x1F) |
63 | 65 | |
64 | 66 | void gpio_info(void); |
67 | + | |
68 | +#ifdef CONFIG_DM_GPIO | |
69 | + | |
70 | +/* Information about a GPIO bank */ | |
71 | +struct davinci_gpio_platdata { | |
72 | + int bank_index; | |
73 | + ulong base; /* address of registers in physical memory */ | |
74 | + const char *port_name; | |
75 | +}; | |
76 | +#endif | |
65 | 77 | |
66 | 78 | #endif |
... | ... | @@ -9,6 +9,7 @@ |
9 | 9 | */ |
10 | 10 | |
11 | 11 | #include <common.h> |
12 | +#include <dm.h> | |
12 | 13 | #include <environment.h> |
13 | 14 | #include <i2c.h> |
14 | 15 | #include <net.h> |
... | ... | @@ -24,6 +25,7 @@ |
24 | 25 | #include <linux/errno.h> |
25 | 26 | #include <hwconfig.h> |
26 | 27 | #include <asm/mach-types.h> |
28 | +#include <asm/gpio.h> | |
27 | 29 | |
28 | 30 | #ifdef CONFIG_MMC_DAVINCI |
29 | 31 | #include <mmc.h> |
... | ... | @@ -23,7 +23,6 @@ |
23 | 23 | CONFIG_CRC32_VERIFY=y |
24 | 24 | # CONFIG_CMD_EEPROM is not set |
25 | 25 | # CONFIG_CMD_FLASH is not set |
26 | -# CONFIG_CMD_GPIO is not set | |
27 | 26 | # CONFIG_CMD_GPT is not set |
28 | 27 | # CONFIG_CMD_PART is not set |
29 | 28 | # CONFIG_CMD_SETEXPR is not set |
... | ... | @@ -37,6 +36,7 @@ |
37 | 36 | CONFIG_OF_CONTROL=y |
38 | 37 | CONFIG_ENV_IS_IN_SPI_FLASH=y |
39 | 38 | CONFIG_DM=y |
39 | +CONFIG_DM_GPIO=y | |
40 | 40 | CONFIG_DM_I2C=y |
41 | 41 | CONFIG_DM_I2C_COMPAT=y |
42 | 42 | CONFIG_DM_SPI_FLASH=y |
... | ... | @@ -7,11 +7,14 @@ |
7 | 7 | */ |
8 | 8 | |
9 | 9 | #include <common.h> |
10 | +#include <dm.h> | |
11 | +#include <fdtdec.h> | |
10 | 12 | #include <asm/io.h> |
11 | 13 | #include <asm/gpio.h> |
12 | 14 | #include <asm/arch/hardware.h> |
13 | 15 | #include <asm/arch/davinci_misc.h> |
14 | 16 | |
17 | +#ifndef CONFIG_DM_GPIO | |
15 | 18 | static struct gpio_registry { |
16 | 19 | int is_registered; |
17 | 20 | char name[GPIO_NAME_SIZE]; |
... | ... | @@ -303,7 +306,7 @@ |
303 | 306 | #define davinci_configure_pin_mux(a, b) |
304 | 307 | #endif /* CONFIG_SOC_DA8XX */ |
305 | 308 | |
306 | -int gpio_request(unsigned gpio, const char *label) | |
309 | +int gpio_request(unsigned int gpio, const char *label) | |
307 | 310 | { |
308 | 311 | if (gpio >= MAX_NUM_GPIOS) |
309 | 312 | return -1; |
... | ... | @@ -320,7 +323,7 @@ |
320 | 323 | return 0; |
321 | 324 | } |
322 | 325 | |
323 | -int gpio_free(unsigned gpio) | |
326 | +int gpio_free(unsigned int gpio) | |
324 | 327 | { |
325 | 328 | if (gpio >= MAX_NUM_GPIOS) |
326 | 329 | return -1; |
327 | 330 | |
328 | 331 | |
329 | 332 | |
330 | 333 | |
331 | 334 | |
332 | 335 | |
333 | 336 | |
334 | 337 | |
335 | 338 | |
... | ... | @@ -333,42 +336,30 @@ |
333 | 336 | /* Do not configure as input or change pin mux here */ |
334 | 337 | return 0; |
335 | 338 | } |
339 | +#endif | |
336 | 340 | |
337 | -int gpio_direction_input(unsigned gpio) | |
341 | +static int _gpio_direction_output(struct davinci_gpio *bank, unsigned int gpio, int value) | |
338 | 342 | { |
339 | - struct davinci_gpio *bank; | |
340 | - | |
341 | - bank = GPIO_BANK(gpio); | |
342 | - setbits_le32(&bank->dir, 1U << GPIO_BIT(gpio)); | |
343 | + clrbits_le32(&bank->dir, 1U << GPIO_BIT(gpio)); | |
344 | + gpio_set_value(gpio, value); | |
343 | 345 | return 0; |
344 | 346 | } |
345 | 347 | |
346 | -int gpio_direction_output(unsigned gpio, int value) | |
348 | +static int _gpio_direction_input(struct davinci_gpio *bank, unsigned int gpio) | |
347 | 349 | { |
348 | - struct davinci_gpio *bank; | |
349 | - | |
350 | - bank = GPIO_BANK(gpio); | |
351 | - clrbits_le32(&bank->dir, 1U << GPIO_BIT(gpio)); | |
352 | - gpio_set_value(gpio, value); | |
350 | + setbits_le32(&bank->dir, 1U << GPIO_BIT(gpio)); | |
353 | 351 | return 0; |
354 | 352 | } |
355 | 353 | |
356 | -int gpio_get_value(unsigned gpio) | |
354 | +static int _gpio_get_value(struct davinci_gpio *bank, unsigned int gpio) | |
357 | 355 | { |
358 | - struct davinci_gpio *bank; | |
359 | 356 | unsigned int ip; |
360 | - | |
361 | - bank = GPIO_BANK(gpio); | |
362 | 357 | ip = in_le32(&bank->in_data) & (1U << GPIO_BIT(gpio)); |
363 | 358 | return ip ? 1 : 0; |
364 | 359 | } |
365 | 360 | |
366 | -int gpio_set_value(unsigned gpio, int value) | |
361 | +static int _gpio_set_value(struct davinci_gpio *bank, unsigned int gpio, int value) | |
367 | 362 | { |
368 | - struct davinci_gpio *bank; | |
369 | - | |
370 | - bank = GPIO_BANK(gpio); | |
371 | - | |
372 | 363 | if (value) |
373 | 364 | bank->set_data = 1U << GPIO_BIT(gpio); |
374 | 365 | else |
375 | 366 | |
376 | 367 | |
... | ... | @@ -377,14 +368,21 @@ |
377 | 368 | return 0; |
378 | 369 | } |
379 | 370 | |
371 | +static int _gpio_get_dir(struct davinci_gpio *bank, unsigned int gpio) | |
372 | +{ | |
373 | + return in_le32(&bank->dir) & (1U << GPIO_BIT(gpio)); | |
374 | +} | |
375 | + | |
376 | +#ifndef CONFIG_DM_GPIO | |
377 | + | |
380 | 378 | void gpio_info(void) |
381 | 379 | { |
382 | - unsigned gpio, dir, val; | |
380 | + unsigned int gpio, dir, val; | |
383 | 381 | struct davinci_gpio *bank; |
384 | 382 | |
385 | 383 | for (gpio = 0; gpio < MAX_NUM_GPIOS; ++gpio) { |
386 | 384 | bank = GPIO_BANK(gpio); |
387 | - dir = in_le32(&bank->dir) & (1U << GPIO_BIT(gpio)); | |
385 | + dir = _gpio_get_dir(bank, gpio); | |
388 | 386 | val = gpio_get_value(gpio); |
389 | 387 | |
390 | 388 | printf("% 4d: %s: %d [%c] %s\n", |
... | ... | @@ -393,4 +391,151 @@ |
393 | 391 | gpio_registry[gpio].name); |
394 | 392 | } |
395 | 393 | } |
394 | + | |
395 | +int gpio_direction_input(unsigned int gpio) | |
396 | +{ | |
397 | + struct davinci_gpio *bank; | |
398 | + | |
399 | + bank = GPIO_BANK(gpio); | |
400 | + return _gpio_direction_input(bank, gpio); | |
401 | +} | |
402 | + | |
403 | +int gpio_direction_output(unsigned int gpio, int value) | |
404 | +{ | |
405 | + struct davinci_gpio *bank; | |
406 | + | |
407 | + bank = GPIO_BANK(gpio); | |
408 | + return _gpio_direction_output(bank, gpio, value); | |
409 | +} | |
410 | + | |
411 | +int gpio_get_value(unsigned int gpio) | |
412 | +{ | |
413 | + struct davinci_gpio *bank; | |
414 | + | |
415 | + bank = GPIO_BANK(gpio); | |
416 | + return _gpio_get_value(bank, gpio); | |
417 | +} | |
418 | + | |
419 | +int gpio_set_value(unsigned int gpio, int value) | |
420 | +{ | |
421 | + struct davinci_gpio *bank; | |
422 | + | |
423 | + bank = GPIO_BANK(gpio); | |
424 | + return _gpio_set_value(bank, gpio, value); | |
425 | +} | |
426 | + | |
427 | +#else /* CONFIG_DM_GPIO */ | |
428 | + | |
429 | +static struct davinci_gpio *davinci_get_gpio_bank(struct udevice *dev, unsigned int offset) | |
430 | +{ | |
431 | + struct davinci_gpio_bank *bank = dev_get_priv(dev); | |
432 | + | |
433 | + /* The device tree is not broken into banks but the infrastructure is | |
434 | + * expecting it this way, so we'll first include the 0x10 offset, then | |
435 | + * calculate the bank manually based on the offset. | |
436 | + */ | |
437 | + | |
438 | + return ((struct davinci_gpio *)bank->base) + 0x10 + (offset >> 5); | |
439 | +} | |
440 | + | |
441 | +static int davinci_gpio_direction_input(struct udevice *dev, unsigned int offset) | |
442 | +{ | |
443 | + struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset); | |
444 | + | |
445 | + _gpio_direction_input(base, offset); | |
446 | + return 0; | |
447 | +} | |
448 | + | |
449 | +static int davinci_gpio_direction_output(struct udevice *dev, unsigned int offset, | |
450 | + int value) | |
451 | +{ | |
452 | + struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset); | |
453 | + | |
454 | + _gpio_direction_output(base, offset, value); | |
455 | + return 0; | |
456 | +} | |
457 | + | |
458 | +static int davinci_gpio_get_value(struct udevice *dev, unsigned int offset) | |
459 | +{ | |
460 | + struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset); | |
461 | + | |
462 | + return _gpio_get_value(base, offset); | |
463 | +} | |
464 | + | |
465 | +static int davinci_gpio_set_value(struct udevice *dev, unsigned int offset, | |
466 | + int value) | |
467 | +{ | |
468 | + struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset); | |
469 | + | |
470 | + _gpio_set_value(base, offset, value); | |
471 | + | |
472 | + return 0; | |
473 | +} | |
474 | + | |
475 | +static int davinci_gpio_get_function(struct udevice *dev, unsigned int offset) | |
476 | +{ | |
477 | + unsigned int dir; | |
478 | + struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset); | |
479 | + | |
480 | + dir = _gpio_get_dir(base, offset); | |
481 | + | |
482 | + if (dir) | |
483 | + return GPIOF_INPUT; | |
484 | + | |
485 | + return GPIOF_OUTPUT; | |
486 | +} | |
487 | + | |
488 | +static const struct dm_gpio_ops gpio_davinci_ops = { | |
489 | + .direction_input = davinci_gpio_direction_input, | |
490 | + .direction_output = davinci_gpio_direction_output, | |
491 | + .get_value = davinci_gpio_get_value, | |
492 | + .set_value = davinci_gpio_set_value, | |
493 | + .get_function = davinci_gpio_get_function, | |
494 | +}; | |
495 | + | |
496 | +static int davinci_gpio_probe(struct udevice *dev) | |
497 | +{ | |
498 | + struct davinci_gpio_bank *bank = dev_get_priv(dev); | |
499 | + struct davinci_gpio_platdata *plat = dev_get_platdata(dev); | |
500 | + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); | |
501 | + const void *fdt = gd->fdt_blob; | |
502 | + int node = dev_of_offset(dev); | |
503 | + | |
504 | + uc_priv->bank_name = plat->port_name; | |
505 | + uc_priv->gpio_count = fdtdec_get_int(fdt, node, "ti,ngpio", -1); | |
506 | + bank->base = (struct davinci_gpio *)plat->base; | |
507 | + return 0; | |
508 | +} | |
509 | + | |
510 | +static const struct udevice_id davinci_gpio_ids[] = { | |
511 | + { .compatible = "ti,dm6441-gpio" }, | |
512 | + { } | |
513 | +}; | |
514 | + | |
515 | +static int davinci_gpio_ofdata_to_platdata(struct udevice *dev) | |
516 | +{ | |
517 | + struct davinci_gpio_platdata *plat = dev_get_platdata(dev); | |
518 | + fdt_addr_t addr; | |
519 | + | |
520 | + addr = devfdt_get_addr(dev); | |
521 | + if (addr == FDT_ADDR_T_NONE) | |
522 | + return -EINVAL; | |
523 | + | |
524 | + plat->base = addr; | |
525 | + return 0; | |
526 | +} | |
527 | + | |
528 | +U_BOOT_DRIVER(gpio_davinci) = { | |
529 | + .name = "gpio_davinci", | |
530 | + .id = UCLASS_GPIO, | |
531 | + .ops = &gpio_davinci_ops, | |
532 | + .ofdata_to_platdata = of_match_ptr(davinci_gpio_ofdata_to_platdata), | |
533 | + .of_match = davinci_gpio_ids, | |
534 | + .bind = dm_scan_fdt_dev, | |
535 | + .platdata_auto_alloc_size = sizeof(struct davinci_gpio_platdata), | |
536 | + .probe = davinci_gpio_probe, | |
537 | + .priv_auto_alloc_size = sizeof(struct davinci_gpio_bank), | |
538 | +}; | |
539 | + | |
540 | +#endif |
... | ... | @@ -40,7 +40,6 @@ |
40 | 40 | |
41 | 41 | #ifdef CONFIG_DIRECT_NOR_BOOT |
42 | 42 | #define CONFIG_ARCH_CPU_INIT |
43 | -#define CONFIG_DA8XX_GPIO | |
44 | 43 | #define CONFIG_SYS_DV_NOR_BOOT_CFG (0x11) |
45 | 44 | #endif |
46 | 45 | |
... | ... | @@ -227,6 +226,7 @@ |
227 | 226 | #define CONFIG_MTD_PARTITIONS /* required for UBI partition support */ |
228 | 227 | #endif |
229 | 228 | |
229 | +#define CONFIG_DA8XX_GPIO | |
230 | 230 | /* |
231 | 231 | * U-Boot general configuration |
232 | 232 | */ |
-
mentioned in commit 1eddf5
-
mentioned in commit 1eddf5
-
mentioned in commit 1eddf5
-
mentioned in commit 313502
-
mentioned in commit 1eddf5
-
mentioned in commit 313502
-
mentioned in commit 1eddf5
-
mentioned in commit 313502
-
mentioned in commit 1eddf5
-
mentioned in commit 313502
-
mentioned in commit 1eddf5
-
mentioned in commit 1eddf5
-
mentioned in commit 313502
-
mentioned in commit 313502
-
mentioned in commit 1eddf5
-
mentioned in commit 313502
-
mentioned in commit 1eddf5
-
mentioned in commit 313502
-
mentioned in commit 1eddf5
-
mentioned in commit 313502
-
mentioned in commit 1eddf5
-
mentioned in commit 313502
-
mentioned in commit 1eddf5
-
mentioned in commit 313502
-
mentioned in commit 1eddf5
-
mentioned in commit 313502
-
mentioned in commit 1eddf5
-
mentioned in commit 313502