Linus Walleij wrote at Monday, May 02, 2011 1:16 PM: > From: Linus Walleij <linus.walleij@xxxxxxxxxx> > > This creates a subsystem for handling of pinmux devices. These are > devices that enable and disable groups of pins on primarily PGA and > BGA type of chip packages and common in embedded systems. I would avoid any references to particular package types; I've seen pinmuxing applied to PLCC and DIP/DIL too, and in general, it's possible irrespective of package type. > This is being done to depopulate the arch/arm/* directory of such > custom drivers and try to abstract the infrastructure they all > need. See the Documentation/pinmux.txt file that is part of this > patch for more details. > diff --git a/Documentation/pinmux.txt b/Documentation/pinmux.txt >... > +The mux settings are: > + > +- Oriented around enumerated physical pins or pads denoted by unsigned > + integers in the range 0..MAX_INT. Every pin on your system (or atleast > + every pin that can be muxed) should have a unique number. The numberspace Does this imply a model where each pin's "special function" can be controlled independently? I think reading through the document that isn't the case, but I just wanted to be sure. In particular, NVIDIA Tegra has a setup where: * Pinmux configuration for "special functions" is at a "pad-group" level, where there may be 1..N pins in a pad-group, and there is a single register field that defines the current special function routed to/from all pins in that pad-group at once. * Each pad group can be assigned 1 of N special functions (none might be an option in some/all cases too) * Some special functions may be assignable to multiple pad groups, although obviously only 1 pad group per function at a time. * GPIO selection is at per-pin granularity; individual pins may be used as a GPIO irrespective of what SFR is selected for the pad group containing the pin. * There are also other configurations associated with pinmuxing, such as drive strength, pull up/down enables, etc. Also, some of our drivers use "dynamic pinmuxing". For example, our downstream I2C driver exposes N I2C busses and reprograms the pinmux at runtime to attach the actual I2C controller to different sets of pins, essentially multi-plexing the control across N physical busses. > diff --git a/include/linux/pinmux.h b/include/linux/pinmux.h > new file mode 100644 > index 0000000..9bdcc33 > --- /dev/null > +++ b/include/linux/pinmux.h > +/** > + * struct pinmux_map - boards/machines shall provide this map for devices > + * @node: list node - only for internal use Node isn't in the structure. > + * @function: a functional name for this mapping so it can be passed down > + * to the driver to invoke that function and be referenced by this ID > + * in e.g. pinmux_get() > + * @dev: the device using this specific mapping, may be NULL if you provide > + * .dev_name instead (this is more common) > + * @dev_name: the name of the device using this specific mapping, the name > + * must be the same that will return your struct device* > + */ > +struct pinmux_map { > + const char *function; > + struct device *dev; > + const char *dev_name; > +}; > +/* > + * The pin number is a global pin number space, nominally the arch shall define > + * the number of pins in *total* across all chips in the arch/system. > + * > + * Example: if your arch has two chips with 64 pins each, you have > + * 8*3 = 24 MACH_NR_PINS. 2*64 = 128 MACH_NR_PINS ? > +struct pinmux_dev; > + > +/** > + * struct pinmux_ops - pinmux operations, to be implemented by drivers > + * @request: called by the core to see if a certain pin can be muxed in > + * and made available in a certain mux setting The driver is allowed > + * to answer "no" by returning a negative error code > + * @list_functions: list the number of selectable named functions available > + * in this pinmux driver, the core will begin on 0 and call this > + * repeatedly as long as it returns >= 0 to enumerate mux settings > + * @get_function_name: return the function name of the muxing selector, > + * called by the core to figure out which mux setting it shall map a > + * certain device to > + * @get_function_pins: return an array of pins corresponding to a certain > + * function selector in @pins, and the size of the array in @num_pins > + * @enable: enable a certain muxing enumerator. The driver does not need to > + * figure out whether enabling this function conflicts some other use > + * of the pins, such collisions are handled by the pinmux subsystem > + * @disable: disable a certain muxing enumerator > + * @gpio_request_enable: requests and enables GPIO on a certain pin. > + * Implement this only if you can mux every pin individually as GPIO. If > + * your gpio assignments are grouped, so you cannot control the GPIO > + * muxing of every indvidual pin. > + * @dbg_show: optional debugfs display hook that will provide per-device > + * info for a certain pin in debugfs > + */ > +struct pinmux_ops { > + int (*request) (struct pinmux_dev *pmxdev, unsigned offset); s/offset/pin/? I assume that's what it means. Same for gpio_request_enable below too. > + int (*free) (struct pinmux_dev *pmxdev, unsigned offset); > + int (*list_functions) (struct pinmux_dev *pmxdev, unsigned selector); > + const char *(*get_function_name) (struct pinmux_dev *pmxdev, > + unsigned selector); > + int (*get_function_pins) (struct pinmux_dev *pmxdev, unsigned selector, > + unsigned ** const pins, unsigned * const num_pins); > + int (*enable) (struct pinmux_dev *pmxdev, unsigned selector); > + void (*disable) (struct pinmux_dev *pmxdev, unsigned selector); > + int (*gpio_request_enable) (struct pinmux_dev *pmxdev, unsigned offset); > + void (*dbg_show) (struct pinmux_dev *pmxdev, struct seq_file *s, > + unsigned offset); > +}; > + > +/** > + * struct pinmux_desc - pinmux descriptor, register this to pinmux subsystem > + * @name: name for the pinmux > + * @ops: pinmux operation table > + * @owner: module providing the pinmux, used for refcounting > + * @base: the number of the first pin handled by this pinmux, in the global > + * pin space, subtracted from a given pin to get the offset into the range > + * of a certain pinmux > + * @no_pin_settings: the number of pins handled by this pinmux - note that That's npins below. > + * this is the number of possible pin settings, if your driver handles > + * 8 pins that each can be muxed in 3 different ways, you reserve 24 > + * pins in the global pin space and set this to 24 > + */ > +struct pinmux_desc { > + const char *name; > + struct pinmux_ops *ops; > + struct module *owner; > + int base; > + int npins; > +}; > +/* External interface to pinmux */ > +extern int pinmux_request_gpio(int pin, unsigned gpio); > +extern void pinmux_free_gpio(int pin); Is there (or should there be) any automatic interaction with gpiolib? > +extern int pinmux_register_mappings(struct pinmux_map const *map, > + unsigned num_maps); > +extern struct pinmux *pinmux_get(struct device *dev, const char *func); I feel slightly uneasy tying the pinmux API to devices rather than Letting it be more free-form. I've seen this pattern for clocks too, but IIRC there is an override there allowing specification of a NULL device in order to look up a clock by raw clock name instead of device + sub-clock-name right? Still, I'm a relative neophyte regarding internal Linux kernel APIs, so my opinion here may not be particularly relevant. -- nvpublic -- To unsubscribe from this list: send the line "unsubscribe linux-tegra" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html