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