diff options
Diffstat (limited to 'arch/arm/mach-tegra/board-pinmux.c')
| -rw-r--r-- | arch/arm/mach-tegra/board-pinmux.c | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/board-pinmux.c b/arch/arm/mach-tegra/board-pinmux.c new file mode 100644 index 000000000000..adc3efe979b3 --- /dev/null +++ b/arch/arm/mach-tegra/board-pinmux.c | |||
| @@ -0,0 +1,104 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2011, NVIDIA CORPORATION. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is licensed under the terms of the GNU General Public | ||
| 5 | * License version 2, as published by the Free Software Foundation, and | ||
| 6 | * may be copied, distributed, and modified under those terms. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/device.h> | ||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/notifier.h> | ||
| 18 | #include <linux/of.h> | ||
| 19 | #include <linux/string.h> | ||
| 20 | |||
| 21 | #include <mach/gpio-tegra.h> | ||
| 22 | #include <mach/pinmux.h> | ||
| 23 | |||
| 24 | #include "board-pinmux.h" | ||
| 25 | #include "devices.h" | ||
| 26 | |||
| 27 | struct tegra_board_pinmux_conf *confs[2]; | ||
| 28 | |||
| 29 | static void tegra_board_pinmux_setup_gpios(void) | ||
| 30 | { | ||
| 31 | int i; | ||
| 32 | |||
| 33 | for (i = 0; i < ARRAY_SIZE(confs); i++) { | ||
| 34 | if (!confs[i]) | ||
| 35 | continue; | ||
| 36 | |||
| 37 | tegra_gpio_config(confs[i]->gpios, confs[i]->gpio_count); | ||
| 38 | } | ||
| 39 | } | ||
| 40 | |||
| 41 | static void tegra_board_pinmux_setup_pinmux(void) | ||
| 42 | { | ||
| 43 | int i; | ||
| 44 | |||
| 45 | for (i = 0; i < ARRAY_SIZE(confs); i++) { | ||
| 46 | if (!confs[i]) | ||
| 47 | continue; | ||
| 48 | |||
| 49 | tegra_pinmux_config_table(confs[i]->pgs, confs[i]->pg_count); | ||
| 50 | |||
| 51 | if (confs[i]->drives) | ||
| 52 | tegra_drive_pinmux_config_table(confs[i]->drives, | ||
| 53 | confs[i]->drive_count); | ||
| 54 | } | ||
| 55 | } | ||
| 56 | |||
| 57 | static int tegra_board_pinmux_bus_notify(struct notifier_block *nb, | ||
| 58 | unsigned long event, void *vdev) | ||
| 59 | { | ||
| 60 | static bool had_gpio; | ||
| 61 | static bool had_pinmux; | ||
| 62 | |||
| 63 | struct device *dev = vdev; | ||
| 64 | const char *devname; | ||
| 65 | |||
| 66 | if (event != BUS_NOTIFY_BOUND_DRIVER) | ||
| 67 | return NOTIFY_DONE; | ||
| 68 | |||
| 69 | devname = dev_name(dev); | ||
| 70 | |||
| 71 | if (!had_gpio && !strcmp(devname, GPIO_DEV)) { | ||
| 72 | tegra_board_pinmux_setup_gpios(); | ||
| 73 | had_gpio = true; | ||
| 74 | } else if (!had_pinmux && !strcmp(devname, PINMUX_DEV)) { | ||
| 75 | tegra_board_pinmux_setup_pinmux(); | ||
| 76 | had_pinmux = true; | ||
| 77 | } | ||
| 78 | |||
| 79 | if (had_gpio && had_pinmux) | ||
| 80 | return NOTIFY_STOP_MASK; | ||
| 81 | else | ||
| 82 | return NOTIFY_DONE; | ||
| 83 | } | ||
| 84 | |||
| 85 | static struct notifier_block nb = { | ||
| 86 | .notifier_call = tegra_board_pinmux_bus_notify, | ||
| 87 | }; | ||
| 88 | |||
| 89 | static struct platform_device *devices[] = { | ||
| 90 | &tegra_gpio_device, | ||
| 91 | &tegra_pinmux_device, | ||
| 92 | }; | ||
| 93 | |||
| 94 | void tegra_board_pinmux_init(struct tegra_board_pinmux_conf *conf_a, | ||
| 95 | struct tegra_board_pinmux_conf *conf_b) | ||
| 96 | { | ||
| 97 | confs[0] = conf_a; | ||
| 98 | confs[1] = conf_b; | ||
| 99 | |||
| 100 | bus_register_notifier(&platform_bus_type, &nb); | ||
| 101 | |||
| 102 | if (!of_machine_is_compatible("nvidia,tegra20")) | ||
| 103 | platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
| 104 | } | ||
