1 /* 2 * Copyright (c) 2010 3 * Ben Gray <ben.r.gray@gmail.com>. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Ben Gray. 17 * 4. The name of the company nor the name of the author may be used to 18 * endorse or promote products derived from this software without specific 19 * prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY BEN GRAY ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL BEN GRAY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 30 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /** 34 * Exposes pinmux module to pinctrl-compatible interface 35 */ 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/kernel.h> 40 #include <sys/module.h> 41 #include <sys/bus.h> 42 #include <sys/resource.h> 43 #include <sys/rman.h> 44 #include <sys/lock.h> 45 #include <sys/mutex.h> 46 47 #include <machine/bus.h> 48 #include <machine/resource.h> 49 50 #include <dev/ofw/openfirm.h> 51 #include <dev/ofw/ofw_bus.h> 52 #include <dev/ofw/ofw_bus_subr.h> 53 #include <dev/fdt/fdt_pinctrl.h> 54 55 #include <arm/ti/omap4/omap4_scm_padconf.h> 56 #include <arm/ti/am335x/am335x_scm_padconf.h> 57 #include <arm/ti/ti_cpuid.h> 58 #include "ti_pinmux.h" 59 60 struct pincfg { 61 uint32_t reg; 62 uint32_t conf; 63 }; 64 65 static struct resource_spec ti_pinmux_res_spec[] = { 66 { SYS_RES_MEMORY, 0, RF_ACTIVE }, /* Control memory window */ 67 { -1, 0 } 68 }; 69 70 static struct ti_pinmux_softc *ti_pinmux_sc; 71 72 #define ti_pinmux_read_2(sc, reg) \ 73 bus_space_read_2((sc)->sc_bst, (sc)->sc_bsh, (reg)) 74 #define ti_pinmux_write_2(sc, reg, val) \ 75 bus_space_write_2((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) 76 #define ti_pinmux_read_4(sc, reg) \ 77 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) 78 #define ti_pinmux_write_4(sc, reg, val) \ 79 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) 80 81 /** 82 * ti_padconf_devmap - Array of pins, should be defined one per SoC 83 * 84 * This array is typically defined in one of the targeted *_scm_pinumx.c 85 * files and is specific to the given SoC platform. Each entry in the array 86 * corresponds to an individual pin. 87 */ 88 static const struct ti_pinmux_device *ti_pinmux_dev; 89 90 /** 91 * ti_pinmux_padconf_from_name - searches the list of pads and returns entry 92 * with matching ball name. 93 * @ballname: the name of the ball 94 * 95 * RETURNS: 96 * A pointer to the matching padconf or NULL if the ball wasn't found. 97 */ 98 static const struct ti_pinmux_padconf* 99 ti_pinmux_padconf_from_name(const char *ballname) 100 { 101 const struct ti_pinmux_padconf *padconf; 102 103 padconf = ti_pinmux_dev->padconf; 104 while (padconf->ballname != NULL) { 105 if (strcmp(ballname, padconf->ballname) == 0) 106 return(padconf); 107 padconf++; 108 } 109 110 return (NULL); 111 } 112 113 /** 114 * ti_pinmux_padconf_set_internal - sets the muxmode and state for a pad/pin 115 * @padconf: pointer to the pad structure 116 * @muxmode: the name of the mode to use for the pin, i.e. "uart1_rx" 117 * @state: the state to put the pad/pin in, i.e. PADCONF_PIN_??? 118 * 119 * 120 * LOCKING: 121 * Internally locks it's own context. 122 * 123 * RETURNS: 124 * 0 on success. 125 * EINVAL if pin requested is outside valid range or already in use. 126 */ 127 static int 128 ti_pinmux_padconf_set_internal(struct ti_pinmux_softc *sc, 129 const struct ti_pinmux_padconf *padconf, 130 const char *muxmode, unsigned int state) 131 { 132 unsigned int mode; 133 uint16_t reg_val; 134 135 /* populate the new value for the PADCONF register */ 136 reg_val = (uint16_t)(state & ti_pinmux_dev->padconf_sate_mask); 137 138 /* find the new mode requested */ 139 for (mode = 0; mode < 8; mode++) { 140 if ((padconf->muxmodes[mode] != NULL) && 141 (strcmp(padconf->muxmodes[mode], muxmode) == 0)) { 142 break; 143 } 144 } 145 146 /* couldn't find the mux mode */ 147 if (mode >= 8) { 148 printf("Invalid mode \"%s\"\n", muxmode); 149 return (EINVAL); 150 } 151 152 /* set the mux mode */ 153 reg_val |= (uint16_t)(mode & ti_pinmux_dev->padconf_muxmode_mask); 154 155 if (bootverbose) 156 device_printf(sc->sc_dev, "setting internal %x for %s\n", 157 reg_val, muxmode); 158 /* write the register value (16-bit writes) */ 159 ti_pinmux_write_2(sc, padconf->reg_off, reg_val); 160 161 return (0); 162 } 163 164 /** 165 * ti_pinmux_padconf_set - sets the muxmode and state for a pad/pin 166 * @padname: the name of the pad, i.e. "c12" 167 * @muxmode: the name of the mode to use for the pin, i.e. "uart1_rx" 168 * @state: the state to put the pad/pin in, i.e. PADCONF_PIN_??? 169 * 170 * 171 * LOCKING: 172 * Internally locks it's own context. 173 * 174 * RETURNS: 175 * 0 on success. 176 * EINVAL if pin requested is outside valid range or already in use. 177 */ 178 int 179 ti_pinmux_padconf_set(const char *padname, const char *muxmode, unsigned int state) 180 { 181 const struct ti_pinmux_padconf *padconf; 182 183 if (!ti_pinmux_sc) 184 return (ENXIO); 185 186 /* find the pin in the devmap */ 187 padconf = ti_pinmux_padconf_from_name(padname); 188 if (padconf == NULL) 189 return (EINVAL); 190 191 return (ti_pinmux_padconf_set_internal(ti_pinmux_sc, padconf, muxmode, state)); 192 } 193 194 /** 195 * ti_pinmux_padconf_get - gets the muxmode and state for a pad/pin 196 * @padname: the name of the pad, i.e. "c12" 197 * @muxmode: upon return will contain the name of the muxmode of the pin 198 * @state: upon return will contain the state of the pad/pin 199 * 200 * 201 * LOCKING: 202 * Internally locks it's own context. 203 * 204 * RETURNS: 205 * 0 on success. 206 * EINVAL if pin requested is outside valid range or already in use. 207 */ 208 int 209 ti_pinmux_padconf_get(const char *padname, const char **muxmode, 210 unsigned int *state) 211 { 212 const struct ti_pinmux_padconf *padconf; 213 uint16_t reg_val; 214 215 if (!ti_pinmux_sc) 216 return (ENXIO); 217 218 /* find the pin in the devmap */ 219 padconf = ti_pinmux_padconf_from_name(padname); 220 if (padconf == NULL) 221 return (EINVAL); 222 223 /* read the register value (16-bit reads) */ 224 reg_val = ti_pinmux_read_2(ti_pinmux_sc, padconf->reg_off); 225 226 /* save the state */ 227 if (state) 228 *state = (reg_val & ti_pinmux_dev->padconf_sate_mask); 229 230 /* save the mode */ 231 if (muxmode) 232 *muxmode = padconf->muxmodes[(reg_val & ti_pinmux_dev->padconf_muxmode_mask)]; 233 234 return (0); 235 } 236 237 /** 238 * ti_pinmux_padconf_set_gpiomode - converts a pad to GPIO mode. 239 * @gpio: the GPIO pin number (0-195) 240 * @state: the state to put the pad/pin in, i.e. PADCONF_PIN_??? 241 * 242 * 243 * 244 * LOCKING: 245 * Internally locks it's own context. 246 * 247 * RETURNS: 248 * 0 on success. 249 * EINVAL if pin requested is outside valid range or already in use. 250 */ 251 int 252 ti_pinmux_padconf_set_gpiomode(uint32_t gpio, unsigned int state) 253 { 254 const struct ti_pinmux_padconf *padconf; 255 uint16_t reg_val; 256 257 if (!ti_pinmux_sc) 258 return (ENXIO); 259 260 /* find the gpio pin in the padconf array */ 261 padconf = ti_pinmux_dev->padconf; 262 while (padconf->ballname != NULL) { 263 if (padconf->gpio_pin == gpio) 264 break; 265 padconf++; 266 } 267 if (padconf->ballname == NULL) 268 return (EINVAL); 269 270 /* populate the new value for the PADCONF register */ 271 reg_val = (uint16_t)(state & ti_pinmux_dev->padconf_sate_mask); 272 273 /* set the mux mode */ 274 reg_val |= (uint16_t)(padconf->gpio_mode & ti_pinmux_dev->padconf_muxmode_mask); 275 276 /* write the register value (16-bit writes) */ 277 ti_pinmux_write_2(ti_pinmux_sc, padconf->reg_off, reg_val); 278 279 return (0); 280 } 281 282 /** 283 * ti_pinmux_padconf_get_gpiomode - gets the current GPIO mode of the pin 284 * @gpio: the GPIO pin number (0-195) 285 * @state: upon return will contain the state 286 * 287 * 288 * 289 * LOCKING: 290 * Internally locks it's own context. 291 * 292 * RETURNS: 293 * 0 on success. 294 * EINVAL if pin requested is outside valid range or not configured as GPIO. 295 */ 296 int 297 ti_pinmux_padconf_get_gpiomode(uint32_t gpio, unsigned int *state) 298 { 299 const struct ti_pinmux_padconf *padconf; 300 uint16_t reg_val; 301 302 if (!ti_pinmux_sc) 303 return (ENXIO); 304 305 /* find the gpio pin in the padconf array */ 306 padconf = ti_pinmux_dev->padconf; 307 while (padconf->ballname != NULL) { 308 if (padconf->gpio_pin == gpio) 309 break; 310 padconf++; 311 } 312 if (padconf->ballname == NULL) 313 return (EINVAL); 314 315 /* read the current register settings */ 316 reg_val = ti_pinmux_read_2(ti_pinmux_sc, padconf->reg_off); 317 318 /* check to make sure the pins is configured as GPIO in the first state */ 319 if ((reg_val & ti_pinmux_dev->padconf_muxmode_mask) != padconf->gpio_mode) 320 return (EINVAL); 321 322 /* read and store the reset of the state, i.e. pull-up, pull-down, etc */ 323 if (state) 324 *state = (reg_val & ti_pinmux_dev->padconf_sate_mask); 325 326 return (0); 327 } 328 329 static int 330 ti_pinmux_configure_pins(device_t dev, phandle_t cfgxref) 331 { 332 struct pincfg *cfgtuples, *cfg; 333 phandle_t cfgnode; 334 int i, ntuples; 335 static struct ti_pinmux_softc *sc; 336 337 sc = device_get_softc(dev); 338 cfgnode = OF_node_from_xref(cfgxref); 339 ntuples = OF_getencprop_alloc_multi(cfgnode, "pinctrl-single,pins", 340 sizeof(*cfgtuples), (void **)&cfgtuples); 341 342 if (ntuples < 0) 343 return (ENOENT); 344 345 if (ntuples == 0) 346 return (0); /* Empty property is not an error. */ 347 348 for (i = 0, cfg = cfgtuples; i < ntuples; i++, cfg++) { 349 if (bootverbose) { 350 char name[32]; 351 OF_getprop(cfgnode, "name", &name, sizeof(name)); 352 printf("%16s: muxreg 0x%04x muxval 0x%02x\n", 353 name, cfg->reg, cfg->conf); 354 } 355 356 /* write the register value (16-bit writes) */ 357 ti_pinmux_write_2(sc, cfg->reg, cfg->conf); 358 } 359 360 OF_prop_free(cfgtuples); 361 362 return (0); 363 } 364 365 /* 366 * Device part of OMAP SCM driver 367 */ 368 369 static int 370 ti_pinmux_probe(device_t dev) 371 { 372 if (!ofw_bus_status_okay(dev)) 373 return (ENXIO); 374 375 if (!ofw_bus_is_compatible(dev, "pinctrl-single")) 376 return (ENXIO); 377 378 if (ti_pinmux_sc) { 379 printf("%s: multiple pinctrl modules in device tree data, ignoring\n", 380 __func__); 381 return (EEXIST); 382 } 383 switch (ti_chip()) { 384 #ifdef SOC_OMAP4 385 case CHIP_OMAP_4: 386 ti_pinmux_dev = &omap4_pinmux_dev; 387 break; 388 #endif 389 #ifdef SOC_TI_AM335X 390 case CHIP_AM335X: 391 ti_pinmux_dev = &ti_am335x_pinmux_dev; 392 break; 393 #endif 394 default: 395 printf("Unknown CPU in pinmux\n"); 396 return (ENXIO); 397 } 398 399 device_set_desc(dev, "TI Pinmux Module"); 400 return (BUS_PROBE_DEFAULT); 401 } 402 403 /** 404 * ti_pinmux_attach - attaches the pinmux to the simplebus 405 * @dev: new device 406 * 407 * RETURNS 408 * Zero on success or ENXIO if an error occuried. 409 */ 410 static int 411 ti_pinmux_attach(device_t dev) 412 { 413 struct ti_pinmux_softc *sc = device_get_softc(dev); 414 415 #if 0 416 if (ti_pinmux_sc) 417 return (ENXIO); 418 #endif 419 420 sc->sc_dev = dev; 421 422 if (bus_alloc_resources(dev, ti_pinmux_res_spec, sc->sc_res)) { 423 device_printf(dev, "could not allocate resources\n"); 424 return (ENXIO); 425 } 426 427 sc->sc_bst = rman_get_bustag(sc->sc_res[0]); 428 sc->sc_bsh = rman_get_bushandle(sc->sc_res[0]); 429 430 if (ti_pinmux_sc == NULL) 431 ti_pinmux_sc = sc; 432 433 fdt_pinctrl_register(dev, "pinctrl-single,pins"); 434 fdt_pinctrl_configure_tree(dev); 435 436 return (0); 437 } 438 439 static device_method_t ti_pinmux_methods[] = { 440 DEVMETHOD(device_probe, ti_pinmux_probe), 441 DEVMETHOD(device_attach, ti_pinmux_attach), 442 443 /* fdt_pinctrl interface */ 444 DEVMETHOD(fdt_pinctrl_configure, ti_pinmux_configure_pins), 445 { 0, 0 } 446 }; 447 448 static driver_t ti_pinmux_driver = { 449 "ti_pinmux", 450 ti_pinmux_methods, 451 sizeof(struct ti_pinmux_softc), 452 }; 453 454 DRIVER_MODULE(ti_pinmux, simplebus, ti_pinmux_driver, 0, 0); 455 MODULE_VERSION(ti_pinmux, 1); 456 MODULE_DEPEND(ti_pinmux, ti_scm, 1, 1, 1); 457