Bryan Huntsman | 3f2bc4d | 2011-08-16 17:27:22 -0700 | [diff] [blame] | 1 | /* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved. |
Gregory Bean | 1963a2a | 2010-08-28 10:05:44 -0700 | [diff] [blame] | 2 | * |
| 3 | * This program is free software; you can redistribute it and/or modify |
| 4 | * it under the terms of the GNU General Public License version 2 and |
| 5 | * only version 2 as published by the Free Software Foundation. |
| 6 | * |
| 7 | * This program is distributed in the hope that it will be useful, |
| 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 10 | * GNU General Public License for more details. |
Gregory Bean | 1963a2a | 2010-08-28 10:05:44 -0700 | [diff] [blame] | 11 | */ |
| 12 | #ifndef __ARCH_ARM_MACH_MSM_GPIOMUX_H |
| 13 | #define __ARCH_ARM_MACH_MSM_GPIOMUX_H |
| 14 | |
| 15 | #include <linux/bitops.h> |
Gregory Bean | ab78cde | 2010-09-01 16:26:12 -0700 | [diff] [blame] | 16 | #include <linux/errno.h> |
Gregory Bean | 1963a2a | 2010-08-28 10:05:44 -0700 | [diff] [blame] | 17 | |
Bryan Huntsman | 3f2bc4d | 2011-08-16 17:27:22 -0700 | [diff] [blame] | 18 | enum msm_gpiomux_setting { |
| 19 | GPIOMUX_ACTIVE = 0, |
| 20 | GPIOMUX_SUSPENDED, |
| 21 | GPIOMUX_NSETTINGS |
| 22 | }; |
| 23 | |
| 24 | enum gpiomux_drv { |
| 25 | GPIOMUX_DRV_2MA = 0, |
| 26 | GPIOMUX_DRV_4MA, |
| 27 | GPIOMUX_DRV_6MA, |
| 28 | GPIOMUX_DRV_8MA, |
| 29 | GPIOMUX_DRV_10MA, |
| 30 | GPIOMUX_DRV_12MA, |
| 31 | GPIOMUX_DRV_14MA, |
| 32 | GPIOMUX_DRV_16MA, |
| 33 | }; |
| 34 | |
| 35 | enum gpiomux_func { |
| 36 | GPIOMUX_FUNC_GPIO = 0, |
| 37 | GPIOMUX_FUNC_1, |
| 38 | GPIOMUX_FUNC_2, |
| 39 | GPIOMUX_FUNC_3, |
| 40 | GPIOMUX_FUNC_4, |
| 41 | GPIOMUX_FUNC_5, |
| 42 | GPIOMUX_FUNC_6, |
| 43 | GPIOMUX_FUNC_7, |
| 44 | GPIOMUX_FUNC_8, |
| 45 | GPIOMUX_FUNC_9, |
| 46 | GPIOMUX_FUNC_A, |
| 47 | GPIOMUX_FUNC_B, |
| 48 | GPIOMUX_FUNC_C, |
| 49 | GPIOMUX_FUNC_D, |
| 50 | GPIOMUX_FUNC_E, |
| 51 | GPIOMUX_FUNC_F, |
| 52 | }; |
| 53 | |
| 54 | enum gpiomux_pull { |
| 55 | GPIOMUX_PULL_NONE = 0, |
| 56 | GPIOMUX_PULL_DOWN, |
| 57 | GPIOMUX_PULL_KEEPER, |
| 58 | GPIOMUX_PULL_UP, |
| 59 | }; |
| 60 | |
| 61 | /* Direction settings are only meaningful when GPIOMUX_FUNC_GPIO is selected. |
| 62 | * This element is ignored for all other FUNC selections, as the output- |
| 63 | * enable pin is not under software control in those cases. See the SWI |
| 64 | * for your target for more details. |
| 65 | */ |
| 66 | enum gpiomux_dir { |
| 67 | GPIOMUX_IN = 0, |
| 68 | GPIOMUX_OUT_HIGH, |
| 69 | GPIOMUX_OUT_LOW, |
| 70 | }; |
| 71 | |
| 72 | struct gpiomux_setting { |
| 73 | enum gpiomux_func func; |
| 74 | enum gpiomux_drv drv; |
| 75 | enum gpiomux_pull pull; |
| 76 | enum gpiomux_dir dir; |
| 77 | }; |
Gregory Bean | 1963a2a | 2010-08-28 10:05:44 -0700 | [diff] [blame] | 78 | |
| 79 | /** |
| 80 | * struct msm_gpiomux_config: gpiomux settings for one gpio line. |
| 81 | * |
Bryan Huntsman | 3f2bc4d | 2011-08-16 17:27:22 -0700 | [diff] [blame] | 82 | * A complete gpiomux config is the combination of a drive-strength, |
| 83 | * function, pull, and (sometimes) direction. For functions other than GPIO, |
| 84 | * the input/output setting is hard-wired according to the function. |
Gregory Bean | 1963a2a | 2010-08-28 10:05:44 -0700 | [diff] [blame] | 85 | * |
Bryan Huntsman | 3f2bc4d | 2011-08-16 17:27:22 -0700 | [diff] [blame] | 86 | * @gpio: The index number of the gpio being described. |
| 87 | * @settings: The settings to be installed, specifically: |
| 88 | * GPIOMUX_ACTIVE: The setting to be installed when the |
| 89 | * line is active, or its reference count is > 0. |
| 90 | * GPIOMUX_SUSPENDED: The setting to be installed when |
| 91 | * the line is suspended, or its reference count is 0. |
Gregory Bean | 1963a2a | 2010-08-28 10:05:44 -0700 | [diff] [blame] | 92 | */ |
| 93 | struct msm_gpiomux_config { |
Bryan Huntsman | 3f2bc4d | 2011-08-16 17:27:22 -0700 | [diff] [blame] | 94 | unsigned gpio; |
| 95 | struct gpiomux_setting *settings[GPIOMUX_NSETTINGS]; |
Gregory Bean | 1963a2a | 2010-08-28 10:05:44 -0700 | [diff] [blame] | 96 | }; |
| 97 | |
| 98 | /** |
Bryan Huntsman | 3f2bc4d | 2011-08-16 17:27:22 -0700 | [diff] [blame] | 99 | * struct msm_gpiomux_configs: a collection of gpiomux configs. |
| 100 | * |
| 101 | * It is so common to manage blocks of gpiomux configs that the data structure |
| 102 | * for doing so has been standardized here as a convenience. |
| 103 | * |
| 104 | * @cfg: A pointer to the first config in an array of configs. |
| 105 | * @ncfg: The number of configs in the array. |
Gregory Bean | 1963a2a | 2010-08-28 10:05:44 -0700 | [diff] [blame] | 106 | */ |
Bryan Huntsman | 3f2bc4d | 2011-08-16 17:27:22 -0700 | [diff] [blame] | 107 | struct msm_gpiomux_configs { |
| 108 | struct msm_gpiomux_config *cfg; |
| 109 | size_t ncfg; |
Gregory Bean | 1963a2a | 2010-08-28 10:05:44 -0700 | [diff] [blame] | 110 | }; |
| 111 | |
Gregory Bean | ab78cde | 2010-09-01 16:26:12 -0700 | [diff] [blame] | 112 | #ifdef CONFIG_MSM_GPIOMUX |
| 113 | |
Bryan Huntsman | 3f2bc4d | 2011-08-16 17:27:22 -0700 | [diff] [blame] | 114 | /* Before using gpiomux, initialize the subsystem by telling it how many |
| 115 | * gpios are going to be managed. Calling any other gpiomux functions before |
| 116 | * msm_gpiomux_init is unsupported. |
Gregory Bean | 1963a2a | 2010-08-28 10:05:44 -0700 | [diff] [blame] | 117 | */ |
Bryan Huntsman | 3f2bc4d | 2011-08-16 17:27:22 -0700 | [diff] [blame] | 118 | int msm_gpiomux_init(size_t ngpio); |
| 119 | |
| 120 | /* Install a block of gpiomux configurations in gpiomux. This is functionally |
| 121 | * identical to calling msm_gpiomux_write many times. |
| 122 | */ |
| 123 | void msm_gpiomux_install(struct msm_gpiomux_config *configs, unsigned nconfigs); |
Gregory Bean | 1963a2a | 2010-08-28 10:05:44 -0700 | [diff] [blame] | 124 | |
| 125 | /* Increment a gpio's reference count, possibly activating the line. */ |
| 126 | int __must_check msm_gpiomux_get(unsigned gpio); |
| 127 | |
| 128 | /* Decrement a gpio's reference count, possibly suspending the line. */ |
| 129 | int msm_gpiomux_put(unsigned gpio); |
| 130 | |
Bryan Huntsman | 3f2bc4d | 2011-08-16 17:27:22 -0700 | [diff] [blame] | 131 | /* Install a new setting in a gpio. To erase a slot, use NULL. |
| 132 | * The old setting that was overwritten can be passed back to the caller |
| 133 | * old_setting can be NULL if the caller is not interested in the previous |
| 134 | * setting |
| 135 | * If a previous setting was not available to return (NULL configuration) |
| 136 | * - the function returns 1 |
| 137 | * else function returns 0 |
Gregory Bean | 1963a2a | 2010-08-28 10:05:44 -0700 | [diff] [blame] | 138 | */ |
Bryan Huntsman | 3f2bc4d | 2011-08-16 17:27:22 -0700 | [diff] [blame] | 139 | int msm_gpiomux_write(unsigned gpio, enum msm_gpiomux_setting which, |
| 140 | struct gpiomux_setting *setting, struct gpiomux_setting *old_setting); |
Gregory Bean | 1963a2a | 2010-08-28 10:05:44 -0700 | [diff] [blame] | 141 | |
| 142 | /* Architecture-internal function for use by the framework only. |
| 143 | * This function can assume the following: |
| 144 | * - the gpio value has passed a bounds-check |
| 145 | * - the gpiomux spinlock has been obtained |
| 146 | * |
| 147 | * This function is not for public consumption. External users |
| 148 | * should use msm_gpiomux_write. |
| 149 | */ |
Bryan Huntsman | 3f2bc4d | 2011-08-16 17:27:22 -0700 | [diff] [blame] | 150 | void __msm_gpiomux_write(unsigned gpio, struct gpiomux_setting val); |
Gregory Bean | ab78cde | 2010-09-01 16:26:12 -0700 | [diff] [blame] | 151 | #else |
Bryan Huntsman | 3f2bc4d | 2011-08-16 17:27:22 -0700 | [diff] [blame] | 152 | static inline int msm_gpiomux_init(size_t ngpio) |
| 153 | { |
| 154 | return -ENOSYS; |
| 155 | } |
| 156 | |
| 157 | static inline void |
| 158 | msm_gpiomux_install(struct msm_gpiomux_config *configs, unsigned nconfigs) {} |
| 159 | |
Gregory Bean | ab78cde | 2010-09-01 16:26:12 -0700 | [diff] [blame] | 160 | static inline int __must_check msm_gpiomux_get(unsigned gpio) |
| 161 | { |
| 162 | return -ENOSYS; |
| 163 | } |
Gregory Bean | 1963a2a | 2010-08-28 10:05:44 -0700 | [diff] [blame] | 164 | |
Gregory Bean | ab78cde | 2010-09-01 16:26:12 -0700 | [diff] [blame] | 165 | static inline int msm_gpiomux_put(unsigned gpio) |
| 166 | { |
| 167 | return -ENOSYS; |
| 168 | } |
| 169 | |
| 170 | static inline int msm_gpiomux_write(unsigned gpio, |
Bryan Huntsman | 3f2bc4d | 2011-08-16 17:27:22 -0700 | [diff] [blame] | 171 | enum msm_gpiomux_setting which, struct gpiomux_setting *setting, |
| 172 | struct gpiomux_setting *old_setting) |
Gregory Bean | ab78cde | 2010-09-01 16:26:12 -0700 | [diff] [blame] | 173 | { |
| 174 | return -ENOSYS; |
| 175 | } |
| 176 | #endif |
Gregory Bean | 1963a2a | 2010-08-28 10:05:44 -0700 | [diff] [blame] | 177 | #endif |