Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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, §ion, &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, §ion, &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, §ion, &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, §ion, &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 Loading... | |
| 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 Loading... | |
| 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"); |
| OLD | NEW |