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/am335x/am335x_scm_padconf.h> 56 #include <arm/ti/ti_cpuid.h> 57 #include "ti_pinmux.h" 58 59 struct pincfg { 60 uint32_t reg; 61 uint32_t conf; 62 }; 63 64 static struct resource_spec ti_pinmux_res_spec[] = { 65 { SYS_RES_MEMORY, 0, RF_ACTIVE }, /* Control memory window */ 66 { -1, 0 } 67 }; 68 69 static struct ti_pinmux_softc *ti_pinmux_sc; 70 71 #define ti_pinmux_read_2(sc, reg) \ 72 bus_space_read_2((sc)->sc_bst, (sc)->sc_bsh, (reg)) 73 #define ti_pinmux_write_2(sc, reg, val) \ 74 bus_space_write_2((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) 75 #define ti_pinmux_read_4(sc, reg) \ 76 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) 77 #define ti_pinmux_write_4(sc, reg, val) \ 78 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) 79 80 /** 81 * ti_padconf_devmap - Array of pins, should be defined one per SoC 82 * 83 * This array is typically defined in one of the targeted *_scm_pinumx.c 84 * files and is specific to the given SoC platform. Each entry in the array 85 * corresponds to an individual pin. 86 */ 87 static const struct ti_pinmux_device *ti_pinmux_dev; 88 89 /** 90 * ti_pinmux_padconf_from_name - searches the list of pads and returns entry 91 * with matching ball name. 92 * @ballname: the name of the ball 93 * 94 * RETURNS: 95 * A pointer to the matching padconf or NULL if the ball wasn't found. 96 */ 97 static const struct ti_pinmux_padconf* 98 ti_pinmux_padconf_from_name(const char *ballname) 99 { 100 const struct ti_pinmux_padconf *padconf; 101 102 padconf = ti_pinmux_dev->padconf; 103 while (padconf->ballname != NULL) { 104 if (strcmp(ballname, padconf->ballname) == 0) 105 return(padconf); 106 padconf++; 107 } 108 109 return (NULL); 110 } 111 112 /** 113 * ti_pinmux_padconf_set_internal - sets the muxmode and state for a pad/pin 114 * @padconf: pointer to the pad structure 115 * @muxmode: the name of the mode to use for the pin, i.e. "uart1_rx" 116 * @state: the state to put the pad/pin in, i.e. PADCONF_PIN_??? 117 * 118 * 119 * LOCKING: 120 * Internally locks it's own context. 121 * 122 * RETURNS: 123 * 0 on success. 124 * EINVAL if pin requested is outside valid range or already in use. 125 */ 126 static int 127 ti_pinmux_padconf_set_internal(struct ti_pinmux_softc *sc, 128 const struct ti_pinmux_padconf *padconf, 129 const char *muxmode, unsigned int state) 130 { 131 unsigned int mode; 132 uint16_t reg_val; 133 134 /* populate the new value for the PADCONF register */ 135 reg_val = (uint16_t)(state & ti_pinmux_dev->padconf_sate_mask); 136 137 /* find the new mode requested */ 138 for (mode = 0; mode < 8; mode++) { 139 if ((padconf->muxmodes[mode] != NULL) && 140 (strcmp(padconf->muxmodes[mode], muxmode) == 0)) { 141 break; 142 } 143 } 144 145 /* couldn't find the mux mode */ 146 if (mode >= 8) { 147 printf("Invalid mode \"%s\"\n", muxmode); 148 return (EINVAL); 149 } 150 151 /* set the mux mode */ 152 reg_val |= (uint16_t)(mode & ti_pinmux_dev->padconf_muxmode_mask); 153 154 if (bootverbose) 155 device_printf(sc->sc_dev, "setting internal %x for %s\n", 156 reg_val, muxmode); 157 /* write the register value (16-bit writes) */ 158 ti_pinmux_write_2(sc, padconf->reg_off, reg_val); 159 160 return (0); 161 } 162 163 /** 164 * ti_pinmux_padconf_set - sets the muxmode and state for a pad/pin 165 * @padname: the name of the pad, i.e. "c12" 166 * @muxmode: the name of the mode to use for the pin, i.e. "uart1_rx" 167 * @state: the state to put the pad/pin in, i.e. PADCONF_PIN_??? 168 * 169 * 170 * LOCKING: 171 * Internally locks it's own context. 172 * 173 * RETURNS: 174 * 0 on success. 175 * EINVAL if pin requested is outside valid range or already in use. 176 */ 177 int 178 ti_pinmux_padconf_set(const char *padname, const char *muxmode, unsigned int state) 179 { 180 const struct ti_pinmux_padconf *padconf; 181 182 if (!ti_pinmux_sc) 183 return (ENXIO); 184 185 /* find the pin in the devmap */ 186 padconf = ti_pinmux_padconf_from_name(padname); 187 if (padconf == NULL) 188 return (EINVAL); 189 190 return (ti_pinmux_padconf_set_internal(ti_pinmux_sc, padconf, muxmode, state)); 191 } 192 193 /** 194 * ti_pinmux_padconf_get - gets the muxmode and state for a pad/pin 195 * @padname: the name of the pad, i.e. "c12" 196 * @muxmode: upon return will contain the name of the muxmode of the pin 197 * @state: upon return will contain the state of the pad/pin 198 * 199 * 200 * LOCKING: 201 * Internally locks it's own context. 202 * 203 * RETURNS: 204 * 0 on success. 205 * EINVAL if pin requested is outside valid range or already in use. 206 */ 207 int 208 ti_pinmux_padconf_get(const char *padname, const char **muxmode, 209 unsigned int *state) 210 { 211 const struct ti_pinmux_padconf *padconf; 212 uint16_t reg_val; 213 214 if (!ti_pinmux_sc) 215 return (ENXIO); 216 217 /* find the pin in the devmap */ 218 padconf = ti_pinmux_padconf_from_name(padname); 219 if (padconf == NULL) 220 return (EINVAL); 221 222 /* read the register value (16-bit reads) */ 223 reg_val = ti_pinmux_read_2(ti_pinmux_sc, padconf->reg_off); 224 225 /* save the state */ 226 if (state) 227 *state = (reg_val & ti_pinmux_dev->padconf_sate_mask); 228 229 /* save the mode */ 230 if (muxmode) 231 *muxmode = padconf->muxmodes[(reg_val & ti_pinmux_dev->padconf_muxmode_mask)]; 232 233 return (0); 234 } 235 236 /** 237 * ti_pinmux_padconf_set_gpiomode - converts a pad to GPIO mode. 238 * @gpio: the GPIO pin number (0-195) 239 * @state: the state to put the pad/pin in, i.e. PADCONF_PIN_??? 240 * 241 * 242 * 243 * LOCKING: 244 * Internally locks it's own context. 245 * 246 * RETURNS: 247 * 0 on success. 248 * EINVAL if pin requested is outside valid range or already in use. 249 */ 250 int 251 ti_pinmux_padconf_set_gpiomode(uint32_t gpio, unsigned int state) 252 { 253 const struct ti_pinmux_padconf *padconf; 254 uint16_t reg_val; 255 256 if (!ti_pinmux_sc) 257 return (ENXIO); 258 259 /* find the gpio pin in the padconf array */ 260 padconf = ti_pinmux_dev->padconf; 261 while (padconf->ballname != NULL) { 262 if (padconf->gpio_pin == gpio) 263 break; 264 padconf++; 265 } 266 if (padconf->ballname == NULL) 267 return (EINVAL); 268 269 /* populate the new value for the PADCONF register */ 270 reg_val = (uint16_t)(state & ti_pinmux_dev->padconf_sate_mask); 271 272 /* set the mux mode */ 273 reg_val |= (uint16_t)(padconf->gpio_mode & ti_pinmux_dev->padconf_muxmode_mask); 274 275 /* write the register value (16-bit writes) */ 276 ti_pinmux_write_2(ti_pinmux_sc, padconf->reg_off, reg_val); 277 278 return (0); 279 } 280 281 /** 282 * ti_pinmux_padconf_get_gpiomode - gets the current GPIO mode of the pin 283 * @gpio: the GPIO pin number (0-195) 284 * @state: upon return will contain the state 285 * 286 * 287 * 288 * LOCKING: 289 * Internally locks it's own context. 290 * 291 * RETURNS: 292 * 0 on success. 293 * EINVAL if pin requested is outside valid range or not configured as GPIO. 294 */ 295 int 296 ti_pinmux_padconf_get_gpiomode(uint32_t gpio, unsigned int *state) 297 { 298 const struct ti_pinmux_padconf *padconf; 299 uint16_t reg_val; 300 301 if (!ti_pinmux_sc) 302 return (ENXIO); 303 304 /* find the gpio pin in the padconf array */ 305 padconf = ti_pinmux_dev->padconf; 306 while (padconf->ballname != NULL) { 307 if (padconf->gpio_pin == gpio) 308 break; 309 padconf++; 310 } 311 if (padconf->ballname == NULL) 312 return (EINVAL); 313 314 /* read the current register settings */ 315 reg_val = ti_pinmux_read_2(ti_pinmux_sc, padconf->reg_off); 316 317 /* check to make sure the pins is configured as GPIO in the first state */ 318 if ((reg_val & ti_pinmux_dev->padconf_muxmode_mask) != padconf->gpio_mode) 319 return (EINVAL); 320 321 /* read and store the reset of the state, i.e. pull-up, pull-down, etc */ 322 if (state) 323 *state = (reg_val & ti_pinmux_dev->padconf_sate_mask); 324 325 return (0); 326 } 327 328 static int 329 ti_pinmux_configure_pins(device_t dev, phandle_t cfgxref) 330 { 331 struct pincfg *cfgtuples, *cfg; 332 phandle_t cfgnode; 333 int i, ntuples; 334 static struct ti_pinmux_softc *sc; 335 336 sc = device_get_softc(dev); 337 cfgnode = OF_node_from_xref(cfgxref); 338 ntuples = OF_getencprop_alloc_multi(cfgnode, "pinctrl-single,pins", 339 sizeof(*cfgtuples), (void **)&cfgtuples); 340 341 if (ntuples < 0) 342 return (ENOENT); 343 344 if (ntuples == 0) 345 return (0); /* Empty property is not an error. */ 346 347 for (i = 0, cfg = cfgtuples; i < ntuples; i++, cfg++) { 348 if (bootverbose) { 349 char name[32]; 350 OF_getprop(cfgnode, "name", &name, sizeof(name)); 351 printf("%16s: muxreg 0x%04x muxval 0x%02x\n", 352 name, cfg->reg, cfg->conf); 353 } 354 355 /* write the register value (16-bit writes) */ 356 ti_pinmux_write_2(sc, cfg->reg, cfg->conf); 357 } 358 359 OF_prop_free(cfgtuples); 360 361 return (0); 362 } 363 364 /* 365 * Device part of OMAP SCM driver 366 */ 367 368 static int 369 ti_pinmux_probe(device_t dev) 370 { 371 if (!ofw_bus_status_okay(dev)) 372 return (ENXIO); 373 374 if (!ofw_bus_is_compatible(dev, "pinctrl-single")) 375 return (ENXIO); 376 377 if (ti_pinmux_sc) { 378 printf("%s: multiple pinctrl modules in device tree data, ignoring\n", 379 __func__); 380 return (EEXIST); 381 } 382 switch (ti_chip()) { 383 #ifdef SOC_TI_AM335X 384 case CHIP_AM335X: 385 ti_pinmux_dev = &ti_am335x_pinmux_dev; 386 break; 387 #endif 388 default: 389 printf("Unknown CPU in pinmux\n"); 390 return (ENXIO); 391 } 392 393 device_set_desc(dev, "TI Pinmux Module"); 394 return (BUS_PROBE_DEFAULT); 395 } 396 397 /** 398 * ti_pinmux_attach - attaches the pinmux to the simplebus 399 * @dev: new device 400 * 401 * RETURNS 402 * Zero on success or ENXIO if an error occuried. 403 */ 404 static int 405 ti_pinmux_attach(device_t dev) 406 { 407 struct ti_pinmux_softc *sc = device_get_softc(dev); 408 409 #if 0 410 if (ti_pinmux_sc) 411 return (ENXIO); 412 #endif 413 414 sc->sc_dev = dev; 415 416 if (bus_alloc_resources(dev, ti_pinmux_res_spec, sc->sc_res)) { 417 device_printf(dev, "could not allocate resources\n"); 418 return (ENXIO); 419 } 420 421 sc->sc_bst = rman_get_bustag(sc->sc_res[0]); 422 sc->sc_bsh = rman_get_bushandle(sc->sc_res[0]); 423 424 if (ti_pinmux_sc == NULL) 425 ti_pinmux_sc = sc; 426 427 fdt_pinctrl_register(dev, "pinctrl-single,pins"); 428 fdt_pinctrl_configure_tree(dev); 429 430 return (0); 431 } 432 433 static device_method_t ti_pinmux_methods[] = { 434 DEVMETHOD(device_probe, ti_pinmux_probe), 435 DEVMETHOD(device_attach, ti_pinmux_attach), 436 437 /* fdt_pinctrl interface */ 438 DEVMETHOD(fdt_pinctrl_configure, ti_pinmux_configure_pins), 439 { 0, 0 } 440 }; 441 442 static driver_t ti_pinmux_driver = { 443 "ti_pinmux", 444 ti_pinmux_methods, 445 sizeof(struct ti_pinmux_softc), 446 }; 447 448 DRIVER_MODULE(ti_pinmux, simplebus, ti_pinmux_driver, 0, 0); 449 MODULE_VERSION(ti_pinmux, 1); 450 MODULE_DEPEND(ti_pinmux, ti_scm, 1, 1, 1); 451