Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(259)

Side by Side Diff: drivers/gpio/nm10_gpio.c

Issue 3333016: Add ability to change gpio directions. (Closed) Base URL: http://git.chromium.org/git/kernel.git
Patch Set: Add support to change of GPIO pins' directions to NM10 driver. Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2010, The Chromium OS Authors 2 * Copyright (c) 2010, The Chromium OS Authors
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as 5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation. 6 * published by the Free Software Foundation.
7 * 7 *
8 * This program is distributed in the hope that it will be useful, 8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 struct nm10_gpio { 88 struct nm10_gpio {
89 struct gpio_chip chip; 89 struct gpio_chip chip;
90 u32 io_base; /* base IO space address of the GPIO register file */ 90 u32 io_base; /* base IO space address of the GPIO register file */
91 91
92 /* cached contents of the GPIO bit selections, read during driver 92 /* cached contents of the GPIO bit selections, read during driver
93 * installation */ 93 * installation */
94 u32 cached_select[NM10_GPIO_SECTIONS]; 94 u32 cached_select[NM10_GPIO_SECTIONS];
95 }; 95 };
96 96
97 /** 97 /**
98 * nm10_get_parameters() - get value of a GPIO bit
99 *
100 * Inputs:
101 * @chip: generic gpio chip handle associated with this module
102 * @offset: zero based GPIO bit number (in this controller's scope).
103 *
104 * Outputs:
105 * @psection - pointer to the NM10 section number containing bit offset
106 * @pbit,- pointer to the offset's bit mask within the section
107 * @pgpio - pointer to address of this nm10_gpio instance.
108 *
109 * Returns zero on errors or nonzero on success.
110 */
111 static int nm10_get_parameters(struct gpio_chip *chip, unsigned offset,
112 u8* psection, u32* pbit,
113 struct nm10_gpio **pgpio)
Olof Johansson 2010/09/03 19:35:14 I would prefer having a couple of macros instead o
114 {
115 *pgpio = container_of(chip, struct nm10_gpio, chip);
116
117 *psection = offset / NM10_GPIO_BITS_PER_SECTION;
118 *pbit = BIT(offset % NM10_GPIO_BITS_PER_SECTION);
119
120 if (*psection >= NM10_GPIO_SECTIONS) {
121 printk(KERN_ERR "%s: bad offset %d\n",
122 gpio_driver_name, offset);
123 return 0;
124 }
125
126 if (!(*pbit & (*pgpio)->cached_select[*psection])) {
127 return 0; /* this bit is not used for GPIO */
128 }
129 return ~0;
130 }
131
132 /**
98 * nm10_gpio_get() - get value of a GPIO bit 133 * nm10_gpio_get() - get value of a GPIO bit
99 * @chip: generic gpio chip handle associated with this module 134 * @chip: generic gpio chip handle associated with this module
100 * @offset: zero based GPIO bit number (in this controller's scope). 135 * @offset: zero based GPIO bit number (in this controller's scope).
101 * 136 *
102 * Returns zero in cases when offset exceeds the chip's GPIO capacity, or the 137 * Returns zero in cases when offset exceeds the chip's GPIO capacity, or the
103 * passed in bit not used for GPIO. If the offset is of a valid bit - returns 138 * passed in bit not used for GPIO. If the offset is of a valid bit - returns
104 * a bitmask with the bit value matching the actual bit input state. 139 * a bitmask with the bit value matching the actual bit input state.
105 */ 140 */
106 static int nm10_gpio_get(struct gpio_chip *chip, unsigned offset) 141 static int nm10_gpio_get(struct gpio_chip *chip, unsigned offset)
107 { 142 {
108 u8 section; 143 u8 section;
109 u32 bit; 144 u32 bit;
110 struct nm10_gpio *pgpio = container_of(chip, struct nm10_gpio, chip); 145 struct nm10_gpio *pgpio = container_of(chip, struct nm10_gpio, chip);
111 146
112 » section = offset / NM10_GPIO_BITS_PER_SECTION; 147 » if (!nm10_get_parameters(chip, offset, &section, &bit, &pgpio)) {
113 » bit = BIT(offset % NM10_GPIO_BITS_PER_SECTION);
114
115 » if (section >= NM10_GPIO_SECTIONS) {
116 » » printk(KERN_ERR "%s: bad offset %d\n",
117 » » gpio_driver_name, offset);
118 return 0; 148 return 0;
119 } 149 }
120 150
121 if (!(bit & pgpio->cached_select[section])) {
122 return 0; /* this bit is not used for GPIO */
123 }
124 return inl(pgpio->io_base + 151 return inl(pgpio->io_base +
125 nm10_gpio_sections[section].io_level_offset) & bit; 152 nm10_gpio_sections[section].io_level_offset) & bit;
126 } 153 }
127 154
128 /** 155 /**
129 * nm10_gpio_set() - get value of a GPIO bit 156 * nm10_gpio_set() - set value of a GPIO bit
130 * @chip: generic gpio chip handle associated with this module 157 * @chip: generic gpio chip handle associated with this module
131 * @offset: zero based GPIO bit number (in this controller's scope). 158 * @offset: zero based GPIO bit number (in this controller's scope).
159 * @value: the value to set the output to
132 * 160 *
133 * If the offset is of a valid bit (used for GPIO output) - the bit state is 161 * If the offset is of a valid bit (used for GPIO output) - the bit state is
134 * changed to reflect the value. All other in range offset values are ignored. 162 * changed to reflect the value. All other in range offset values are ignored.
135 */ 163 */
136 static void nm10_gpio_set(struct gpio_chip *chip, unsigned offset, int value) 164 static void nm10_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
137 { 165 {
138 u8 section; 166 u8 section;
139 u32 bit; 167 u32 bit;
140 const struct nm10_gpio_info *pinfo; 168 const struct nm10_gpio_info *pinfo;
141 » struct nm10_gpio *pgpio = container_of(chip, struct nm10_gpio, chip); 169 » struct nm10_gpio *pgpio;
142 u32 gpio_reg_value; 170 u32 gpio_reg_value;
143 171
144 » section = offset / NM10_GPIO_BITS_PER_SECTION; 172 » if (!nm10_get_parameters(chip, offset, &section, &bit, &pgpio)) {
145 » bit = BIT(offset % NM10_GPIO_BITS_PER_SECTION); 173 » » return;
146
147 » if (section >= NM10_GPIO_SECTIONS) {
148 » » printk(KERN_ERR "%s: bad offset %d\n",
149 » » gpio_driver_name, offset);
150 » }
151
152 » if (!(bit & pgpio->cached_select[section])) {
153 » » return;»» /* this bit is not used for GPIO */
154 } 174 }
155 175
156 pinfo = nm10_gpio_sections + section; 176 pinfo = nm10_gpio_sections + section;
157 if (inl(pgpio->io_base + pinfo->io_select_offset) & bit) { 177 if (inl(pgpio->io_base + pinfo->io_select_offset) & bit) {
158 return; /* this is an input bit */ 178 return; /* this is an input bit */
159 } 179 }
160 180
161 gpio_reg_value = inl(pgpio->io_base + pinfo->io_level_offset); 181 gpio_reg_value = inl(pgpio->io_base + pinfo->io_level_offset);
162 182
163 if (value) { 183 if (value) {
164 gpio_reg_value |= bit; 184 gpio_reg_value |= bit;
165 } else { 185 } else {
166 gpio_reg_value &= ~bit; 186 gpio_reg_value &= ~bit;
167 } 187 }
168 outl(gpio_reg_value, pgpio->io_base + pinfo->io_level_offset); 188 outl(gpio_reg_value, pgpio->io_base + pinfo->io_level_offset);
169 } 189 }
170 190
191 /**
192 * nm10_gpio_direction_inp() configure signal "offset" as input, or return error
193 * @chip: generic gpio chip handle associated with this module
194 * @offset: zero based GPIO bit number (in this controller's scope).
195 */
196 static int nm10_gpio_direction_inp(struct gpio_chip *chip,
197 unsigned offset)
198 {
199 u8 section;
200 u32 bit;
201 struct nm10_gpio *pgpio = container_of(chip, struct nm10_gpio, chip);
202 u32 io_select_offset;
203
204 if (!nm10_get_parameters(chip, offset, &section, &bit, &pgpio)) {
205 return -1;
206 }
207
208 io_select_offset = pgpio->io_base +
209 nm10_gpio_sections[section].io_select_offset;
210 outl(inl(io_select_offset) | bit, io_select_offset);
211 return 0;
212 }
213
214 /**
215 * nm10_gpio_direction_out() configure signal "offset" as output,
216 * or return error
217 * @chip: generic gpio chip handle associated with this module
218 * @offset: zero based GPIO bit number (in this controller's scope).
219 * @value: the value to set the output to
220 */
221 static int nm10_gpio_direction_out(struct gpio_chip *chip,
222 unsigned offset, int value)
223 {
224 u8 section;
225 u32 bit;
226 struct nm10_gpio *pgpio = container_of(chip, struct nm10_gpio, chip);
227 u32 io_select_offset;
228
229 if (!nm10_get_parameters(chip, offset, &section, &bit, &pgpio)) {
230 return -1;
231 }
232
233 io_select_offset = pgpio->io_base +
234 nm10_gpio_sections[section].io_select_offset;
235 outl(inl(io_select_offset) & ~bit, io_select_offset);
236 nm10_gpio_set(chip, offset, value);
237 return 0;
238 }
239
171 static int __devinit nm10_gpio_probe(struct pci_dev *pdev, 240 static int __devinit nm10_gpio_probe(struct pci_dev *pdev,
172 const struct pci_device_id *id) 241 const struct pci_device_id *id)
173 { 242 {
174 int retval, ii; 243 int retval, ii;
175 u32 value; 244 u32 value;
176 struct nm10_gpio *pgpio; 245 struct nm10_gpio *pgpio;
177 246
178 retval = pci_enable_device(pdev); 247 retval = pci_enable_device(pdev);
179 printk(KERN_INFO "%s version %s built on %s at %s\n", gpio_driver_name, 248 printk(KERN_INFO "%s version %s built on %s at %s\n", gpio_driver_name,
180 gpio_driver_version, __DATE__, __TIME__); 249 gpio_driver_version, __DATE__, __TIME__);
(...skipping 25 matching lines...) Expand all
206 goto err3; 275 goto err3;
207 } 276 }
208 277
209 /* used to access GPIO bits on this chip */ 278 /* used to access GPIO bits on this chip */
210 pgpio->io_base = value; 279 pgpio->io_base = value;
211 280
212 pgpio->chip.base = -1; 281 pgpio->chip.base = -1;
213 pgpio->chip.label = dev_name(&pdev->dev); 282 pgpio->chip.label = dev_name(&pdev->dev);
214 pgpio->chip.get = nm10_gpio_get; 283 pgpio->chip.get = nm10_gpio_get;
215 pgpio->chip.set = nm10_gpio_set; 284 pgpio->chip.set = nm10_gpio_set;
285 pgpio->chip.direction_input = nm10_gpio_direction_inp;
286 pgpio->chip.direction_output = nm10_gpio_direction_out;
216 pgpio->chip.ngpio = NM10_MAX_GPIO_BITS; 287 pgpio->chip.ngpio = NM10_MAX_GPIO_BITS;
217 pgpio->chip.can_sleep = 0; 288 pgpio->chip.can_sleep = 0;
218 pci_set_drvdata(pdev, pgpio); 289 pci_set_drvdata(pdev, pgpio);
219 290
220 /* store GPIO configuration locally */ 291 /* store GPIO configuration locally */
221 for (ii = 0; ii < ARRAY_SIZE(pgpio->cached_select); ii++) { 292 for (ii = 0; ii < ARRAY_SIZE(pgpio->cached_select); ii++) {
222 pgpio->cached_select[ii] = inl(pgpio->io_base + 293 pgpio->cached_select[ii] = inl(pgpio->io_base +
223 nm10_gpio_sections[ii]. 294 nm10_gpio_sections[ii].
224 use_select_offset); 295 use_select_offset);
225 } 296 }
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 { 361 {
291 pci_unregister_driver(&nm10_gpio_pci_driver); 362 pci_unregister_driver(&nm10_gpio_pci_driver);
292 } 363 }
293 364
294 module_init(nm10_gpio_init); 365 module_init(nm10_gpio_init);
295 module_exit(nm10_gpio_exit); 366 module_exit(nm10_gpio_exit);
296 367
297 MODULE_LICENSE("GPL"); 368 MODULE_LICENSE("GPL");
298 MODULE_AUTHOR("The Chromium OS Authors"); 369 MODULE_AUTHOR("The Chromium OS Authors");
299 MODULE_DESCRIPTION("NM10 GPIO driver"); 370 MODULE_DESCRIPTION("NM10 GPIO driver");
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698