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*
ti_pinmux_padconf_from_name(const char * ballname)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
ti_pinmux_padconf_set_internal(struct ti_pinmux_softc * sc,const struct ti_pinmux_padconf * padconf,const char * muxmode,unsigned int state)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
ti_pinmux_padconf_set(const char * padname,const char * muxmode,unsigned int state)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
ti_pinmux_padconf_get(const char * padname,const char ** muxmode,unsigned int * state)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
ti_pinmux_padconf_set_gpiomode(uint32_t gpio,unsigned int state)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
ti_pinmux_padconf_get_gpiomode(uint32_t gpio,unsigned int * state)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
ti_pinmux_configure_pins(device_t dev,phandle_t cfgxref)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
ti_pinmux_probe(device_t dev)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
ti_pinmux_attach(device_t dev)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